diff --git a/BUILD.gn b/BUILD.gn index 357f711..8f91d4f 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -1135,6 +1135,28 @@ "//third_party/blink/tools:wpt_tests_isolate", ] } + script_test("headless_shell_wpt") { + script = "//third_party/blink/tools/run_wpt_tests.py" + args = [ + "--test-type", + "testharness", + "reftest", + "crashtest", + "print-reftest", + "--product=headless_shell", + "--no-virtual-tests", + "--no-wpt-internal", + "--no-show-results", + "--zero-tests-executed-ok", + ] + data_deps = [ + ":blink_web_tests_expectations", + ":blink_web_tests_support_data", + "//chrome:chrome", + "//chrome/test/chromedriver:chromedriver_server", + "//third_party/blink/tools:wpt_tests_isolate", + ] + } } group("blink_web_tests_support_data") {
diff --git a/DEPS b/DEPS index 321232f4..ec383d1 100644 --- a/DEPS +++ b/DEPS
@@ -308,19 +308,19 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'src_internal_revision': 'df97b0f7451528e858398030e718d637a29aaa5f', + 'src_internal_revision': '51784961a549aa3eff970c32af08734422989955', # 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': '2790777048d3f00384f68be8081f3a3db615746c', + 'skia_revision': 'a3a016537a8c512df42b50522e78710b320c0faf', # 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': '628dd1909b2405aa0a68f9bd1aa00bbe5bc717b0', + 'v8_revision': '3d675d1ac3f96a60508bffa312e48bd46ddb466f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '313c73c3f6a056a049c03c4f928ab5d83f17a77a', + 'angle_revision': 'd71b8ee0f0e26b14a8fa642460df2635c2d7db2f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -363,7 +363,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': 'd091bca546fa15928db36c8447e126ee43ddb5f4', + 'freetype_revision': '12adfc212bd2f7560e1e175e66458124f9bd554b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -383,7 +383,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '7d44c8067842719b399fb10f625e573e29cb723b', + 'catapult_revision': 'e939ac77bb9471acc10f49e82cfe65790068c3d1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling chromium_variations # and whatever else without interference from each other. @@ -827,7 +827,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - 'ef9ed7638a0a413170457f22032944d1b61febbb', + '4ccf9ec2cc92967d39ca0e3d0b0158bfd7937c81', 'condition': 'checkout_android and checkout_src_internal', }, @@ -836,7 +836,7 @@ }, 'src/ios/third_party/earl_grey2/src': { - 'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + 'a09fa0c5cf18578d1985f3abffb599ecdc6fd514', + 'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + '26acfe36928095395dfcb6ff3d0578550bd868ac', 'condition': 'checkout_ios', }, @@ -982,7 +982,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'kp4Klz8ufJ2EgDaTvWPyNBOHWCPWMYaJDGa1FzMAKP8C', + 'version': '1qnqDwkuAyFH32YJq-GEdgF84BjauJ9_6hJa_Md5yGcC', }, ], 'condition': 'checkout_android', @@ -1157,7 +1157,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' + '@' + 'edee6b1f898f39a0e19e99d28be674a1aaa546a3', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '8af906338f6c07813067abf296170c8a4f46c538', 'condition': 'checkout_chromeos', }, @@ -1192,13 +1192,13 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'ed3d513241532dbea8e324ec9e1fe767bd75bddf', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'af97284b58afb6bdb7dd2b353bc651c718ce5bb4', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '904930d0bf12b7030892a118a2d2a6817dde61a3', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '84f68106afc210db30fb1efa8f76425cb067e82b', 'condition': 'checkout_src_internal', }, @@ -1652,7 +1652,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '09a4f3ec842a8932341b195c5b01e141c8a16eb7', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + '624f91b189a5a6fd35b1d3c43c60678c1f111dff', + Var('chromium_git') + '/openscreen' + '@' + 'dcd61dfe0e1e6c27d6d48fd4a29a9117e7d4b666', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '95fe35ffb383710a6e0567e958ead9a3b66e930c', @@ -1663,7 +1663,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f6656e9828f5a5a5358d0782bd4d5cdecdc652f5', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '234fd02711c642ec5211da272283db8fd8d91af4', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '8ef97ff3b7332e38e61b347a2fbed425a4617151', @@ -1811,7 +1811,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@01c82a000dcec3cc0452ef2faee80167fd788b79', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@6066c0d57a8bd7d68060336c7b01eeb9a1271589', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '56300b29fbfcc693ee6609ddad3fdd5b7a449a21', @@ -1848,7 +1848,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'bc3c8bad295ae0ba7f0ddb18848df70f92a820c0', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '11eade521a44d63af95cc72cfbbfa6c6becf972f', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '0da8f2f1189d05814b5bbfd770f362928f2fb829', 'src/third_party/webrtc': Var('webrtc_git') + '/src.git' + '@' + '85bea5a11bf3e771b335671b9875b8a9b033f223', @@ -1985,7 +1985,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'M1WdGLxXi9-fM7KnNtTP2IezFumjhaN7cZy9zMF6gKUC', + 'version': 'tX5EJQ1TlaqN-BaDUAHJ-JgOCALXI5p2m9a91Aj5KA4C', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -4125,7 +4125,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - '8af50d3b84698254f56ba6ffd69171a2abce3e12', + '4e9a9e1ff027107175ef685b140354acc5bfc1a9', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/WATCHLISTS b/WATCHLISTS index 096f372..62a31cc 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -1980,6 +1980,9 @@ '|components/cbor/'\ '|AndroidManifest', }, + 'security_interstitials': { + 'filepath': 'components/security_interstitials', + }, 'select_to_speak': { 'filepath': 'select_to_speak', }, @@ -3205,6 +3208,7 @@ 'search_engine_choice_screen': ['chrome-waffle-eng+watch@google.com'], 'search_prefetch': ['lingqi+watch@chromium.org'], 'security': ['security-watchlist@chromium.org'], + 'security_interstitials': ['drubery+watch@chromium.org'], 'select_to_speak': ['katie+watch@chromium.org', 'anastasi+watch@google.com'], 'send_tab_to_self': ['jeffreycohen+watch-send_tab_to_self@chromium.org',
diff --git a/android_webview/browser/BUILD.gn b/android_webview/browser/BUILD.gn index 07c860f..14d6f27 100644 --- a/android_webview/browser/BUILD.gn +++ b/android_webview/browser/BUILD.gn
@@ -116,8 +116,6 @@ "aw_web_ui_controller_factory.h", "component_updater/first_party_sets_component_loader.cc", "component_updater/first_party_sets_component_loader.h", - "component_updater/loader_policies/empty_component_loader_policy.cc", - "component_updater/loader_policies/empty_component_loader_policy.h", "component_updater/loader_policies/origin_trials_component_loader_policy.cc", "component_updater/loader_policies/origin_trials_component_loader_policy.h", "component_updater/masked_domain_list_component_loader.cc",
diff --git a/android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.cc b/android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.cc deleted file mode 100644 index 721dbac..0000000 --- a/android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.cc +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.h" - -#include <stdint.h> - -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "android_webview/common/aw_features.h" -#include "base/containers/flat_map.h" -#include "base/feature_list.h" -#include "base/files/scoped_file.h" -#include "base/values.h" -#include "base/version.h" -#include "components/component_updater/android/component_loader_policy.h" - -namespace android_webview { - -namespace { - -// Persisted to logs, should never change. -constexpr char kEmptyComponentLoaderPolicyMetricsSuffix[] = - "WebViewEmptyComponent"; - -// A fake SHA256 PublicKey of jebgalgnebhfojomionfpkfelancnnkf -const uint8_t kFakePublicKeySHA256[32] = { - 0x94, 0x16, 0x0b, 0x6d, 0x41, 0x75, 0xe9, 0xec, 0x8e, 0xd5, 0xfa, - 0x54, 0xb0, 0xd2, 0xdd, 0xa5, 0x6e, 0x05, 0x6b, 0xe8, 0x73, 0x47, - 0xf6, 0xc4, 0x11, 0x9f, 0xbc, 0xb3, 0x09, 0xb3, 0x5b, 0x40}; - -} // namespace - -void EmptyComponentLoaderPolicy::ComponentLoaded( - const base::Version& /*version*/, - base::flat_map<std::string, base::ScopedFD>& /*fd_map*/, - base::Value::Dict /*manifest*/) {} - -void EmptyComponentLoaderPolicy::ComponentLoadFailed( - component_updater::ComponentLoadResult /*error*/) {} - -void EmptyComponentLoaderPolicy::GetHash(std::vector<uint8_t>* hash) const { - hash->assign(kFakePublicKeySHA256, - kFakePublicKeySHA256 + std::size(kFakePublicKeySHA256)); -} - -std::string EmptyComponentLoaderPolicy::GetMetricsSuffix() const { - return kEmptyComponentLoaderPolicyMetricsSuffix; -} - -void LoadEmptyComponent( - component_updater::ComponentLoaderPolicyVector& policies) { - if (!base::FeatureList::IsEnabled( - android_webview::features::kWebViewEmptyComponentLoaderPolicy)) { - return; - } - - policies.push_back(std::make_unique<EmptyComponentLoaderPolicy>()); -} - -} // namespace android_webview
diff --git a/android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.h b/android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.h deleted file mode 100644 index 5a38144..0000000 --- a/android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.h +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_WEBVIEW_BROWSER_COMPONENT_UPDATER_LOADER_POLICIES_EMPTY_COMPONENT_LOADER_POLICY_H_ -#define ANDROID_WEBVIEW_BROWSER_COMPONENT_UPDATER_LOADER_POLICIES_EMPTY_COMPONENT_LOADER_POLICY_H_ - -#include <stdint.h> - -#include <string> -#include <vector> - -#include "base/containers/flat_map.h" -#include "base/files/scoped_file.h" -#include "base/values.h" -#include "components/component_updater/android/component_loader_policy.h" - -namespace base { -class Version; -} // namespace base - -namespace android_webview { - -// A fake empty component to run experiment to measure component updater -// performance impact. -// TODO(crbug.com/1288006): remove this when the experiment is over. -class EmptyComponentLoaderPolicy - : public component_updater::ComponentLoaderPolicy { - public: - EmptyComponentLoaderPolicy() = default; - ~EmptyComponentLoaderPolicy() override = default; - - EmptyComponentLoaderPolicy(const EmptyComponentLoaderPolicy&) = delete; - EmptyComponentLoaderPolicy& operator=(const EmptyComponentLoaderPolicy&) = - delete; - - // The following methods override ComponentLoaderPolicy. - void ComponentLoaded(const base::Version& version, - base::flat_map<std::string, base::ScopedFD>& fd_map, - base::Value::Dict manifest) override; - void ComponentLoadFailed( - component_updater::ComponentLoadResult error) override; - void GetHash(std::vector<uint8_t>* hash) const override; - std::string GetMetricsSuffix() const override; -}; - -void LoadEmptyComponent( - component_updater::ComponentLoaderPolicyVector& policies); - -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_BROWSER_COMPONENT_UPDATER_LOADER_POLICIES_EMPTY_COMPONENT_LOADER_POLICY_H_
diff --git a/android_webview/browser/component_updater/registration.cc b/android_webview/browser/component_updater/registration.cc index b85cc7c..b6c08cb 100644 --- a/android_webview/browser/component_updater/registration.cc +++ b/android_webview/browser/component_updater/registration.cc
@@ -5,7 +5,6 @@ #include "android_webview/browser/component_updater/registration.h" #include "android_webview/browser/component_updater/first_party_sets_component_loader.h" -#include "android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.h" #include "android_webview/browser/component_updater/masked_domain_list_component_loader.h" #include "android_webview/browser/component_updater/origin_trials_component_loader.h" #include "android_webview/browser/component_updater/tpcd_metadata_component_loader.h" @@ -20,7 +19,6 @@ LoadTrustTokenKeyCommitmentsComponent(policies); LoadMaskedDomainListComponent(policies); LoadOriginTrialsComponent(policies); - LoadEmptyComponent(policies); LoadTpcMetadataComponent(policies); return policies; }
diff --git a/android_webview/common/aw_features.cc b/android_webview/common/aw_features.cc index cd5010b..8ac02a8 100644 --- a/android_webview/common/aw_features.cc +++ b/android_webview/common/aw_features.cc
@@ -73,12 +73,6 @@ "WebViewDisplayCutout", base::FEATURE_ENABLED_BY_DEFAULT); -// Fake empty component to measure component updater performance impact on -// WebView clients. -BASE_FEATURE(kWebViewEmptyComponentLoaderPolicy, - "WebViewEmptyComponentLoaderPolicy", - base::FEATURE_DISABLED_BY_DEFAULT); - // Enable the WebView Media Integrity API. // This feature requires `kWebViewInjectPlatformJsApis` to be enabled as well. BASE_FEATURE(kWebViewMediaIntegrityApi,
diff --git a/android_webview/common/aw_features.h b/android_webview/common/aw_features.h index ba9b2202..be4e06a 100644 --- a/android_webview/common/aw_features.h +++ b/android_webview/common/aw_features.h
@@ -21,7 +21,6 @@ BASE_DECLARE_FEATURE(kWebViewCheckPakFileDescriptors); BASE_DECLARE_FEATURE(kWebViewClearFunctorInBackground); BASE_DECLARE_FEATURE(kWebViewDisplayCutout); -BASE_DECLARE_FEATURE(kWebViewEmptyComponentLoaderPolicy); BASE_DECLARE_FEATURE(kWebViewEnumerateDevicesCache); BASE_DECLARE_FEATURE(kWebViewExitReasonMetric); BASE_DECLARE_FEATURE(kWebViewExtraHeadersSameOriginOnly);
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index 970a0bf..d814ddda 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -356,9 +356,6 @@ Flag.baseFeature( NetworkServiceFeatures.MASKED_DOMAIN_LIST, "When enabled, the masked domain list required for IP Protection is loaded."), - Flag.baseFeature( - AwFeatures.WEBVIEW_EMPTY_COMPONENT_LOADER_POLICY, - "Enables loading a fake empty (no-op) component during WebView startup."), Flag.commandLine( AwSwitches.WEBVIEW_SELECTIVE_IMAGE_INVERSION_DARKENING, "Enables use selective image inversion to automatically darken page, it will be"
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwBackForwardCacheTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwBackForwardCacheTest.java index f63641f..517a5ea 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwBackForwardCacheTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwBackForwardCacheTest.java
@@ -9,10 +9,11 @@ import android.webkit.JavascriptInterface; import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; +import androidx.test.filters.LargeTest; import com.google.common.util.concurrent.SettableFuture; +import org.json.JSONObject; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -27,6 +28,7 @@ import org.chromium.base.test.util.DoNotBatch; import org.chromium.base.test.util.Feature; import org.chromium.content_public.browser.test.util.HistoryUtils; +import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.net.test.EmbeddedTestServer; import java.util.concurrent.TimeUnit; @@ -100,10 +102,12 @@ mTestServer.stopAndDestroyServer(); } - private void navigateForwardAndBack() throws Throwable { + private void navigateForward() throws Throwable { mActivityTestRule.loadUrlSync( mAwContents, mContentsClient.getOnPageFinishedHelper(), mForwardUrl); + } + private void navigateBack() throws Throwable { // Create a new future to avoid the future set in the initial load. SettableFuture<Boolean> pageFullyLoadedFuture = SettableFuture.create(); mLoadedNotifier.setFuture(pageFullyLoadedFuture); @@ -124,6 +128,11 @@ true, pageFullyLoadedFuture.get(SCALED_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); } + private void navigateForwardAndBack() throws Throwable { + navigateForward(); + navigateBack(); + } + private boolean isPageShowPersisted() throws Exception { String isPersisted = mActivityTestRule.executeJavaScriptAndWaitForResult( @@ -142,8 +151,16 @@ "JSON.stringify(performance.getEntriesByType('navigation')[0].notRestoredReasons);"); } + private String extractSimpleReasonString(String notRestoredReasons) throws Exception { + // Remove the escape character and the beginning and trailing quotes + notRestoredReasons = notRestoredReasons.replace("\\", ""); + notRestoredReasons = notRestoredReasons.substring(1, notRestoredReasons.length() - 1); + JSONObject json_obj = new JSONObject(notRestoredReasons); + return json_obj.getJSONArray("reasons").getJSONObject(0).getString("reason"); + } + @Test - @SmallTest + @LargeTest @Feature({"AndroidWebView"}) @CommandLineFlags.Add({ "enable-features=WebViewBackForwardCache" @@ -157,7 +174,7 @@ } @Test - @SmallTest + @LargeTest @Feature({"AndroidWebView"}) @CommandLineFlags.Add({ "disable-features=WebViewBackForwardCache" @@ -166,10 +183,65 @@ mActivityTestRule.loadUrlSync( mAwContents, mContentsClient.getOnPageFinishedHelper(), mInitialUrl); navigateForwardAndBack(); - String not_restored_reasons = getNotRestoredReasons(); - Assert.assertTrue(not_restored_reasons.indexOf("reasons") >= 0); + String notRestoredReasons = getNotRestoredReasons(); + Assert.assertEquals(extractSimpleReasonString(notRestoredReasons), "masked"); Assert.assertFalse(isPageShowPersisted()); } - // TODO: Add more cases (e.g. page eviction when in BFCache) to test + @Test + @LargeTest + @Feature({"AndroidWebView"}) + @CommandLineFlags.Add({"enable-features=WebViewBackForwardCache"}) + public void testPageEvictedWhenModifyingJSInterface() throws Exception, Throwable { + mActivityTestRule.loadUrlSync( + mAwContents, mContentsClient.getOnPageFinishedHelper(), mInitialUrl); + + // Test adding javascript interface + navigateForward(); + Object testInjectedObject = + new Object() { + @JavascriptInterface + public void mock() {} + }; + AwActivityTestRule.addJavascriptInterfaceOnUiThread( + mAwContents, testInjectedObject, "testInjectedObject"); + navigateBack(); + String notRestoredReasons = getNotRestoredReasons(); + Assert.assertEquals(extractSimpleReasonString(notRestoredReasons), "masked"); + Assert.assertFalse(isPageShowPersisted()); + + // Test removing javascript interface + navigateForward(); + TestThreadUtils.runOnUiThreadBlocking( + () -> mAwContents.removeJavascriptInterface("testInjectedObject")); + navigateBack(); + notRestoredReasons = getNotRestoredReasons(); + Assert.assertEquals(extractSimpleReasonString(notRestoredReasons), "masked"); + Assert.assertFalse(isPageShowPersisted()); + + // Test BFCache can still work for future navigations + navigateForwardAndBack(); + Assert.assertTrue(isPageShowPersisted()); + } + + @Test + @LargeTest + @Feature({"AndroidWebView"}) + @CommandLineFlags.Add({"enable-features=WebViewBackForwardCache"}) + public void testPageEvictedWhenAddingWebMessageListener() throws Exception, Throwable { + mActivityTestRule.loadUrlSync( + mAwContents, mContentsClient.getOnPageFinishedHelper(), mInitialUrl); + navigateForward(); + TestWebMessageListener listener = new TestWebMessageListener(); + TestWebMessageListener.addWebMessageListenerOnUiThread( + mAwContents, "awMessagePort", new String[] {"*"}, listener); + navigateBack(); + String notRestoredReasons = getNotRestoredReasons(); + Assert.assertTrue(notRestoredReasons.indexOf("reasons") >= 0); + Assert.assertFalse(isPageShowPersisted()); + + // Test BFCache can still work for future navigations + navigateForwardAndBack(); + Assert.assertTrue(isPageShowPersisted()); + } }
diff --git a/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt b/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt index ecdbbe61..5674796e 100644 --- a/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt +++ b/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt
@@ -2718,11 +2718,13 @@ getter longitude getter speed method constructor + method toJSON interface GeolocationPosition attribute @@toStringTag getter coords getter timestamp method constructor + method toJSON interface GeolocationPositionError attribute @@toStringTag attribute PERMISSION_DENIED
diff --git a/ash/accessibility/accessibility_controller.cc b/ash/accessibility/accessibility_controller.cc index 54daa5e4..c3fff2d 100644 --- a/ash/accessibility/accessibility_controller.cc +++ b/ash/accessibility/accessibility_controller.cc
@@ -2332,6 +2332,11 @@ base::Unretained(this))); if (::features::IsAccessibilityMouseKeysEnabled()) { pref_change_registrar_->Add( + prefs::kAccessibilityMouseKeysDisableInTextFields, + base::BindRepeating(&AccessibilityController:: + UpdateMouseKeysDisableInTextFieldsFromPref, + base::Unretained(this))); + pref_change_registrar_->Add( prefs::kAccessibilityMouseKeysAcceleration, base::BindRepeating( &AccessibilityController::UpdateMouseKeysAccelerationFromPref, @@ -2440,6 +2445,7 @@ UpdateAutoclickMovementThresholdFromPref(); UpdateAutoclickMenuPositionFromPref(); if (::features::IsAccessibilityMouseKeysEnabled()) { + UpdateMouseKeysDisableInTextFieldsFromPref(); UpdateMouseKeysAccelerationFromPref(); UpdateMouseKeysMaxSpeedFromPref(); UpdateMouseKeysDominantHandFromPref(); @@ -2524,6 +2530,13 @@ GetAutoclickMenuPosition()); } +void AccessibilityController::UpdateMouseKeysDisableInTextFieldsFromPref() { + DCHECK(active_user_prefs_); + bool value = active_user_prefs_->GetBoolean( + prefs::kAccessibilityMouseKeysDisableInTextFields); + Shell::Get()->mouse_keys_controller()->set_disable_in_text_fields(value); +} + void AccessibilityController::UpdateMouseKeysAccelerationFromPref() { DCHECK(active_user_prefs_); double acceleration =
diff --git a/ash/accessibility/accessibility_controller.h b/ash/accessibility/accessibility_controller.h index 288ca39..9d3abdda 100644 --- a/ash/accessibility/accessibility_controller.h +++ b/ash/accessibility/accessibility_controller.h
@@ -670,6 +670,7 @@ void UpdateAutoclickStabilizePositionFromPref(); void UpdateAutoclickMovementThresholdFromPref(); void UpdateAutoclickMenuPositionFromPref(); + void UpdateMouseKeysDisableInTextFieldsFromPref(); void UpdateMouseKeysAccelerationFromPref(); void UpdateMouseKeysMaxSpeedFromPref(); void UpdateMouseKeysDominantHandFromPref();
diff --git a/ash/accessibility/mouse_keys/mouse_keys_unittest.cc b/ash/accessibility/mouse_keys/mouse_keys_unittest.cc index 34e8acb..8116cc21 100644 --- a/ash/accessibility/mouse_keys/mouse_keys_unittest.cc +++ b/ash/accessibility/mouse_keys/mouse_keys_unittest.cc
@@ -162,7 +162,10 @@ } void SetDisableInTextFields(bool value) { - return GetMouseKeysController()->set_disable_in_text_fields(value); + PrefService* prefs = + Shell::Get()->session_controller()->GetLastActiveUserPrefService(); + + prefs->SetBoolean(prefs::kAccessibilityMouseKeysDisableInTextFields, value); } void SetLeftHanded(bool value) {
diff --git a/ash/birch/birch_model.cc b/ash/birch/birch_model.cc index 5353f2b..34adb2a 100644 --- a/ash/birch/birch_model.cc +++ b/ash/birch/birch_model.cc
@@ -78,7 +78,7 @@ base::UmaHistogramCounts100("Ash.Birch.ResultsReturned.Calendar", calendar_items.size()); base::UmaHistogramTimes("Ash.Birch.Latency.Calendar", - GetNow() - fetch_start_time_); + GetNow() - fetch_start_time_calendar_); is_fetching_calendar_ = false; } if (calendar_items != calendar_items_) { @@ -110,7 +110,7 @@ base::UmaHistogramCounts100("Ash.Birch.ResultsReturned.File", file_suggest_items.size()); base::UmaHistogramTimes("Ash.Birch.Latency.File", - GetNow() - fetch_start_time_); + GetNow() - fetch_start_time_file_suggest_); is_fetching_file_suggest_ = false; } if (file_suggest_items_ != file_suggest_items) { @@ -126,7 +126,7 @@ base::UmaHistogramCounts100("Ash.Birch.ResultsReturned.Tab", recent_tab_items.size()); base::UmaHistogramTimes("Ash.Birch.Latency.Tab", - GetNow() - fetch_start_time_); + GetNow() - fetch_start_time_recent_tab_); is_fetching_recent_tab_ = false; } if (recent_tab_items_ != recent_tab_items) { @@ -142,7 +142,7 @@ base::UmaHistogramCounts100("Ash.Birch.ResultsReturned.Weather", weather_items.size()); base::UmaHistogramTimes("Ash.Birch.Latency.Weather", - GetNow() - fetch_start_time_); + GetNow() - fetch_start_time_weather_); is_fetching_weather_ = false; } if (weather_items_ != weather_items) { @@ -158,7 +158,7 @@ base::UmaHistogramCounts100("Ash.Birch.ResultsReturned.ReleaseNotes", release_notes_items.size()); base::UmaHistogramTimes("Ash.Birch.Latency.ReleaseNotes", - GetNow() - fetch_start_time_); + GetNow() - fetch_start_time_release_notes_); is_fetching_release_notes_ = false; } if (release_notes_items != release_notes_items_) { @@ -228,6 +228,7 @@ if (prefs->GetBoolean(prefs::kBirchUseCalendar)) { is_calendar_data_fresh_ = false; is_attachment_data_fresh_ = false; // Attachments use the same provider. + fetch_start_time_calendar_ = GetNow(); is_fetching_calendar_ = true; is_fetching_attachment_ = true; birch_client_->GetCalendarProvider()->RequestBirchDataFetch(); @@ -235,18 +236,21 @@ } if (prefs->GetBoolean(prefs::kBirchUseFileSuggest)) { is_files_data_fresh_ = false; + fetch_start_time_file_suggest_ = GetNow(); is_fetching_file_suggest_ = true; birch_client_->GetFileSuggestProvider()->RequestBirchDataFetch(); did_fetch = true; } if (prefs->GetBoolean(prefs::kBirchUseRecentTabs)) { is_tabs_data_fresh_ = false; + fetch_start_time_recent_tab_ = GetNow(); is_fetching_recent_tab_ = true; birch_client_->GetRecentTabsProvider()->RequestBirchDataFetch(); did_fetch = true; } if (prefs->GetBoolean(prefs::kBirchUseReleaseNotes)) { is_release_notes_data_fresh_ = false; + fetch_start_time_release_notes_ = GetNow(); is_fetching_release_notes_ = true; birch_client_->GetReleaseNotesProvider()->RequestBirchDataFetch(); did_fetch = true; @@ -254,6 +258,7 @@ } if (weather_provider_ && prefs->GetBoolean(prefs::kBirchUseWeather)) { is_weather_data_fresh_ = false; + fetch_start_time_weather_ = GetNow(); is_fetching_weather_ = true; weather_provider_->RequestBirchDataFetch(); did_fetch = true; @@ -526,6 +531,15 @@ } else { is_calendar_data_fresh_ = false; is_attachment_data_fresh_ = false; + // When calendar is toggled on while a fetch is in progress, perform + // a calendar data fetch. + const bool fetch_in_progress = !pending_requests_.empty(); + if (birch_client_ && fetch_in_progress && !is_fetching_calendar_) { + fetch_start_time_calendar_ = GetNow(); + is_fetching_calendar_ = true; + is_fetching_attachment_ = true; + birch_client_->GetCalendarProvider()->RequestBirchDataFetch(); + } } } @@ -535,6 +549,15 @@ file_suggest_items_.clear(); } else { is_files_data_fresh_ = false; + + // When file suggest is toggled on while a fetch is in progress, perform + // a file suggest data fetch. + const bool fetch_in_progress = !pending_requests_.empty(); + if (birch_client_ && fetch_in_progress && !is_fetching_file_suggest_) { + fetch_start_time_file_suggest_ = GetNow(); + is_fetching_file_suggest_ = true; + birch_client_->GetFileSuggestProvider()->RequestBirchDataFetch(); + } } } @@ -544,6 +567,14 @@ recent_tab_items_.clear(); } else { is_tabs_data_fresh_ = false; + // When recent tabs is toggled on while a fetch is in progress, perform + // a tabs data fetch. + const bool fetch_in_progress = !pending_requests_.empty(); + if (birch_client_ && fetch_in_progress && !is_fetching_recent_tab_) { + fetch_start_time_recent_tab_ = GetNow(); + is_fetching_recent_tab_ = true; + birch_client_->GetRecentTabsProvider()->RequestBirchDataFetch(); + } } } @@ -553,6 +584,14 @@ weather_items_.clear(); } else { is_weather_data_fresh_ = false; + // When weather is toggled on while a fetch is in progress, perform + // a weather data fetch. + const bool fetch_in_progress = !pending_requests_.empty(); + if (weather_provider_ && fetch_in_progress && !is_fetching_weather_) { + fetch_start_time_weather_ = GetNow(); + is_fetching_weather_ = true; + weather_provider_->RequestBirchDataFetch(); + } } } @@ -562,6 +601,14 @@ release_notes_items_.clear(); } else { is_release_notes_data_fresh_ = false; + // When release notes is toggled on while a fetch is in progress, perform + // a release notes fetch. + const bool fetch_in_progress = !pending_requests_.empty(); + if (birch_client_ && fetch_in_progress && !is_fetching_release_notes_) { + fetch_start_time_release_notes_ = GetNow(); + is_fetching_release_notes_ = true; + birch_client_->GetReleaseNotesProvider()->RequestBirchDataFetch(); + } } }
diff --git a/ash/birch/birch_model.h b/ash/birch/birch_model.h index c795629c..7ca19a9 100644 --- a/ash/birch/birch_model.h +++ b/ash/birch/birch_model.h
@@ -191,6 +191,11 @@ // When the last fetch was started. Used for metrics. base::Time fetch_start_time_; + base::Time fetch_start_time_calendar_; + base::Time fetch_start_time_file_suggest_; + base::Time fetch_start_time_recent_tab_; + base::Time fetch_start_time_weather_; + base::Time fetch_start_time_release_notes_; // Which fetches are in progress. Used for metrics. bool is_fetching_calendar_ = false;
diff --git a/ash/birch/birch_model_unittest.cc b/ash/birch/birch_model_unittest.cc index 29f34be..3550c4e 100644 --- a/ash/birch/birch_model_unittest.cc +++ b/ash/birch/birch_model_unittest.cc
@@ -547,6 +547,64 @@ EXPECT_TRUE(model->IsDataFresh()); } +TEST_F(BirchModelTest, EnablePrefsDuringFetchCausesDataFetchRequest) { + BirchModel* model = Shell::Get()->birch_model(); + + // Disable all the prefs except weather, so that a data fetch request creates + // a pending request. + PrefService* prefs = + Shell::Get()->session_controller()->GetPrimaryUserPrefService(); + ASSERT_TRUE(prefs); + prefs->SetBoolean(prefs::kBirchUseCalendar, false); + prefs->SetBoolean(prefs::kBirchUseFileSuggest, false); + prefs->SetBoolean(prefs::kBirchUseRecentTabs, false); + prefs->SetBoolean(prefs::kBirchUseReleaseNotes, false); + + // Request a fetch, creating a pending fetch request. + model->RequestBirchDataFetch(/*is_post_login=*/false, base::DoNothing()); + + auto& client = stub_birch_client_; + EXPECT_FALSE(client.calendar_provider_.did_request_birch_data_fetch_); + EXPECT_FALSE(client.file_suggest_provider_.did_request_birch_data_fetch_); + EXPECT_FALSE(client.recent_tabs_provider_.did_request_birch_data_fetch_); + EXPECT_FALSE(client.release_notes_provider_.did_request_birch_data_fetch_); + + // Enable prefs and then expect that data fetch requests are called for each + // enabled data type. + prefs->SetBoolean(prefs::kBirchUseCalendar, true); + prefs->SetBoolean(prefs::kBirchUseFileSuggest, true); + prefs->SetBoolean(prefs::kBirchUseRecentTabs, true); + prefs->SetBoolean(prefs::kBirchUseReleaseNotes, true); + EXPECT_TRUE(client.calendar_provider_.did_request_birch_data_fetch_); + EXPECT_TRUE(client.file_suggest_provider_.did_request_birch_data_fetch_); + EXPECT_TRUE(client.recent_tabs_provider_.did_request_birch_data_fetch_); + EXPECT_TRUE(client.release_notes_provider_.did_request_birch_data_fetch_); +} + +TEST_F(BirchModelTest, EnableWeatherPrefDuringFetchCausesDataFetchRequest) { + BirchModel* model = Shell::Get()->birch_model(); + + // Install a stub weather provider. + auto weather_provider = std::make_unique<StubBirchDataProvider>(); + auto* weather_provider_ptr = weather_provider.get(); + model->OverrideWeatherProviderForTest(std::move(weather_provider)); + + // Disable the weather pref. + PrefService* prefs = + Shell::Get()->session_controller()->GetPrimaryUserPrefService(); + ASSERT_TRUE(prefs); + prefs->SetBoolean(prefs::kBirchUseWeather, false); + + // Request a fetch, creating a pending fetch request. + model->RequestBirchDataFetch(/*is_post_login=*/false, base::DoNothing()); + + EXPECT_FALSE(weather_provider_ptr->did_request_birch_data_fetch_); + + // Enable the weather pref and expect a weather data fetch. + prefs->SetBoolean(prefs::kBirchUseWeather, true); + EXPECT_TRUE(weather_provider_ptr->did_request_birch_data_fetch_); +} + // Regression test for missing attachment type check in IsDataFresh(). TEST_F(BirchModelTest, IsDataFresh_Attachments) { BirchModel* model = Shell::Get()->birch_model();
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 317dbba..6fff71a 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -3064,7 +3064,7 @@ // the churn observation check in ping. BASE_FEATURE(kDeviceActiveClientChurnObservationNewDeviceMetadata, "DeviceActiveClientChurnObservationNewDeviceMetadata", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Enables or disables forced reboots when DeviceScheduledReboot policy is set. BASE_FEATURE(kDeviceForceScheduledReboot,
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h index 0917af4..cb08b8f 100644 --- a/ash/constants/ash_pref_names.h +++ b/ash/constants/ash_pref_names.h
@@ -176,6 +176,11 @@ inline constexpr char kEduCoexistenceToSAcceptedVersion[] = "family_link_user.edu_coexistence_tos_accepted_version"; +// A boolean pref indicating if a PIN has been set up for on-device apps +// parental controls. +inline constexpr char kOnDeviceAppControlsSetupCompleted[] = + "on_device_app_controls.setup_completed"; + // A boolean pref indicating whether welcome page should be skipped in // in-session 'Add account' flow. inline constexpr char kShouldSkipInlineLoginWelcomePage[] =
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc index d2d85e3..2b0adf9 100644 --- a/ash/display/display_manager_unittest.cc +++ b/ash/display/display_manager_unittest.cc
@@ -503,116 +503,6 @@ display_manager()->GetDisplayAt(1).bounds()); } -// Test recommended zoom factor will be applied to external display when -// connected for the first time. -TEST_F(DisplayManagerTest, UpdateDisplayWithUnseenExternalDisplayTest) { - // Set up internal display and external display. - const int64_t internal_display_id = - display::test::DisplayManagerTestApi(display_manager()) - .SetFirstDisplayAsInternalDisplay(); - const int external_id_1 = 10; - const display::ManagedDisplayInfo internal_display_info = - CreateDisplayInfo(internal_display_id, gfx::Rect(0, 0, 1920, 1200)); - display::ManagedDisplayInfo external_display_info_1 = - CreateDisplayInfo(external_id_1, gfx::Rect(1, 1, 3840, 2160)); - const float external_display_dpi_1 = 192.f; - external_display_info_1.set_device_dpi(external_display_dpi_1); - - std::vector<display::ManagedDisplayInfo> display_info_list; - display_info_list.clear(); - display_info_list.push_back(internal_display_info); - display_info_list.push_back(external_display_info_1); - display_manager()->OnNativeDisplaysChanged(display_info_list); - - EXPECT_EQ(2U, display_manager()->GetNumDisplays()); - EXPECT_EQ(2U, display_manager()->num_connected_displays()); - - // The recommended zoom factor should be applied since this external display - // is connected for the first time. - - // The available zoom factors for 3840X2160 are - // {1.f, 1.10f, 1.20f, 1.40f, 1.60f, 1.80f, 2.00f, 2.20f, 2.40f}. The expected - // zoom factor = external_display_dpi_1 / - // kRecommendedDefaultExternalDisplayDpi = 192 / 96 = 2, which is available. - const float expect_zoom_factor_1 = 2.f; - EXPECT_EQ(expect_zoom_factor_1, - GetDisplayInfoForId(external_id_1).zoom_factor()); - - // Update the external display again. - external_display_info_1.set_device_dpi(300.f); - display_info_list.clear(); - display_info_list.push_back(internal_display_info); - display_info_list.push_back(external_display_info_1); - display_manager()->OnNativeDisplaysChanged(display_info_list); - - // The recommended zoom factor should not be applied since this external - // display is connected before. - EXPECT_EQ(1.f, GetDisplayInfoForId(external_id_1).zoom_factor()); - - // Test with a new external display with different display dpi. - const int external_id_2 = 20; - display::ManagedDisplayInfo external_display_info_2 = - CreateDisplayInfo(external_id_2, gfx::Rect(1, 1, 3840, 2160)); - const float external_display_dpi_2 = 140.f; - external_display_info_2.set_device_dpi(external_display_dpi_2); - - display_info_list.clear(); - display_info_list.push_back(internal_display_info); - display_info_list.push_back(external_display_info_2); - display_manager()->OnNativeDisplaysChanged(display_info_list); - - // The available zoom factors for 3840X2160 are - // {1.f, 1.10f, 1.20f, 1.40f, 1.60f, 1.80f, 2.00f, 2.20f, 2.40f}. The expected - // zoom factor = external_display_dpi_2 / - // kRecommendedDefaultExternalDisplayDpi = 140 / 96 = 1.46, the closest - // available zoom factor is 1.4. - const float expect_zoom_factor_2 = 1.4f; - EXPECT_EQ(expect_zoom_factor_2, - GetDisplayInfoForId(external_id_2).zoom_factor()); - - // Test with a new external display with a large display dpi. - const int external_id_3 = 30; - display::ManagedDisplayInfo external_display_info_3 = - CreateDisplayInfo(external_id_3, gfx::Rect(1, 1, 3840, 2160)); - const float external_display_dpi_3 = 300.f; - external_display_info_3.set_device_dpi(external_display_dpi_3); - - display_info_list.clear(); - display_info_list.push_back(internal_display_info); - display_info_list.push_back(external_display_info_3); - display_manager()->OnNativeDisplaysChanged(display_info_list); - - // The available zoom factors for 3840X2160 are - // {1.f, 1.10f, 1.20f, 1.40f, 1.60f, 1.80f, 2.00f, 2.20f, 2.40f}. The expected - // zoom factor = external_display_dpi_3 / - // kRecommendedDefaultExternalDisplayDpi = 300 / 96 = 3.125, the closest - // available zoom factor is 2.4. - const float expect_zoom_factor_3 = 2.4f; - EXPECT_EQ(expect_zoom_factor_3, - GetDisplayInfoForId(external_id_3).zoom_factor()); - - // Test with a new external display with a small display dpi. - const int external_id_4 = 40; - display::ManagedDisplayInfo external_display_info_4 = - CreateDisplayInfo(external_id_4, gfx::Rect(1, 1, 3840, 2160)); - const float external_display_dpi_4 = 50.f; - external_display_info_4.set_device_dpi(external_display_dpi_4); - - display_info_list.clear(); - display_info_list.push_back(internal_display_info); - display_info_list.push_back(external_display_info_4); - display_manager()->OnNativeDisplaysChanged(display_info_list); - - // The available zoom factors for 3840X2160 are - // {1.f, 1.10f, 1.20f, 1.40f, 1.60f, 1.80f, 2.00f, 2.20f, 2.40f}. The expected - // zoom factor = external_display_dpi_4 / - // kRecommendedDefaultExternalDisplayDpi = 50 / 96 = 0.52, the closest - // available zoom factor is 1. - const float expect_zoom_factor_4 = 1.f; - EXPECT_EQ(expect_zoom_factor_4, - GetDisplayInfoForId(external_id_4).zoom_factor()); -} - // Test in emulation mode (use_fullscreen_host_window=false) TEST_F(DisplayManagerTest, EmulatorTest) { EXPECT_EQ(1U, display_manager()->GetNumDisplays());
diff --git a/ash/public/cpp/shelf_config.h b/ash/public/cpp/shelf_config.h index ba256dae..e19edd6 100644 --- a/ash/public/cpp/shelf_config.h +++ b/ash/public/cpp/shelf_config.h
@@ -75,7 +75,6 @@ void OnSessionStateChanged(session_manager::SessionState state) override; // DisplayObserver: - void OnDisplayTabletStateChanged(display::TabletState state) override; void OnDisplayMetricsChanged(const display::Display& display, uint32_t changed_metrics) override; @@ -85,6 +84,10 @@ // AppListControllerObserver: void OnAppListVisibilityWillChange(bool shown, int64_t display_id) override; + // Updates the shelf configuration to match the provided tablet mode state. + // Called during transitions to enter or exit tablet mode. + void UpdateForTabletMode(bool in_tablet_mode); + // Whether the shelf control buttons must be shown for accessibility // reasons. bool ShelfControlsForcedShownForAccessibility() const;
diff --git a/ash/shelf/shelf_config.cc b/ash/shelf/shelf_config.cc index edbfcf2..61dc446 100644 --- a/ash/shelf/shelf_config.cc +++ b/ash/shelf/shelf_config.cc
@@ -212,36 +212,11 @@ UpdateConfig(is_app_list_visible_, /*tablet_mode_changed=*/false); } -void ShelfConfig::OnDisplayTabletStateChanged(display::TabletState state) { - switch (state) { - case display::TabletState::kInClamshellMode: - break; - case display::TabletState::kEnteringTabletMode: - // Update the shelf config at the "starting" stage of the tablet mode - // transition, so that the shelf bounds are set and remains stable during - // the transition animation. Otherwise, updating the shelf bounds during - // the animation will lead to work-area bounds changes which lead to many - // re-layouts, hurting the animation's smoothness. - // https://crbug.com/1044316. - DCHECK(!in_tablet_mode_); - in_tablet_mode_ = true; - - UpdateConfig(is_app_list_visible_, /*tablet_mode_changed=*/true); - break; - case display::TabletState::kInTabletMode: - break; - case display::TabletState::kExitingTabletMode: - // Many events can lead to UpdateConfig being called as a result of - // kInClamshellMode event, therefore we need to listen to the "ending" - // stage rather than the "ended", so `in_tablet_mode_` gets updated - // correctly, and the shelf bounds are stabilized early so as not to have - // multiple unnecessary work-area bounds changes. - in_tablet_mode_ = false; - - UpdateConfig(is_app_list_visible_, /*tablet_mode_changed=*/true); - - has_shown_elevated_app_bar_ = std::nullopt; - break; +void ShelfConfig::UpdateForTabletMode(bool in_tablet_mode) { + in_tablet_mode_ = in_tablet_mode; + UpdateConfig(is_app_list_visible_, /*tablet_mode_changed=*/true); + if (!in_tablet_mode_) { + has_shown_elevated_app_bar_ = std::nullopt; } }
diff --git a/ash/system/toast/system_nudge_view.cc b/ash/system/toast/system_nudge_view.cc index 119f592..21f2e446 100644 --- a/ash/system/toast/system_nudge_view.cc +++ b/ash/system/toast/system_nudge_view.cc
@@ -34,6 +34,7 @@ #include "ui/views/layout/flex_layout.h" #include "ui/views/layout/flex_layout_view.h" #include "ui/views/view.h" +#include "ui/views/view_class_properties.h" #include "ui/views/view_tracker.h" namespace ash { @@ -122,6 +123,12 @@ } // namespace +DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(SystemNudgeView, kBubbleIdForTesting); +DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(SystemNudgeView, + kPrimaryButtonIdForTesting); +DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(SystemNudgeView, + kSecondaryButtonIdForTesting); + SystemNudgeView::SystemNudgeView(const AnchoredNudgeData& nudge_data) : shadow_(SystemShadow::CreateShadowOnTextureLayer( SystemShadow::Type::kElevation4)), @@ -135,6 +142,7 @@ SetBackground(views::CreateThemedSolidBackground( nudge_data.background_color_id.value_or(kColorAshShieldAndBase80))); SetNotifyEnterExitOnChild(true); + SetProperty(views::kElementIdentifierKey, kBubbleIdForTesting); // Cache the anchor view when the nudge anchors by its corner to set a pointy // corner based on the nudge's position in relation to this anchor view. @@ -340,6 +348,7 @@ .SetTooltipText(nudge_data.primary_button_text) .SetPillButtonType(PillButton::Type::kPrimaryWithoutIcon) .SetFocusBehavior(views::View::FocusBehavior::ALWAYS) + .SetProperty(views::kElementIdentifierKey, kPrimaryButtonIdForTesting) .Build()); if (has_secondary_button) { @@ -351,6 +360,8 @@ .SetTooltipText(nudge_data.secondary_button_text) .SetPillButtonType(PillButton::Type::kSecondaryWithoutIcon) .SetFocusBehavior(views::View::FocusBehavior::ALWAYS) + .SetProperty(views::kElementIdentifierKey, + kSecondaryButtonIdForTesting) .Build(), 0); }
diff --git a/ash/system/toast/system_nudge_view.h b/ash/system/toast/system_nudge_view.h index 984f409d..0bc6b0a 100644 --- a/ash/system/toast/system_nudge_view.h +++ b/ash/system/toast/system_nudge_view.h
@@ -35,6 +35,10 @@ METADATA_HEADER(SystemNudgeView, views::FlexLayoutView) public: + DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kBubbleIdForTesting); + DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kPrimaryButtonIdForTesting); + DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kSecondaryButtonIdForTesting); + SystemNudgeView(const AnchoredNudgeData& nudge_data); SystemNudgeView(const SystemNudgeView&) = delete; SystemNudgeView& operator=(const SystemNudgeView&) = delete;
diff --git a/ash/webui/personalization_app/resources/js/user/avatar_list_element.ts b/ash/webui/personalization_app/resources/js/user/avatar_list_element.ts index d0528760..1a17a9c 100644 --- a/ash/webui/personalization_app/resources/js/user/avatar_list_element.ts +++ b/ash/webui/personalization_app/resources/js/user/avatar_list_element.ts
@@ -429,7 +429,8 @@ assert( !url.startsWith('chrome://image/'), 'The URL shouldn\'t be sanitized'); - return `background-image: url('${getAvatarUrl(url)}&staticEncode=true')`; + return `background-image: url('${ + getAvatarUrl(url, /*staticEncode=*/ true)}')`; } return ''; }
diff --git a/ash/webui/personalization_app/resources/js/user/user_preview_element.ts b/ash/webui/personalization_app/resources/js/user/user_preview_element.ts index f201e3a..897792c1f 100644 --- a/ash/webui/personalization_app/resources/js/user/user_preview_element.ts +++ b/ash/webui/personalization_app/resources/js/user/user_preview_element.ts
@@ -171,7 +171,8 @@ } assert( !url.startsWith('chrome://image/'), 'The url should not be sanitized'); - return `background-image: url('${getAvatarUrl(url)}&staticEncode=true')`; + return `background-image: url('${ + getAvatarUrl(url, /*staticEncode=*/ true)}')`; } private getAvatarUrl_(url: string): string {
diff --git a/ash/webui/personalization_app/resources/js/user/utils.ts b/ash/webui/personalization_app/resources/js/user/utils.ts index 8ca972b..25ba7a4 100644 --- a/ash/webui/personalization_app/resources/js/user/utils.ts +++ b/ash/webui/personalization_app/resources/js/user/utils.ts
@@ -14,7 +14,8 @@ * Returns the avatar url. If necessary, prefixes the url with the sanitizing * string. */ -export function getAvatarUrl(url: string): string { +export function getAvatarUrl( + url: string, staticEncode: boolean = false): string { if (!url) { return ''; } @@ -22,5 +23,8 @@ url === AVATAR_PLACEHOLDER_URL) { return url; } - return `chrome://image/?${url}`; + if (!staticEncode) { + return `chrome://image/?${url}`; + } + return `chrome://image/?url=${encodeURIComponent(url)}&staticEncode=true`; }
diff --git a/ash/wm/default_window_resizer.h b/ash/wm/default_window_resizer.h index 5dc7df00..5d5ca1a 100644 --- a/ash/wm/default_window_resizer.h +++ b/ash/wm/default_window_resizer.h
@@ -12,9 +12,9 @@ namespace ash { -// WindowResizer is used by ToplevelWindowEventFilter to handle dragging, moving -// or resizing a window. All coordinates passed to this are in the parent -// windows coordiantes. +// WindowResizer is used by ToplevelWindowEventHandler to handle dragging, +// moving or resizing a window. All coordinates passed to this are in the parent +// windows coordinates. class ASH_EXPORT DefaultWindowResizer : public WindowResizer { public: ~DefaultWindowResizer() override;
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc index dd479eb..4aa6391 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -908,6 +908,13 @@ Shell::Get()->display_manager()->SetTabletState( display::TabletState::kExitingTabletMode); + // Many events can lead to shelf config updates as a result of + // kInClamshellMode event. Update the shelf config during "ending" + // stage rather than the "ended", so `in_tablet_mode_` gets updated + // correctly, and the shelf bounds are stabilized early so as not to have + // multiple unnecessary work-area bounds changes. + ShelfConfig::Get()->UpdateForTabletMode(/*in_tablet_mode=*/false); + if (tablet_mode_window_manager_) { tablet_mode_window_manager_->Shutdown( TabletModeWindowManager::ShutdownReason::kExitTabletUIMode); @@ -1167,6 +1174,18 @@ DCHECK_EQ(display::TabletState::kEnteringTabletMode, display::Screen::GetScreen()->GetTabletState()); + // Transition shelf to tablet mode state, now that the screenshot for tablet + // mode transition was taken. Taking screenshot recreates shelf container + // layer, and uses the original layer - changing shelf state before the + // screenshot is taken would change the shelf appearance, and could cause + // issues where the original shelf widget layer is not re-painted correctly in + // response to a paint schedule for tablet mode state change. + // Update the shelf state befire initiating tablet mode window state changes + // to avoid negative impact of window work-area changes (due to changes in + // shelf bounds) during window state transition on the animation smoothness + // https://crbug.com/1044316. + ShelfConfig::Get()->UpdateForTabletMode(/*in_tablet_mode=*/true); + tablet_mode_window_manager_ = std::make_unique<TabletModeWindowManager>(); tablet_mode_window_manager_->Init();
diff --git a/ash/wm/window_resizer.cc b/ash/wm/window_resizer.cc index 0b011209..b120e4d3 100644 --- a/ash/wm/window_resizer.cc +++ b/ash/wm/window_resizer.cc
@@ -170,7 +170,7 @@ // The minimize size constraint may limit how much we change the window // position. For example, dragging the left edge to the right should stop // repositioning the window when the minimize size is reached. - gfx::Size size = GetSizeForDrag(&delta_x, &delta_y); + const gfx::Size size = GetSizeForDrag(&delta_x, &delta_y); gfx::Point origin = GetOriginForDrag(delta_x, delta_y, passed_location); gfx::Rect new_bounds(origin, size); @@ -417,12 +417,12 @@ return origin; } -gfx::Size WindowResizer::GetSizeForDrag(int* delta_x, int* delta_y) { +gfx::Size WindowResizer::GetSizeForDrag(int* delta_x, int* delta_y) const { gfx::Size size = details().initial_bounds_in_parent.size(); if (details().bounds_change & kBoundsChange_Resizes) { - gfx::Size min_size = GetTarget()->delegate() - ? GetTarget()->delegate()->GetMinimumSize() - : gfx::Size(); + const gfx::Size min_size = GetTarget()->delegate() + ? GetTarget()->delegate()->GetMinimumSize() + : gfx::Size(); size.SetSize(GetWidthForDrag(min_size.width(), delta_x), GetHeightForDrag(min_size.height(), delta_y)); } else if (!details().restore_bounds_in_parent.IsEmpty() && @@ -434,7 +434,7 @@ return size; } -int WindowResizer::GetWidthForDrag(int min_width, int* delta_x) { +int WindowResizer::GetWidthForDrag(int min_width, int* delta_x) const { int width = details().initial_bounds_in_parent.width(); if (details().size_change_direction & kBoundsChangeDirection_Horizontal) { // Along the right edge, positive delta_x increases the window size. @@ -468,7 +468,7 @@ return width; } -int WindowResizer::GetHeightForDrag(int min_height, int* delta_y) { +int WindowResizer::GetHeightForDrag(int min_height, int* delta_y) const { int height = details().initial_bounds_in_parent.height(); if (details().size_change_direction & kBoundsChangeDirection_Vertical) { // Along the bottom edge, positive delta_y increases the window size.
diff --git a/ash/wm/window_resizer.h b/ash/wm/window_resizer.h index 38d699b..7470d44c 100644 --- a/ash/wm/window_resizer.h +++ b/ash/wm/window_resizer.h
@@ -29,8 +29,8 @@ namespace ash { class PresentationTimeRecorder; -// WindowResizer is used by ToplevelWindowEventFilter to handle dragging, moving -// or resizing a window. All coordinates passed to this are in the parent +// WindowResizer is used by ToplevelWindowEventHandler to handle dragging, +// moving or resizing a window. All coordinates passed to this are in the parent // windows coordinates. class ASH_EXPORT WindowResizer { public: @@ -51,10 +51,10 @@ virtual ~WindowResizer(); - // Returns a bitmask of the kBoundsChange_ values. + // Returns a bitmask of the `kBoundsChange_*` values. static int GetBoundsChangeForWindowComponent(int component); - // Returns a bitmask of the kBoundsChange_ values. + // Returns a bitmask of the `kBoundsChangeDirection_*` values. static int GetPositionChangeDirectionForWindowComponent(int window_component); // Invoked to drag/move/resize the window. |location| is in the coordinates @@ -117,13 +117,13 @@ const gfx::PointF& event_location); // Returns the size of the window for the drag. - gfx::Size GetSizeForDrag(int* delta_x, int* delta_y); + gfx::Size GetSizeForDrag(int* delta_x, int* delta_y) const; - // Returns the width of the window. - int GetWidthForDrag(int min_width, int* delta_x); + // Called by `GetSizeForDrag` to get the width of the window for the drag. + int GetWidthForDrag(int min_width, int* delta_x) const; - // Returns the height of the drag. - int GetHeightForDrag(int min_height, int* delta_y); + // Called by `GetSizeForDrag` to get the height of the window for the drag. + int GetHeightForDrag(int min_height, int* delta_y) const; // Updates |new_bounds| to adhere to the aspect ratio. void CalculateBoundsWithAspectRatio(float aspect_ratio,
diff --git a/base/base64.cc b/base/base64.cc index 660ab8d..c877aaa5 100644 --- a/base/base64.cc +++ b/base/base64.cc
@@ -6,6 +6,8 @@ #include <stddef.h> +#include <string_view> + #include "base/check.h" #include "base/numerics/checked_math.h" #include "base/strings/string_util.h" @@ -46,11 +48,11 @@ CHECK_EQ(output->size(), prefix_len + output_size); } -std::string Base64Encode(StringPiece input) { +std::string Base64Encode(std::string_view input) { return Base64Encode(base::as_byte_span(input)); } -bool Base64Decode(StringPiece input, +bool Base64Decode(std::string_view input, std::string* output, Base64DecodePolicy policy) { std::string temp; @@ -87,7 +89,7 @@ return true; } -std::optional<std::vector<uint8_t>> Base64Decode(StringPiece input) { +std::optional<std::vector<uint8_t>> Base64Decode(std::string_view input) { std::vector<uint8_t> ret(modp_b64_decode_len(input.size())); size_t input_size = input.size();
diff --git a/base/base64.h b/base/base64.h index 3ebf60c..ce2d7c04 100644 --- a/base/base64.h +++ b/base/base64.h
@@ -9,11 +9,11 @@ #include <optional> #include <string> +#include <string_view> #include <vector> #include "base/base_export.h" #include "base/containers/span.h" -#include "base/strings/string_piece.h" namespace base { @@ -25,7 +25,7 @@ std::string* output); // Encodes the input string in base64. -BASE_EXPORT std::string Base64Encode(StringPiece input); +BASE_EXPORT std::string Base64Encode(std::string_view input); // Decodes the base64 input string. Returns true if successful and false // otherwise. The output string is only modified if successful. The decoding can @@ -44,12 +44,13 @@ kForgiving, }; BASE_EXPORT bool Base64Decode( - StringPiece input, + std::string_view input, std::string* output, Base64DecodePolicy policy = Base64DecodePolicy::kStrict); // Decodes the base64 input string. Returns `std::nullopt` if unsuccessful. -BASE_EXPORT std::optional<std::vector<uint8_t>> Base64Decode(StringPiece input); +BASE_EXPORT std::optional<std::vector<uint8_t>> Base64Decode( + std::string_view input); } // namespace base
diff --git a/base/base64_decode_fuzzer.cc b/base/base64_decode_fuzzer.cc index 557caf8..16a16a330 100644 --- a/base/base64_decode_fuzzer.cc +++ b/base/base64_decode_fuzzer.cc
@@ -3,13 +3,13 @@ // found in the LICENSE file. #include <string> +#include <string_view> #include "base/base64.h" -#include "base/strings/string_piece.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::string decode_output; - base::StringPiece data_piece(reinterpret_cast<const char*>(data), size); + std::string_view data_piece(reinterpret_cast<const char*>(data), size); base::Base64Decode(data_piece, &decode_output); return 0; }
diff --git a/base/base64_encode_fuzzer.cc b/base/base64_encode_fuzzer.cc index bda3989..969a80f 100644 --- a/base/base64_encode_fuzzer.cc +++ b/base/base64_encode_fuzzer.cc
@@ -3,22 +3,23 @@ // found in the LICENSE file. #include <string> +#include <string_view> #include "base/base64.h" #include "base/check_op.h" -#include "base/strings/string_piece.h" // Encode some random data, and then decode it. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { base::span<const uint8_t> data_span(data, size); - base::StringPiece data_piece(reinterpret_cast<const char*>(data), size); + std::string_view data_piece(reinterpret_cast<const char*>(data), size); const std::string encode_output = base::Base64Encode(data_span); std::string decode_output; CHECK(base::Base64Decode(encode_output, &decode_output)); CHECK_EQ(data_piece, decode_output); - // Also run the StringPiece variant and check that it gives the same results. + // Also run the std::string_view variant and check that it gives the same + // results. CHECK_EQ(encode_output, base::Base64Encode(data_piece)); return 0;
diff --git a/base/base64_unittest.cc b/base/base64_unittest.cc index b8705e6..1b110c8e 100644 --- a/base/base64_unittest.cc +++ b/base/base64_unittest.cc
@@ -4,6 +4,8 @@ #include "base/base64.h" +#include <string_view> + #include "base/numerics/checked_math.h" #include "base/strings/escape.h" #include "base/test/gtest_util.h" @@ -99,10 +101,10 @@ std::string binary_encoded = Base64Encode(kData); - // Check that encoding the same data through the StringPiece interface gives - // the same results. + // Check that encoding the same data through the std::string_view interface + // gives the same results. std::string string_piece_encoded = Base64Encode( - StringPiece(reinterpret_cast<const char*>(kData), sizeof(kData))); + std::string_view(reinterpret_cast<const char*>(kData), sizeof(kData))); EXPECT_EQ(binary_encoded, string_piece_encoded);
diff --git a/base/base64url.cc b/base/base64url.cc index daf91ff..b68a83ab 100644 --- a/base/base64url.cc +++ b/base/base64url.cc
@@ -6,6 +6,8 @@ #include <stddef.h> +#include <string_view> + #include "base/base64.h" #include "base/numerics/safe_math.h" #include "base/strings/string_util.h" @@ -22,12 +24,12 @@ const char kBase64Chars[] = "+/"; const char kBase64UrlSafeChars[] = "-_"; -class StringPieceOrString { +class StringViewOrString { public: - explicit StringPieceOrString(StringPiece piece) : piece_(piece) {} - explicit StringPieceOrString(std::string str) : str_(std::move(str)) {} + explicit StringViewOrString(std::string_view piece) : piece_(piece) {} + explicit StringViewOrString(std::string str) : str_(std::move(str)) {} - StringPiece get() const { + std::string_view get() const { if (str_) { return *str_; } @@ -36,12 +38,12 @@ private: const std::optional<std::string> str_; - const StringPiece piece_; + const std::string_view piece_; }; // Converts the base64url `input` into a plain base64 string. -std::optional<StringPieceOrString> Base64ToBase64URL( - StringPiece input, +std::optional<StringViewOrString> Base64ToBase64URL( + std::string_view input, Base64UrlDecodePolicy policy) { // Characters outside of the base64url alphabet are disallowed, which includes // the {+, /} characters found in the conventional base64 alphabet. @@ -69,7 +71,7 @@ } if (required_padding_characters == 0 && !needs_replacement) { - return StringPieceOrString(input); + return StringViewOrString(input); } // If the string either needs replacement of URL-safe characters to normal @@ -91,7 +93,7 @@ // Append the necessary padding characters. base64_input.resize(out_size.ValueOrDie(), '='); - return StringPieceOrString(std::move(base64_input)); + return StringViewOrString(std::move(base64_input)); } } // namespace @@ -120,16 +122,16 @@ } } -void Base64UrlEncode(StringPiece input, +void Base64UrlEncode(std::string_view input, Base64UrlEncodePolicy policy, std::string* output) { Base64UrlEncode(base::as_byte_span(input), policy, output); } -bool Base64UrlDecode(StringPiece input, +bool Base64UrlDecode(std::string_view input, Base64UrlDecodePolicy policy, std::string* output) { - std::optional<StringPieceOrString> base64_input = + std::optional<StringViewOrString> base64_input = Base64ToBase64URL(input, policy); if (!base64_input) { return false; @@ -138,9 +140,9 @@ } std::optional<std::vector<uint8_t>> Base64UrlDecode( - StringPiece input, + std::string_view input, Base64UrlDecodePolicy policy) { - std::optional<StringPieceOrString> base64_input = + std::optional<StringViewOrString> base64_input = Base64ToBase64URL(input, policy); if (!base64_input) { return std::nullopt;
diff --git a/base/base64url.h b/base/base64url.h index 6fa0484..b18a6d58 100644 --- a/base/base64url.h +++ b/base/base64url.h
@@ -7,11 +7,11 @@ #include <optional> #include <string> +#include <string_view> #include <vector> #include "base/base_export.h" #include "base/containers/span.h" -#include "base/strings/string_piece.h" namespace base { @@ -33,7 +33,7 @@ std::string* output); // Same as the previous function, but accepts an input string. -BASE_EXPORT void Base64UrlEncode(StringPiece input, +BASE_EXPORT void Base64UrlEncode(std::string_view input, Base64UrlEncodePolicy policy, std::string* output); @@ -53,13 +53,13 @@ // // The |policy| defines whether padding will be required, ignored or disallowed // altogether. |input| and |*output| may reference the same storage. -[[nodiscard]] BASE_EXPORT bool Base64UrlDecode(StringPiece input, +[[nodiscard]] BASE_EXPORT bool Base64UrlDecode(std::string_view input, Base64UrlDecodePolicy policy, std::string* output); // Same as the previous function, but writing to a `std::vector`. [[nodiscard]] BASE_EXPORT std::optional<std::vector<uint8_t>> Base64UrlDecode( - StringPiece input, + std::string_view input, Base64UrlDecodePolicy policy); } // namespace base
diff --git a/base/base64url_unittest.cc b/base/base64url_unittest.cc index ddf072d5..30ee347 100644 --- a/base/base64url_unittest.cc +++ b/base/base64url_unittest.cc
@@ -4,6 +4,8 @@ #include "base/base64url.h" +#include <string_view> + #include "base/ranges/algorithm.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -22,11 +24,11 @@ Base64UrlEncode(kData, Base64UrlEncodePolicy::INCLUDE_PADDING, &binary_encoded_with_padding); - // Check that encoding the same binary data through the StringPiece interface - // gives the same result. + // Check that encoding the same binary data through the std::string_view + // interface gives the same result. std::string string_encoded_with_padding; Base64UrlEncode( - StringPiece(reinterpret_cast<const char*>(kData), sizeof(kData)), + std::string_view(reinterpret_cast<const char*>(kData), sizeof(kData)), Base64UrlEncodePolicy::INCLUDE_PADDING, &string_encoded_with_padding); EXPECT_EQ(binary_encoded_with_padding, string_encoded_with_padding); @@ -51,11 +53,11 @@ Base64UrlEncode(kData, Base64UrlEncodePolicy::OMIT_PADDING, &binary_encoded_without_padding); - // Check that encoding the same binary data through the StringPiece interface - // gives the same result. + // Check that encoding the same binary data through the std::string_view + // interface gives the same result. std::string string_encoded_without_padding; Base64UrlEncode( - StringPiece(reinterpret_cast<const char*>(kData), sizeof(kData)), + std::string_view(reinterpret_cast<const char*>(kData), sizeof(kData)), Base64UrlEncodePolicy::OMIT_PADDING, &string_encoded_without_padding); EXPECT_EQ(binary_encoded_without_padding, string_encoded_without_padding);
diff --git a/base/check_is_test.cc b/base/check_is_test.cc index da9cad8e..1479fac 100644 --- a/base/check_is_test.cc +++ b/base/check_is_test.cc
@@ -15,6 +15,11 @@ void check_is_test_impl(base::NotFatalUntil fatal_milestone) { CHECK(g_this_is_a_test, fatal_milestone); } + +// static +bool IsInTest::Get() { + return g_this_is_a_test; +} } // namespace base::internal namespace base::test { @@ -23,7 +28,7 @@ // code. We therefore have to also mark the symbol as exported here. BASE_EXPORT void AllowCheckIsTestForTesting() { // This CHECK ensures that `AllowCheckIsTestForTesting` is called - // just once. Since it is called in `base::TestSuite`, this should effectivly + // just once. Since it is called in `base::TestSuite`, this should effectively // prevent calls to `AllowCheckIsTestForTesting` in production code // (assuming that code has unit test coverage). // @@ -34,5 +39,4 @@ g_this_is_a_test = true; } - } // namespace base::test
diff --git a/base/check_is_test.h b/base/check_is_test.h index f53ed9d4..074b7022 100644 --- a/base/check_is_test.h +++ b/base/check_is_test.h
@@ -6,8 +6,13 @@ #define BASE_CHECK_IS_TEST_H_ #include "base/base_export.h" +#include "base/check.h" #include "base/not_fatal_until.h" +namespace web_app { +class OsIntegrationTestOverride; +} + // Code paths taken in tests are sometimes different from those taken in // production. This might be because the respective tests do not initialize some // objects that would be required for the "normal" code path. @@ -45,6 +50,18 @@ BASE_EXPORT void check_is_test_impl( base::NotFatalUntil fatal_milestone = base::NotFatalUntil::NoSpecifiedMilestoneInternal); + +// This class facilitates an allow-list for GetIsInTest(), helping prevent +// possible misuse. +class BASE_EXPORT IsInTest { + private: + friend class web_app::OsIntegrationTestOverride; + static bool Get(); +}; } // namespace base::internal +// In special cases, code should not execute in a test. This functionality is +// protected by the list of friends in `IsInTest`. +#define CHECK_IS_NOT_TEST() CHECK(!base::internal::IsInTest::Get()) + #endif // BASE_CHECK_IS_TEST_H_
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupColorFaviconProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupColorFaviconProvider.java index 583527ca..12077ae7 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupColorFaviconProvider.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupColorFaviconProvider.java
@@ -22,6 +22,7 @@ static final int TAB_GROUP_FAVICON_COLOR_LEVEL = 1; static final int FAVICON_BACKGROUND_DEFAULT_ALPHA = 255; static final int FAVICON_BACKGROUND_SELECTED_ALPHA = 0; + private static final int INVALID_COLOR_ID = -1; private final Context mContext; public TabGroupColorFaviconProvider(Context context) { @@ -74,20 +75,29 @@ return new TabFaviconFetcher() { @Override public void fetch(Callback<TabFavicon> faviconCallback) { - final @ColorInt int color = - ColorPickerUtils.getTabGroupColorPickerItemColor( - mContext, colorId, isIncognito); + if (colorId != INVALID_COLOR_ID) { + final @ColorInt int color = + ColorPickerUtils.getTabGroupColorPickerItemColor( + mContext, colorId, isIncognito); - LayerDrawable tabGroupColorIcon = - (LayerDrawable) - ResourcesCompat.getDrawable( - mContext.getResources(), - org.chromium.chrome.tab_ui.R.drawable.tab_group_color_icon, - mContext.getTheme()); - ((GradientDrawable) tabGroupColorIcon.getDrawable(TAB_GROUP_FAVICON_COLOR_LEVEL)) - .setColor(color); + LayerDrawable tabGroupColorIcon = + (LayerDrawable) + ResourcesCompat.getDrawable( + mContext.getResources(), + org.chromium.chrome.tab_ui.R.drawable + .tab_group_color_icon, + mContext.getTheme()); + ((GradientDrawable) + tabGroupColorIcon.getDrawable(TAB_GROUP_FAVICON_COLOR_LEVEL)) + .setColor(color); - faviconCallback.onResult(new TabGroupColorFavicon(tabGroupColorIcon, colorId)); + faviconCallback.onResult(new TabGroupColorFavicon(tabGroupColorIcon, colorId)); + } else { + // If the color is invalid, don't set a drawable. + faviconCallback.onResult( + new TabGroupColorFavicon( + null, org.chromium.components.tab_groups.TabGroupColorId.GREY)); + } } }; }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index f051cbe..a66d745 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -1932,12 +1932,12 @@ title, numOfRelatedTabs)); } else { - // In theory this colorId should never be INVALID, but we should aim to read - // something vs nothing if this ever fails. - final @TabGroupColorId int colorId = - TabGroupColorUtils.getOrCreateTabGroupColor( - pseudoTab.getRootId(), - (TabGroupModelFilter) mCurrentTabModelFilterSupplier.get()); + int colorId = TabGroupColorUtils.getTabGroupColor(pseudoTab.getRootId()); + // This should never be the case in practice, but if the color is invalid then set + // it to the first color in the list. + if (colorId == INVALID_COLOR_ID) { + colorId = TabGroupColorId.GREY; + } final @StringRes int colorDescRes = ColorPickerUtils.getTabGroupColorPickerItemColorAccessibilityString( colorId); @@ -1991,12 +1991,12 @@ numOfRelatedTabs)); } } else { - // In theory this colorId should never be INVALID, but we should aim to read - // something vs nothing if this ever fails. - final @TabGroupColorId int colorId = - TabGroupColorUtils.getOrCreateTabGroupColor( - pseudoTab.getRootId(), - (TabGroupModelFilter) mCurrentTabModelFilterSupplier.get()); + int colorId = TabGroupColorUtils.getTabGroupColor(pseudoTab.getRootId()); + // This should never be the case in practice, but if the color is invalid then + // set it to the first color in the list. + if (colorId == INVALID_COLOR_ID) { + colorId = TabGroupColorId.GREY; + } final @StringRes int colorDescRes = ColorPickerUtils.getTabGroupColorPickerItemColorAccessibilityString( colorId); @@ -2113,9 +2113,7 @@ if (ChromeFeatureList.sTabGroupParityAndroid.isEnabled()) { TabGroupModelFilter filter = (TabGroupModelFilter) mCurrentTabModelFilterSupplier.get(); - final @TabGroupColorId int colorId = - TabGroupColorUtils.getOrCreateTabGroupColor( - pseudoTab.getRootId(), filter); + int colorId = TabGroupColorUtils.getTabGroupColor(pseudoTab.getRootId()); faviconFetcher = mTabGroupColorFaviconProvider.getFaviconFromTabGroupColorFetcher( colorId, filter.getTabModel().isIncognito());
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiTest.java index 9492bdf3..f7c1dd71 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiTest.java
@@ -152,6 +152,12 @@ clickFirstCardFromTabSwitcher(cta); clickNthTabInDialog(cta, 4); + ViewUtils.waitForVisibleView( + allOf( + withId(R.id.tab_list_recycler_view), + isDescendantOfA(withId(R.id.bottom_controls)), + isCompletelyDisplayed())); + TestThreadUtils.runOnUiThreadBlocking( () -> { ViewGroup bottomToolbar = cta.findViewById(R.id.bottom_controls); @@ -178,6 +184,12 @@ clickFirstCardFromTabSwitcher(cta); clickNthTabInDialog(cta, 9); + ViewUtils.waitForVisibleView( + allOf( + withId(R.id.tab_list_recycler_view), + isDescendantOfA(withId(R.id.bottom_controls)), + isCompletelyDisplayed())); + TestThreadUtils.runOnUiThreadBlocking( () -> { ViewGroup bottomToolbar = cta.findViewById(R.id.bottom_controls);
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilitiesUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilitiesUnitTest.java index af775b9..b7f9ba6 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilitiesUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilitiesUnitTest.java
@@ -95,7 +95,6 @@ @Test @Config(sdk = VERSION_CODES.S) - @EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) public void testIsTabDragDropEnabled() { MultiWindowTestUtils.enableMultiInstance(); assertTrue(TabUiFeatureUtilities.isTabDragEnabled()); @@ -103,10 +102,7 @@ @Test @Config(sdk = VERSION_CODES.S) - @EnableFeatures({ - ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID, - ChromeFeatureList.TAB_DRAG_DROP_ANDROID - }) + @EnableFeatures({ChromeFeatureList.TAB_DRAG_DROP_ANDROID}) public void testIsTabDragDropEnabled_bothFlagsEnabled() { MultiWindowTestUtils.enableMultiInstance(); assertThrows(AssertionError.class, () -> TabUiFeatureUtilities.isTabDragEnabled()); @@ -114,7 +110,6 @@ @Test @Config(sdk = VERSION_CODES.Q) - @EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) public void testIsTabDragDropEnabled_multiInstanceDisabled() { assertFalse(TabUiFeatureUtilities.isTabDragEnabled()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/FinancialAccountsManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/FinancialAccountsManagementFragment.java index 2cfe00a..88161051 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/FinancialAccountsManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/FinancialAccountsManagementFragment.java
@@ -30,7 +30,7 @@ /** Fragment showing management options for financial accounts like Pix, e-Wallets etc. */ public class FinancialAccountsManagementFragment extends ChromeBaseSettingsFragment - implements PersonalDataManagerObserver { + implements PersonalDataManagerObserver, Preference.OnPreferenceChangeListener { private static Callback<Fragment> sObserverForTest; @VisibleForTesting static final String PREFERENCE_KEY_PIX = "pix"; @@ -39,6 +39,7 @@ static final String TITLE_KEY = "financial_accounts_management_title"; private PersonalDataManager mPersonalDataManager; + private BankAccount[] mBankAccounts; // ChromeBaseSettingsFramgent override. @Override @@ -89,18 +90,45 @@ getPreferenceScreen().removeAll(); getPreferenceScreen().setOrderingAsAdded(true); - BankAccount[] bankAccounts = mPersonalDataManager.getMaskedBankAccounts(); - if (bankAccounts.length > 0) { - ChromeSwitchPreference pixSwitch = new ChromeSwitchPreference(getStyledContext()); - pixSwitch.setKey(PREFERENCE_KEY_PIX); - pixSwitch.setTitle(R.string.settings_manage_other_financial_accounts_pix); - getPreferenceScreen().addPreference(pixSwitch); - for (BankAccount bankAccount : bankAccounts) { - getPreferenceScreen().addPreference(getPreferenceForBankAccount(bankAccount)); + mBankAccounts = mPersonalDataManager.getMaskedBankAccounts(); + if (mBankAccounts.length == 0) { + return; + } + + boolean isFacilitatedPaymentsPixEnabled = + mPersonalDataManager.getFacilitatedPaymentsPixPref(); + ChromeSwitchPreference pixSwitch = new ChromeSwitchPreference(getStyledContext()); + pixSwitch.setChecked(isFacilitatedPaymentsPixEnabled); + pixSwitch.setKey(PREFERENCE_KEY_PIX); + pixSwitch.setTitle(R.string.settings_manage_other_financial_accounts_pix); + getPreferenceScreen().addPreference(pixSwitch); + if (isFacilitatedPaymentsPixEnabled) { + // Show bank accounts only if the Pix switch is enabled. + addPixAccountPreferences(); + } + pixSwitch.setOnPreferenceChangeListener(this); + } + + private void removePixAccountPreferences() { + for (BankAccount bankAccount : mBankAccounts) { + Preference bankAccountPref = + getPreferenceScreen() + .findPreference( + String.format( + PREFERENCE_KEY_PIX_BANK_ACCOUNT, + bankAccount.getInstrumentId())); + if (bankAccountPref != null) { + getPreferenceScreen().removePreference(bankAccountPref); } } } + private void addPixAccountPreferences() { + for (BankAccount bankAccount : mBankAccounts) { + getPreferenceScreen().addPreference(getPreferenceForBankAccount(bankAccount)); + } + } + private Preference getPreferenceForBankAccount(BankAccount bankAccount) { Preference bankAccountPref = new Preference(getStyledContext()); @@ -149,6 +177,22 @@ return getPreferenceManager().getContext(); } + // Preference.OnPreferenceChangeListener override. + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (preference.getKey().equals(PREFERENCE_KEY_PIX)) { + boolean isPixEnabled = (boolean) newValue; + mPersonalDataManager.setFacilitatedPaymentsPixPref(isPixEnabled); + if (isPixEnabled) { + addPixAccountPreferences(); + } else { + removePixAccountPreferences(); + } + return true; + } + return false; + } + // PersonalDataManagerObserver implementation. @Override public void onPersonalDataChanged() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/LayerTitleCache.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/LayerTitleCache.java index cf8d36cd..7b285bd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/LayerTitleCache.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/LayerTitleCache.java
@@ -166,13 +166,14 @@ TabGroupModelFilter filter = (TabGroupModelFilter) mTabModelSelector.getTabModelFilterProvider().getTabModelFilter(incognito); + if (!filter.tabGroupExistsForRootId(groupRootId)) return; + String titleString = filter.getTabGroupTitle(groupRootId); getUpdatedGroupTitle(groupRootId, titleString, incognito); } public String getUpdatedGroupTitle(int groupRootId, String titleString, boolean incognito) { - // TODO(crbug.com/331642736): Investigate skipping creating the bitmap for empty titles. - if (titleString == null) titleString = ""; + if (TextUtils.isEmpty(titleString)) return null; getUpdatedGroupTitleInternal(groupRootId, titleString, incognito); return titleString; @@ -305,8 +306,6 @@ } public void removeGroupTitle(int rootId) { - // TODO(crbug.com/326492787): Currently unused. Call to release bitmaps when we actually - // observe tab group changes (i.e. call this when a tab group is destroyed). Title title = mGroupTitles.get(rootId); if (title == null) return; title.unregister();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStacker.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStacker.java index e1a76e7..cc22c91 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStacker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStacker.java
@@ -50,9 +50,17 @@ StripLayoutView[] indexOrderedViews, float xOffset, float visibleWidth) { for (int i = 0; i < indexOrderedViews.length; i++) { StripLayoutView view = indexOrderedViews[i]; - view.setVisible( - (view.getDrawX() + view.getWidth()) >= xOffset - && view.getDrawX() <= xOffset + visibleWidth); + float drawX; + float width; + if (view instanceof StripLayoutGroupTitle groupTitle) { + drawX = groupTitle.getPaddedX(); + width = groupTitle.getBottomIndicatorWidth(); + } else { + drawX = view.getDrawX(); + width = view.getWidth(); + } + + view.setVisible((drawX + width) >= xOffset && drawX <= xOffset + visibleWidth); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutGroupTitle.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutGroupTitle.java index d269327..33c2d05c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutGroupTitle.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutGroupTitle.java
@@ -20,6 +20,18 @@ * onto the GL canvas. */ public class StripLayoutGroupTitle extends StripLayoutView { + /** Delegate for additional group title functionality. */ + public interface StripLayoutGroupTitleDelegate { + // TODO(https://crbug.com/326492955): Implement click to collapse/expand. + + /** + * Releases the resources associated with this group indicator. + * + * @param rootId The root ID of the given group indicator. + */ + void releaseResourcesForGroupTitle(int rootId); + } + /** A property for animations to use for changing the width of the bottom indicator. */ public static final FloatProperty<StripLayoutGroupTitle> BOTTOM_INDICATOR_WIDTH = new FloatProperty<>("bottomIndicatorWidth") { @@ -51,6 +63,9 @@ private static final int EFFECTIVE_MIN_WIDTH = MIN_VISUAL_WIDTH_DP + WIDTH_MARGINS_DP; private static final int EFFECTIVE_MAX_WIDTH = MAX_VISUAL_WIDTH_DP + WIDTH_MARGINS_DP; + // External influences. + private final StripLayoutGroupTitleDelegate mDelegate; + // State variables. private final boolean mIncognito; @@ -74,6 +89,7 @@ /** * Create a {@link StripLayoutGroupTitle} that represents the TabGroup for the {@code rootId}. * + * @param delegate The delegate for additional strip group title functionality. * @param incognito Whether or not this tab group is Incognito. * @param rootId The root ID for the tab group. * @param title The title of the tab group, if it is set. Null otherwise. @@ -81,6 +97,7 @@ * @param color The color of the tab group. */ public StripLayoutGroupTitle( + StripLayoutGroupTitleDelegate delegate, boolean incognito, int rootId, @Nullable String title, @@ -88,6 +105,7 @@ @ColorInt int color) { assert rootId != Tab.INVALID_TAB_ID : "Tried to create a group title for an invalid group."; + mDelegate = delegate; mIncognito = incognito; updateRootId(rootId); @@ -142,6 +160,13 @@ } @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + + if (!visible) mDelegate.releaseResourcesForGroupTitle(mRootId); + } + + @Override public String getAccessibilityDescription() { return mAccessibilityDescription; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java index ac8d6ac3..05ef800 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -51,6 +51,8 @@ import org.chromium.chrome.browser.compositor.layouts.components.CompositorButton.CompositorOnClickHandler; import org.chromium.chrome.browser.compositor.layouts.components.TintedCompositorButton; import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackScroller; +import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutGroupTitle.StripLayoutGroupTitleDelegate; +import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutTab.StripLayoutTabDelegate; import org.chromium.chrome.browser.compositor.overlays.strip.TabLoadTracker.TabLoadTrackerCallback; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.layouts.animation.CompositorAnimator; @@ -59,6 +61,7 @@ import org.chromium.chrome.browser.tabmodel.TabCreator; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelUtils; +import org.chromium.chrome.browser.tasks.tab_groups.TabGroupColorUtils; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilterObserver; import org.chromium.chrome.browser.tasks.tab_management.ColorPickerUtils; @@ -85,7 +88,7 @@ * * <p>The stacking and visual behavior is driven by setting a {@link StripStacker}. */ -public class StripLayoutHelper implements StripLayoutTab.StripLayoutTabDelegate { +public class StripLayoutHelper implements StripLayoutTabDelegate, StripLayoutGroupTitleDelegate { /** A property for animations to use for changing the X offset of the tab. */ public static final FloatProperty<StripLayoutHelper> SCROLL_OFFSET = new FloatProperty<StripLayoutHelper>("scrollOffset") { @@ -173,6 +176,7 @@ private static final float CLOSE_BTN_VISIBILITY_THRESHOLD_START = 96.f; private static final long TAB_SWITCH_METRICS_MAX_ALLOWED_SCROLL_INTERVAL = DateUtils.MINUTE_IN_MILLIS; + private static final int INVALID_COLOR_ID = -1; // Histogram Constants private static final String PLACEHOLDER_LEFTOVER_TABS_HISTOGRAM_NAME = @@ -252,14 +256,14 @@ if (groupTitle == null) return; int widthPx = mLayerTitleCache.getGroupTitleWidth(mIncognito, newTitle); - updateGroupTitle(rootId, newTitle, widthPx); + updateGroupTitle(groupTitle, newTitle, widthPx); updateGroupAccessibilityDescription(groupTitle); - // TODO(crbug.com/331664842): When group title bitmaps are culled, guard this - // with groupTitle.isVisible() check to avoid creating when unneeded. - mLayerTitleCache.getUpdatedGroupTitle( - rootId, groupTitle.getTitle(), mIncognito); - mRenderHost.requestRender(); + if (groupTitle.isVisible()) { + mLayerTitleCache.getUpdatedGroupTitle( + rootId, groupTitle.getTitle(), mIncognito); + mRenderHost.requestRender(); + } } @Override @@ -274,18 +278,25 @@ groupTitle.updateTint(color); // Title may also need to change color. - // TODO(crbug.com/331664842): When group title bitmaps are culled, guard this - // with groupTitle.isVisible() check to avoid creating when unneeded. - mLayerTitleCache.getUpdatedGroupTitle( - rootId, groupTitle.getTitle(), mIncognito); - mRenderHost.requestRender(); + if (groupTitle.isVisible()) { + mLayerTitleCache.getUpdatedGroupTitle( + rootId, groupTitle.getTitle(), mIncognito); + mRenderHost.requestRender(); + } } @Override public void didChangeGroupRootId(int oldRootId, int newRootId) { + releaseResourcesForGroupTitle(oldRootId); + StripLayoutGroupTitle groupTitle = findGroupTitle(oldRootId); if (groupTitle != null) groupTitle.updateRootId(newRootId); } + + @Override + public void didRemoveTabGroup(int oldRootId) { + releaseResourcesForGroupTitle(oldRootId); + } }; // External influences @@ -2422,11 +2433,9 @@ groupTitle.setAccessibilityDescription(buildGroupAccessibilityDescription(groupTitle)); } - private void updateGroupTitle(int rootId, String title, int widthPx) { - StripLayoutGroupTitle groupTitle = findGroupTitle(rootId); - if (groupTitle == null) return; - - updateGroupTitle(groupTitle, title, widthPx); + @Override + public void releaseResourcesForGroupTitle(int rootId) { + mLayerTitleCache.removeGroupTitle(rootId); } private void updateGroupTitle(StripLayoutGroupTitle groupTitle, String title, int widthPx) { @@ -2455,7 +2464,12 @@ } private StripLayoutGroupTitle createGroupTitle(int rootId) { - @TabGroupColorId int colorId = mTabGroupModelFilter.getTabGroupColor(rootId); + int colorId = TabGroupColorUtils.getTabGroupColor(rootId); + // If the color is invalid, temporarily assign a default placeholder color. + if (colorId == INVALID_COLOR_ID) { + colorId = TabGroupColorId.GREY; + } + @ColorInt int color = ColorPickerUtils.getTabGroupColorPickerItemColor(mContext, colorId, mIncognito); String titleString = mTabGroupModelFilter.getTabGroupTitle(rootId); @@ -2468,7 +2482,7 @@ } StripLayoutGroupTitle groupTitle = - new StripLayoutGroupTitle(mIncognito, rootId, titleString, textWidth, color); + new StripLayoutGroupTitle(this, mIncognito, rootId, titleString, textWidth, color); updateGroupAccessibilityDescription(groupTitle); pushPropertiesToGroupTitle(groupTitle); @@ -2862,7 +2876,7 @@ // 4. Calculate which tabs are visible. float stripWidth = getVisibleRightBound() - getVisibleLeftBound(); - mStripStacker.performOcclusionPass(mStripTabs, getVisibleLeftBound(), stripWidth); + mStripStacker.performOcclusionPass(mStripViews, getVisibleLeftBound(), stripWidth); // 5. Create render list. createRenderList();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java index 82e5217..8c453e6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -947,8 +947,7 @@ * or not the newly created {@link WebContents} will be hidden or not. * @param tabState State containing information about this Tab, if it was persisted. * @param initializeRenderer Determines whether or not we initialize renderer with {@link - * WebContents} creation. The CREATE_NEW_TAB_INITIALIZE_RENDERER feature also controls this - * parameter, which initializes the renderer when it is enabled. + * WebContents} creation. */ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) void initialize( @@ -962,14 +961,7 @@ boolean initializeRenderer) { try { TraceEvent.begin("Tab.initialize"); - // If the feature is enabled, the renderer will always be initialized during the - // WebContents creation. It is an experimental performance optimization to speed - // up navigation. - initializeRenderer = - ChromeFeatureList.isEnabled( - ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER) - ? true - : initializeRenderer; + if (parent != null) { mParentId = parent.getId(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ViewTransitionPixelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ViewTransitionPixelTest.java index d47b37a90..def1c333 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ViewTransitionPixelTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ViewTransitionPixelTest.java
@@ -26,9 +26,7 @@ import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.CriteriaNotSatisfiedException; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.Features.DisableFeatures; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.fullscreen.FullscreenManagerTestUtils; import org.chromium.chrome.browser.tab.TabStateBrowserControlsVisibilityDelegate; @@ -428,8 +426,6 @@ @Test @MediumTest @Feature({"RenderTest"}) - // TODO(crbug.com/1453741): Fix test with CREATE_NEW_TAB_INITIALIZE_RENDERER. - @DisableFeatures(ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER) public void testVirtualKeyboardResizesVisual() throws Throwable { startKeyboardTest(VirtualKeyboardMode.RESIZES_VISUAL); @@ -472,8 +468,6 @@ @Test @MediumTest @Feature({"RenderTest"}) - // TODO(crbug.com/1453741): Fix test with CREATE_NEW_TAB_INITIALIZE_RENDERER. - @DisableFeatures(ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER) public void testVirtualKeyboardResizesContent() throws Throwable { startKeyboardTest(VirtualKeyboardMode.RESIZES_CONTENT); @@ -516,8 +510,6 @@ @Test @MediumTest @Feature({"RenderTest"}) - // TODO(crbug.com/1453741): Fix test with CREATE_NEW_TAB_INITIALIZE_RENDERER. - @DisableFeatures(ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER) public void testDialog() throws Throwable { String url = "/chrome/test/data/android/view_transition_dialog.html"; mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(url)); @@ -548,8 +540,6 @@ @Test @MediumTest @Feature({"RenderTest"}) - // TODO(crbug.com/1453741): Fix test with CREATE_NEW_TAB_INITIALIZE_RENDERER. - @DisableFeatures(ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER) public void testPageWiderThanICB() throws Throwable { String url = "/chrome/test/data/android/view_transition_wider_than_icb.html"; mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(url)); @@ -585,8 +575,6 @@ @Test @MediumTest @Feature({"RenderTest"}) - // TODO(crbug.com/1453741): Fix test with CREATE_NEW_TAB_INITIALIZE_RENDERER. - @DisableFeatures(ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER) public void testBrowserControlsRootSnapshotControlsOverlay() throws Throwable { String url = "/chrome/test/data/android/view_transition_browser_controls.html"; mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(url)); @@ -634,8 +622,6 @@ @Test @MediumTest @Feature({"RenderTest"}) - // TODO(crbug.com/1453741): Fix test with CREATE_NEW_TAB_INITIALIZE_RENDERER. - @DisableFeatures(ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER) public void testBrowserControlsRootSnapshotControlsPush() throws Throwable { String url = "/chrome/test/data/android/view_transition_browser_controls.html"; mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(url)); @@ -675,8 +661,6 @@ @Test @MediumTest @Feature({"RenderTest"}) - // TODO(crbug.com/1453741): Fix test with CREATE_NEW_TAB_INITIALIZE_RENDERER. - @DisableFeatures(ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER) public void testBrowserControlsChildSnapshotControlsOverlay() throws Throwable { String url = "/chrome/test/data/android/view_transition_browser_controls_child.html"; mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(url)); @@ -723,8 +707,6 @@ @Test @MediumTest @Feature({"RenderTest"}) - // TODO(crbug.com/1453741): Fix test with CREATE_NEW_TAB_INITIALIZE_RENDERER. - @DisableFeatures(ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER) public void testBrowserControlsChildSnapshotControlsPush() throws Throwable { String url = "/chrome/test/data/android/view_transition_browser_controls_child.html"; mActivityTestRule.startMainActivityWithURL(mTestServer.getURL(url));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/WarmupManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/WarmupManagerTest.java index 0453e4c..e32ce9b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/WarmupManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/WarmupManagerTest.java
@@ -33,11 +33,9 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.Features.EnableFeatures; import org.chromium.base.test.util.HistogramWatcher; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.WarmupManager.SpareTabFinalStatus; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.profiles.OTRProfileID; @@ -550,31 +548,6 @@ pageLoadHistogramWatcher.pollInstrumentationThreadUntilSatisfied(); } - /** - * Tests that we are able to create new tab along with initializing renderer when the feature - * CREATE_NEW_TAB_INITIALIZE_RENDERER is enabled. - */ - @Test - @MediumTest - @Feature({"SpareTab"}) - @UiThreadTest - @EnableFeatures({ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER}) - public void testOnTabCreationWithInitializeRenderer() { - Profile profile = getProfile(ProfileType.REGULAR_PROFILE); - mWarmupManager.createRegularSpareTab(profile); - Assert.assertTrue(mWarmupManager.hasSpareTab(profile)); - - Tab tab = mWarmupManager.takeSpareTab(profile, TabLaunchType.FROM_TAB_GROUP_UI); - WebContents webContents = tab.getWebContents(); - Assert.assertNotNull(tab); - Assert.assertNotNull(webContents); - Assert.assertEquals(TabLaunchType.FROM_TAB_GROUP_UI, tab.getLaunchType()); - - // RenderFrame should be created when the CREATE_NEW_TAB_INITIALIZE_RENDERER is enabled. - Assert.assertTrue(webContents.getMainFrame().isRenderFrameLive()); - tab.destroy(); - } - @Test @SmallTest @Restriction({DeviceRestriction.RESTRICTION_TYPE_NON_AUTO})
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/FinancialAccountsManagementFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/FinancialAccountsManagementFragmentTest.java index 6eaaa1d..e1dec76 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/FinancialAccountsManagementFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/FinancialAccountsManagementFragmentTest.java
@@ -30,6 +30,8 @@ import org.chromium.chrome.browser.autofill.AutofillUiUtils.CardIconSpecs; import org.chromium.chrome.browser.autofill.PersonalDataManager; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.preferences.Pref; +import org.chromium.chrome.browser.profiles.ProfileManager; import org.chromium.chrome.browser.settings.SettingsActivity; import org.chromium.chrome.browser.settings.SettingsActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -40,6 +42,8 @@ import org.chromium.components.autofill.payments.PaymentRail; import org.chromium.components.browser_ui.settings.ChromeSwitchPreference; import org.chromium.components.image_fetcher.test.TestImageFetcher; +import org.chromium.components.prefs.PrefService; +import org.chromium.components.user_prefs.UserPrefs; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.url.GURL; @@ -47,8 +51,8 @@ /** Instrumentation tests for FinancialAccountsManagementFragment. */ @RunWith(ChromeJUnit4ClassRunner.class) -@Batch(Batch.PER_CLASS) @EnableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_SYNCING_OF_PIX_BANK_ACCOUNTS}) +@Batch(Batch.PER_CLASS) public class FinancialAccountsManagementFragmentTest { @Rule public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor(); @Rule public final AutofillTestRule rule = new AutofillTestRule(); @@ -98,6 +102,8 @@ CardIconSpecs.create( ContextUtils.getApplicationContext(), CardIconSize.LARGE)); + // Set the Pix pref to true. + getPrefService().setBoolean(Pref.FACILITATED_PAYMENTS_PIX, true); }); } @@ -112,44 +118,68 @@ }); } + // Test that when Pix accounts are available the Pix preference toggle is shown. @Test @MediumTest - public void testPixAccountAvailable_PixPrefShown() throws Exception { + public void testPixAccountAvailable_pixSwitchShown() throws Exception { AutofillTestHelper.addMaskedBankAccount(PIX_BANK_ACCOUNT); SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); // Verify that the switch preference for Pix is displayed. - ChromeSwitchPreference pixSwitch = - (ChromeSwitchPreference) - getPreferenceScreen(activity) - .findPreference( - FinancialAccountsManagementFragment.PREFERENCE_KEY_PIX); + ChromeSwitchPreference pixSwitch = getPixSwitchPreference(activity); assertThat(pixSwitch).isNotNull(); } + // Test that when Pix accounts are not available the Pix preference toggle is not shown. @Test @MediumTest - public void testPixAccountNotAvailable_PixPrefNotShown() throws Exception { + public void testPixAccountNotAvailable_pixSwitchNotShown() throws Exception { SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); // Verify that the switch preference for Pix is not displayed. - ChromeSwitchPreference pixSwitch = - (ChromeSwitchPreference) - getPreferenceScreen(activity) - .findPreference( - FinancialAccountsManagementFragment.PREFERENCE_KEY_PIX); + ChromeSwitchPreference pixSwitch = getPixSwitchPreference(activity); assertThat(pixSwitch).isNull(); } + // Test that when Pix profile preference is set to true, the Pix toggle is checked. + @Test + @MediumTest + public void testPixPrefEnabled_pixSwitchEnabled() throws Exception { + AutofillTestHelper.addMaskedBankAccount(PIX_BANK_ACCOUNT); + TestThreadUtils.runOnUiThreadBlocking( + () -> { + getPrefService().setBoolean(Pref.FACILITATED_PAYMENTS_PIX, true); + }); + + SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); + + // Verify that the switch preference for Pix is displayed and is checked. + ChromeSwitchPreference pixSwitch = getPixSwitchPreference(activity); + assertThat(pixSwitch.isChecked()).isTrue(); + } + + // Test that when the Pix profile preference is set to false, the Pix toggle is not checked. + @Test + @MediumTest + public void testPixPrefDisabled_pixSwitchDisabled() throws Exception { + AutofillTestHelper.addMaskedBankAccount(PIX_BANK_ACCOUNT); + TestThreadUtils.runOnUiThreadBlocking( + () -> { + getPrefService().setBoolean(Pref.FACILITATED_PAYMENTS_PIX, false); + }); + + SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); + + // Verify that the switch preference for Pix is displayed the is not checked. + ChromeSwitchPreference pixSwitch = getPixSwitchPreference(activity); + assertThat(pixSwitch.isChecked()).isFalse(); + } + @Test @MediumTest public void testPixAccountShown() { AutofillTestHelper.addMaskedBankAccount(PIX_BANK_ACCOUNT); - String bankAccountPrefKey = - String.format( - FinancialAccountsManagementFragment.PREFERENCE_KEY_PIX_BANK_ACCOUNT, - PIX_BANK_ACCOUNT.getInstrumentId()); SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(); @@ -158,8 +188,7 @@ "Pix • %s •• %s", activity.getString(R.string.bank_account_type_checking), PIX_BANK_ACCOUNT.getAccountNumberSuffix()); - Preference bankAccountPref = - getPreferenceScreen(activity).findPreference(bankAccountPrefKey); + Preference bankAccountPref = getBankAccountPreference(activity, PIX_BANK_ACCOUNT); assertThat(bankAccountPref.getTitle()).isEqualTo(PIX_BANK_ACCOUNT.getBankName()); assertThat(bankAccountPref.getSummary()).isEqualTo(expectedPrefSummary); assertThat(bankAccountPref.getWidgetLayoutResource()) @@ -246,8 +275,74 @@ assertThat(bankAccountPref.getIcon()).isNull(); } + // Test that Pix bank accounts are removed when the Pix toggle is turned off. + @Test + @MediumTest + public void testPixSwitchDisabled_bankAccountPrefsRemoved() { + AutofillTestHelper.addMaskedBankAccount(PIX_BANK_ACCOUNT); + SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(new Bundle()); + ChromeSwitchPreference pixSwitch = getPixSwitchPreference(activity); + Preference bankAccountPref = getBankAccountPreference(activity, PIX_BANK_ACCOUNT); + assertThat(bankAccountPref).isNotNull(); + + // Set the Pix toggle to off. + TestThreadUtils.runOnUiThreadBlocking( + () -> { + pixSwitch.performClick(); + }); + + // Verify that the bank account preference is now null. + bankAccountPref = getBankAccountPreference(activity, PIX_BANK_ACCOUNT); + assertThat(bankAccountPref).isNull(); + } + + // Test that Pix bank accounts are added when the Pix toggle is turned on. + @Test + @MediumTest + public void testPixSwitchEnabled_bankAccountPrefsAdded() { + AutofillTestHelper.addMaskedBankAccount(PIX_BANK_ACCOUNT); + TestThreadUtils.runOnUiThreadBlocking( + () -> { + getPrefService().setBoolean(Pref.FACILITATED_PAYMENTS_PIX, false); + }); + SettingsActivity activity = mSettingsActivityTestRule.startSettingsActivity(new Bundle()); + ChromeSwitchPreference pixSwitch = getPixSwitchPreference(activity); + + Preference bankAccountPref = getBankAccountPreference(activity, PIX_BANK_ACCOUNT); + assertThat(bankAccountPref).isNull(); + + // Set the Pix toggle to on. + TestThreadUtils.runOnUiThreadBlocking( + () -> { + pixSwitch.performClick(); + }); + + // Verify that the bank account preference is now not null. + bankAccountPref = getBankAccountPreference(activity, PIX_BANK_ACCOUNT); + assertThat(bankAccountPref).isNotNull(); + } + private static PreferenceScreen getPreferenceScreen(SettingsActivity activity) { return ((FinancialAccountsManagementFragment) activity.getMainFragment()) .getPreferenceScreen(); } + + private static PrefService getPrefService() { + return UserPrefs.get(ProfileManager.getLastUsedRegularProfile()); + } + + private static ChromeSwitchPreference getPixSwitchPreference(SettingsActivity activity) { + return (ChromeSwitchPreference) + getPreferenceScreen(activity) + .findPreference(FinancialAccountsManagementFragment.PREFERENCE_KEY_PIX); + } + + private static Preference getBankAccountPreference( + SettingsActivity activity, BankAccount bankAccount) { + String bankAccountPrefKey = + String.format( + FinancialAccountsManagementFragment.PREFERENCE_KEY_PIX_BANK_ACCOUNT, + bankAccount.getInstrumentId()); + return getPreferenceScreen(activity).findPreference(bankAccountPrefKey); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/dragdrop/DragAndDropLauncherActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/dragdrop/DragAndDropLauncherActivityTest.java index 05e0d5d..7bf9f9f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/dragdrop/DragAndDropLauncherActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/dragdrop/DragAndDropLauncherActivityTest.java
@@ -206,10 +206,7 @@ */ @Test @LargeTest - @EnableFeatures({ - ChromeFeatureList.DRAG_DROP_TAB_TEARING, - ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID - }) + @EnableFeatures(ChromeFeatureList.DRAG_DROP_TAB_TEARING) public void testDraggedTab_newWindow() throws Exception { HistogramWatcher histogramExpectation = HistogramWatcher.newSingleRecordWatcher(
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java index ef9b5c4..c58fa10 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManagerTest.java
@@ -636,7 +636,6 @@ @Test @Config(sdk = VERSION_CODES.R) - @EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) public void testDragDropInstances_Success() { enableMultiInstance(); initializeTest(); @@ -647,7 +646,6 @@ @Test @Config(sdk = VERSION_CODES.Q) - @EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) public void testDragDropInstances_MultiInstanceNotEnabled_ReturnsNull() { initializeTest(); assertNull( @@ -670,7 +668,6 @@ @Test @Config(sdk = VERSION_CODES.S) - @EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) public void testGetDragListener() { enableMultiInstance(); initializeTest();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java index 61b2e2e6..2ee7a878 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
@@ -1537,7 +1537,6 @@ @Test @Config(sdk = Build.VERSION_CODES.R) - @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) public void testOnLongPress_WithDragDrop_OnTab() { // Extra setup for DragDrop setTabDragSourceMock(); @@ -1597,7 +1596,6 @@ @Test @Config(sdk = Build.VERSION_CODES.R) - @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) public void testOnLongPress_WithDragDrop_OffTab() { // Extra setup for DragDrop setTabDragSourceMock(); @@ -3411,7 +3409,6 @@ } @Test - @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) @Config(sdk = Build.VERSION_CODES.R) public void testDrag_AllowMovingTabOutOfStripLayout_SetActiveTab() { // Setup with 10 tabs and select tab 5. @@ -3448,7 +3445,6 @@ } @Test - @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) @Config(sdk = Build.VERSION_CODES.R) public void testDrag_clearState() { // Initialize with 10 tabs. @@ -3468,7 +3464,6 @@ } @Test - @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) @Config(sdk = Build.VERSION_CODES.R) public void testDrag_sendMoveWindowBroadcast_success() { // Setup with tabs and select first tab. @@ -3482,7 +3477,6 @@ } @Test - @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) @Config(sdk = Build.VERSION_CODES.R) public void testDrag_DragActiveClickedTabOntoStrip() { // Setup and mark the active clicked tab. @@ -3507,7 +3501,6 @@ } @Test - @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) @Config(sdk = Build.VERSION_CODES.R) public void testDrag_DragActiveClickedTabOutOfStrip() { // Setup and mark the active clicked tab. @@ -3544,7 +3537,6 @@ } @Test - @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) @Config(sdk = Build.VERSION_CODES.R) public void testDrag2_DragActiveClickedTabOutOfStrip() { // Setup and mark the active clicked tab.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabDragShadowViewUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabDragShadowViewUnitTest.java index 3f6ef17..c3c0a99 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabDragShadowViewUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripTabDragShadowViewUnitTest.java
@@ -41,10 +41,8 @@ import org.chromium.base.supplier.Supplier; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.Features; -import org.chromium.base.test.util.Features.EnableFeatures; import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.LayerTitleCache; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabUtils; import org.chromium.chrome.browser.tab_ui.TabContentManager; @@ -56,7 +54,6 @@ /** Unit tests for {@link StripTabDragShadowView}. */ @RunWith(BaseRobolectricTestRunner.class) -@EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) public class StripTabDragShadowViewUnitTest { @Rule public ActivityScenarioRule<TestActivity> mActivityScenarioRule =
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java index 27f79a0d..914b056 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java
@@ -91,7 +91,6 @@ import java.util.Set; /** Tests for {@link TabDragSource}. */ -@EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) @DisableFeatures(ChromeFeatureList.DRAG_DROP_TAB_TEARING) @RunWith(BaseRobolectricTestRunner.class) @Config(qualifiers = "sw600dp", sdk = VERSION_CODES.S, shadows = ShadowToast.class) @@ -239,7 +238,6 @@ } @DisableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) - @EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) @Test public void test_startTabDragAction_withTabLinkDragDropFF_returnsTrueForValidTab() { // Act and verify. @@ -334,7 +332,6 @@ ChromeFeatureList.TAB_DRAG_DROP_ANDROID, ChromeFeatureList.DRAG_DROP_TAB_TEARING }) - @EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) public void test_startTabDragAction_returnFalseForNonSplitScreen() { // Set params. when(mMultiWindowUtils.isInMultiWindowMode(mActivity)).thenReturn(false); @@ -352,7 +349,6 @@ } @Test - @EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) @DisableFeatures({ ChromeFeatureList.TAB_DRAG_DROP_ANDROID, ChromeFeatureList.DRAG_DROP_TAB_TEARING @@ -459,7 +455,6 @@ } @Test - @EnableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) @DisableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) public void test_onProvideShadowMetrics_withTabLinkDragDropFF() { // Call startDrag to set class variables.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/dragdrop/ChromeTabbedOnDragListenerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/dragdrop/ChromeTabbedOnDragListenerUnitTest.java index 1c38f4f..014aa669 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/dragdrop/ChromeTabbedOnDragListenerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/dragdrop/ChromeTabbedOnDragListenerUnitTest.java
@@ -27,7 +27,6 @@ import org.chromium.base.ContextUtils; import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.base.test.util.Features.DisableFeatures; -import org.chromium.base.test.util.Features.EnableFeatures; import org.chromium.base.test.util.HistogramWatcher; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.layouts.LayoutStateProvider; @@ -44,12 +43,7 @@ import java.lang.ref.WeakReference; @RunWith(org.chromium.base.test.BaseRobolectricTestRunner.class) -@EnableFeatures({ - ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID, -}) -@DisableFeatures({ - ChromeFeatureList.TAB_DRAG_DROP_ANDROID, -}) +@DisableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) public class ChromeTabbedOnDragListenerUnitTest { private static final int SOURCE_INSTANCE_ID = 1; @Rule public MockitoRule mMockitoProcessorRule = MockitoJUnit.rule();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31UnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31UnitTest.java index a835481..d882f85ed 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31UnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31UnitTest.java
@@ -1029,6 +1029,7 @@ @SmallTest @Config(sdk = 31) @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) + @DisableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) public void testTabMove_MoveTabToNewWindow_calledWithDesiredParameters() { mMultiInstanceManager.mTestBuildInstancesList = true; MultiWindowTestUtils.enableMultiInstance(); @@ -1079,6 +1080,7 @@ @SmallTest @Config(sdk = 31) @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) + @DisableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) public void testTabMove_MoveTabToNewWindow_BeyondMaxWindows_CallsOnly_OpenNewWindow() { mMultiInstanceManager.mTestBuildInstancesList = true; MultiWindowTestUtils.enableMultiInstance(); @@ -1107,6 +1109,7 @@ @Test @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) + @DisableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID) @Config(sdk = 31) public void testTabMove_MoveTabToCurrentWindow_calledWithDesiredParameters() { int tabAtIndex = 0; @@ -1130,7 +1133,10 @@ } @Test - @DisableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID) + @DisableFeatures({ + ChromeFeatureList.TAB_DRAG_DROP_ANDROID, + ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID + }) public void testTabMove_MoveTabToWindow_notCalled() { int tabAtIndex = 0; MultiInstanceManagerApi31 multiInstanceManager =
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h index bc92b9e..563b8ca 100644 --- a/chrome/app/chrome_command_ids.h +++ b/chrome/app/chrome_command_ids.h
@@ -220,6 +220,7 @@ #define IDC_SHOW_HISTORY_CLUSTERS_SIDE_PANEL 40025 #define IDC_PROFILING_ENABLED 40028 #define IDC_BOOKMARKS_MENU 40029 +#define IDC_SAVED_TAB_GROUPS_MENU 40030 #define IDC_EXTENSION_ERRORS 40031 #define IDC_SHOW_SETTINGS_CHANGE_FIRST 40033 #define IDC_SHOW_SETTINGS_CHANGE_LAST 40133
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 797057c..fb0a6ee 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -11131,6 +11131,9 @@ <message name="IDS_CREATE_NEW_TAB_GROUP" desc="The label of item in Everything menu to create a new tab group."> Create new tab group </message> + <message name="IDS_SAVED_TAB_GROUPS_MENU" desc="The title of the 'Tab groups' menu in the App Menu."> + Tab groups + </message> </if> <if expr="use_titlecase"> <message name="IDS_SAVED_TAB_GROUP_TABS_COUNT" desc="In Title Case: Title of unnamed saved tab group in Everything menu. [ICU_Syntax]"> @@ -11139,6 +11142,9 @@ <message name="IDS_CREATE_NEW_TAB_GROUP" desc="The label of item in Everything menu to create a new tab group."> Create New Tab Group </message> + <message name="IDS_SAVED_TAB_GROUPS_MENU" desc="The title of the 'Tab Groups' menu in the App Menu."> + Tab Groups + </message> </if> <!-- Tab Group Editor Bubble -->
diff --git a/chrome/app/generated_resources_grd/IDS_SAVED_TAB_GROUPS_MENU.png.sha1 b/chrome/app/generated_resources_grd/IDS_SAVED_TAB_GROUPS_MENU.png.sha1 new file mode 100644 index 0000000..38f388a --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_SAVED_TAB_GROUPS_MENU.png.sha1
@@ -0,0 +1 @@ +3f7a9988909bb052a233b23337920f020c9d916d \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 9584f36..73cba193 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -6302,6 +6302,9 @@ <message name="IDS_OS_SETTINGS_APP_PARENTAL_CONTROLS_SUBLABEL" desc="The sublabel that describes the feature where users can set up on-device parental controls to block or enable apps."> Manage access and block apps on this Chromebook. </message> + <message name="IDS_OS_SETTINGS_APP_PARENTAL_CONTROLS_SET_UP_BUTTON" desc="Text for the button that allows users to set up a PIN for on-device parental controls."> + Set up + </message> <!-- Apps > Manage your apps > Borealis --> <message name="IDS_SETTINGS_APPS_BOREALIS_MAIN_PERMISSION_TEXT" desc="Description in Steam (name of app, manages other apps) settings page.">
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_APP_PARENTAL_CONTROLS_SET_UP_BUTTON.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_APP_PARENTAL_CONTROLS_SET_UP_BUTTON.png.sha1 new file mode 100644 index 0000000..a6d9a5d9 --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_APP_PARENTAL_CONTROLS_SET_UP_BUTTON.png.sha1
@@ -0,0 +1 @@ +c3055e7ad3a46193c4e01445c09e822959b4e7ac
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 8aaf127f..d20fc2a 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -435,6 +435,7 @@ "+media/renderers", "+media/webrtc", # For webrtc media switches. "+mojo/core/embedder", + "+pdf/pdf_features.h", "+ppapi/c", # For various types. "+ppapi/host", "+ppapi/proxy", @@ -595,9 +596,6 @@ # For GetVirtualKeyboardController. "+ash/keyboard/ui/keyboard_ui_controller.h", ], - "chrome_back_forward_cache_browsertest.cc": [ - "+pdf/pdf_features.h", - ], "chrome_browsing_data_remover_delegate_unittest.cc": [ "+services/network/network_context.h", "+services/network/network_service.h", @@ -614,12 +612,8 @@ "chrome_navigation_browsertest.cc" : [ "+content/common/content_navigation_policy.h", ], - "chrome_web_platform_security_metrics_browsertest.cc" : [ - "+pdf/pdf_features.h", - ], "about_flags\.cc" : [ "+mojo/core/embedder/features.h", - "+pdf/pdf_features.h", "+sandbox/policy/features.h", ], "dbus_memory_pressure_evaluator_linux(_unittest)?\.(cc|h)" : [
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index b999ead1..fe0c8e2 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1302,28 +1302,6 @@ }; const FeatureEntry::FeatureParam - kJourneysLabelsWithSearchVisitEntitiesParams[] = { - {"labels_from_search_visit_entities", "true"}, -}; -const FeatureEntry::FeatureParam kJourneysLabelsWithEntitiesParams[] = { - {"labels_from_entities", "true"}, -}; -const FeatureEntry::FeatureParam - kJourneysLabelsWithEntitiesNoHostnamesParams[] = { - {"labels_from_hostnames", "false"}, - {"labels_from_entities", "true"}, -}; -const FeatureEntry::FeatureVariation kJourneysLabelsVariations[] = { - {"With Entities", kJourneysLabelsWithEntitiesParams, - std::size(kJourneysLabelsWithEntitiesParams), nullptr}, - {"With Entities, No Hostnames", - kJourneysLabelsWithEntitiesNoHostnamesParams, - std::size(kJourneysLabelsWithEntitiesNoHostnamesParams), nullptr}, - {"With Search Entities", kJourneysLabelsWithSearchVisitEntitiesParams, - std::size(kJourneysLabelsWithSearchVisitEntitiesParams), nullptr}, -}; - -const FeatureEntry::FeatureParam kOmniboxCompanyEntityIconAdjustmentLeastAggressive[] = { {"OmniboxCompanyEntityAdjustmentGroup", "least-aggressive"}}; const FeatureEntry::FeatureParam kOmniboxCompanyEntityIconAdjustmentModerate[] = @@ -6351,12 +6329,6 @@ kJourneysVariations, "HistoryJourneys")}, - {"history-journeys-labels", flag_descriptions::kJourneysLabelsName, - flag_descriptions::kJourneysLabelsDescription, kOsDesktop | kOsAndroid, - FEATURE_WITH_PARAMS_VALUE_TYPE(history_clusters::internal::kJourneysLabels, - kJourneysLabelsVariations, - "HistoryJourneysLabels")}, - {"history-journeys-show-all-clusters", flag_descriptions::kJourneysShowAllClustersName, flag_descriptions::kJourneysShowAllClustersDescription, @@ -10355,12 +10327,6 @@ #endif // BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(IS_ANDROID) - {"ml-mobile-pwa-prompt", flag_descriptions::kMobilePWAInstallPromptMlName, - flag_descriptions::kMobilePWAInstallPromptMlDescription, kOsAndroid, - FEATURE_VALUE_TYPE(webapps::features::kInstallPromptSegmentation)}, -#endif - -#if BUILDFLAG(IS_ANDROID) {"mouse-and-trackpad-dropdown-menu", flag_descriptions::kMouseAndTrackpadDropdownMenuName, flag_descriptions::kMouseAndTrackpadDropdownMenuDescription, kOsAndroid,
diff --git a/chrome/browser/accessibility/DEPS b/chrome/browser/accessibility/DEPS index 38df7f9..5697e212 100644 --- a/chrome/browser/accessibility/DEPS +++ b/chrome/browser/accessibility/DEPS
@@ -1,7 +1,6 @@ include_rules = [ "+components/live_caption", "+components/soda", - "+pdf/pdf_features.h", "+services/image_annotation", "+testing/gmock", "+testing/gtest",
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc index a93e810..28453d340 100644 --- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc +++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
@@ -546,6 +546,8 @@ title_indicator_layer->children()[0].get(), title_layer->layer()); } title_layer->SetUIResourceIds(); + } else { + title_indicator_layer->RemoveAllChildren(); } // Set bottom indicator properties.
diff --git a/chrome/browser/apps/guest_view/DEPS b/chrome/browser/apps/guest_view/DEPS deleted file mode 100644 index 4d41653..0000000 --- a/chrome/browser/apps/guest_view/DEPS +++ /dev/null
@@ -1,5 +0,0 @@ -specific_include_rules = { - "web_view_browsertest\.cc": [ - "+pdf/pdf_features.h", - ], -} \ No newline at end of file
diff --git a/chrome/browser/apps/link_capturing/link_capturing_navigation_throttle_browsertest.cc b/chrome/browser/apps/link_capturing/link_capturing_navigation_throttle_browsertest.cc index 865004e..4a3d326 100644 --- a/chrome/browser/apps/link_capturing/link_capturing_navigation_throttle_browsertest.cc +++ b/chrome/browser/apps/link_capturing/link_capturing_navigation_throttle_browsertest.cc
@@ -4,8 +4,6 @@ #include "chrome/browser/apps/link_capturing/link_capturing_navigation_throttle.h" -#include "base/strings/stringprintf.h" - #include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -16,6 +14,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_test_observers.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" @@ -92,7 +91,7 @@ webapps::AppId app_id_; base::test::ScopedFeatureList feature_list_{ features::kDesktopPWAsLinkCapturing}; - web_app::OsIntegrationManager::ScopedSuppressForTesting os_hooks_suppress_; + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; }; IN_PROC_BROWSER_TEST_F(LinkCapturingNavigationThrottleBrowserTest,
diff --git a/chrome/browser/ash/browser_context_keyed_service_factories.cc b/chrome/browser/ash/browser_context_keyed_service_factories.cc index 1576fa66..07f2ca2 100644 --- a/chrome/browser/ash/browser_context_keyed_service_factories.cc +++ b/chrome/browser/ash/browser_context_keyed_service_factories.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/ash/child_accounts/child_user_service_factory.h" #include "chrome/browser/ash/child_accounts/event_based_status_reporting_service_factory.h" #include "chrome/browser/ash/child_accounts/family_user_metrics_service_factory.h" +#include "chrome/browser/ash/child_accounts/on_device_controls/app_controls_service_factory.h" #include "chrome/browser/ash/child_accounts/screen_time_controller_factory.h" #include "chrome/browser/ash/concierge_helper_service.h" #include "chrome/browser/ash/crosapi/keystore_service_factory_ash.h" @@ -217,6 +218,7 @@ nearby::NearbyProcessManagerFactory::GetInstance(); nearby::presence::NearbyPresenceServiceFactory::GetInstance(); OAuth2LoginManagerFactory::GetInstance(); + on_device_controls::AppControlsServiceFactory::GetInstance(); OfflineSigninLimiterFactory::GetInstance(); OwnerSettingsServiceAshFactory::GetInstance(); PasswordSyncTokenVerifierFactory::GetInstance();
diff --git a/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service.cc b/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service.cc index 0aff72b..adab27f 100644 --- a/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service.cc +++ b/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service.cc
@@ -4,9 +4,18 @@ #include "chrome/browser/ash/child_accounts/on_device_controls/app_controls_service.h" +#include "ash/constants/ash_pref_names.h" +#include "components/prefs/pref_registry_simple.h" + namespace ash { namespace on_device_controls { +// static +void AppControlsService::RegisterProfilePrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kOnDeviceAppControlsSetupCompleted, + false); +} + AppControlsService::AppControlsService() = default; AppControlsService::~AppControlsService() = default;
diff --git a/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service.h b/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service.h index c0741196..641509ea 100644 --- a/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service.h +++ b/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service.h
@@ -7,6 +7,8 @@ #include "components/keyed_service/core/keyed_service.h" +class PrefRegistrySimple; + namespace ash { namespace on_device_controls { @@ -14,6 +16,8 @@ // blocking apps. class AppControlsService : public KeyedService { public: + static void RegisterProfilePrefs(PrefRegistrySimple* registry); + AppControlsService(); ~AppControlsService() override; AppControlsService(const AppControlsService&) = delete;
diff --git a/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service_factory.cc b/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service_factory.cc index fc8fe69..bc70baa 100644 --- a/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service_factory.cc +++ b/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service_factory.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/ash/child_accounts/on_device_controls/on_device_utils.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" +#include "components/pref_registry/pref_registry_syncable.h" namespace { constexpr char kServiceName[] = "AppsControlsService"; @@ -64,5 +65,10 @@ return std::make_unique<AppControlsService>(); } +void AppControlsServiceFactory::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) { + AppControlsService::RegisterProfilePrefs(registry); +} + } // namespace on_device_controls } // namespace ash
diff --git a/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service_factory.h b/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service_factory.h index 933b2d9..7ed9873 100644 --- a/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service_factory.h +++ b/chrome/browser/ash/child_accounts/on_device_controls/app_controls_service_factory.h
@@ -16,6 +16,10 @@ class BrowserContext; } // namespace content +namespace user_prefs { +class PrefRegistrySyncable; +} // namespace user_prefs + namespace ash { namespace on_device_controls { @@ -47,6 +51,8 @@ // BrowserContextKeyedServiceFactory: std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; + void RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) override; }; } // namespace on_device_controls
diff --git a/chrome/browser/ash/crosapi/test_controller_ash.cc b/chrome/browser/ash/crosapi/test_controller_ash.cc index 379b8a0f..918a5191 100644 --- a/chrome/browser/ash/crosapi/test_controller_ash.cc +++ b/chrome/browser/ash/crosapi/test_controller_ash.cc
@@ -150,6 +150,21 @@ waiter.Wait(); } +std::string GetMachineStatisticKeyString(mojom::MachineStatisticKeyType key) { + if (key == mojom::MachineStatisticKeyType::kOemDeviceRequisitionKey) { + return ash::system::kOemDeviceRequisitionKey; + } + if (key == mojom::MachineStatisticKeyType::kHardwareClassKey) { + return ash::system::kHardwareClassKey; + } + if (key == mojom::MachineStatisticKeyType::kCustomizationIdKey) { + return ash::system::kCustomizationIdKey; + } + + // Return empty string for unknown key. + return ""; +} + const base::TimeDelta kWindowWaitTimeout = base::Seconds(10); TestControllerAsh* g_instance = nullptr; @@ -1043,6 +1058,34 @@ std::move(callback).Run(); } +void TestControllerAsh::EnableStatisticsProviderForTesting( + bool enable, + EnableStatisticsProviderForTestingCallback callback) { + ash::system::StatisticsProvider::SetTestProvider( + enable ? &fake_statistics_provider_ : nullptr); + std::move(callback).Run(); +} + +void TestControllerAsh::ClearAllMachineStatistics( + ClearAllMachineStatisticsCallback callback) { + fake_statistics_provider_.ClearAllMachineStatistics(); + std::move(callback).Run(); +} + +void TestControllerAsh::SetMachineStatistic( + mojom::MachineStatisticKeyType key, + const std::string& value, + SetMachineStatisticCallback callback) { + std::string key_string = GetMachineStatisticKeyString(key); + if (!key_string.empty()) { + fake_statistics_provider_.SetMachineStatistic(key_string, value); + std::move(callback).Run(true); + } else { + LOG(WARNING) << "Unknown key for setting machine statistic"; + std::move(callback).Run(false); + } +} + // This class waits for overview mode to either enter or exit and fires a // callback. This class will fire the callback at most once. class TestControllerAsh::OverviewWaiter : public ash::OverviewObserver {
diff --git a/chrome/browser/ash/crosapi/test_controller_ash.h b/chrome/browser/ash/crosapi/test_controller_ash.h index 6bc7f497..73434cc 100644 --- a/chrome/browser/ash/crosapi/test_controller_ash.h +++ b/chrome/browser/ash/crosapi/test_controller_ash.h
@@ -14,6 +14,7 @@ #include "ash/wm/splitview/split_view_types.h" #include "base/one_shot_event.h" #include "chrome/browser/ash/crosapi/crosapi_ash.h" +#include "chromeos/ash/components/system/fake_statistics_provider.h" #include "chromeos/crosapi/mojom/test_controller.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" @@ -170,6 +171,17 @@ void UpdateDisplay(int number_of_displays, UpdateDisplayCallback callback) override; + void EnableStatisticsProviderForTesting( + bool enable, + EnableStatisticsProviderForTestingCallback callback) override; + + void ClearAllMachineStatistics( + ClearAllMachineStatisticsCallback callback) override; + + void SetMachineStatistic(mojom::MachineStatisticKeyType key, + const std::string& value, + SetMachineStatisticCallback callback) override; + mojom::StandaloneBrowserTestController* GetStandaloneBrowserTestController() { DCHECK(standalone_browser_test_controller_.is_bound()); return standalone_browser_test_controller_.get(); @@ -227,6 +239,8 @@ // Ash utterance event delegates by utterance id. std::map<int, std::unique_ptr<AshUtteranceEventDelegate>> ash_utterance_event_delegates_; + + ash::system::FakeStatisticsProvider fake_statistics_provider_; }; class TestShillControllerAsh : public crosapi::mojom::TestShillController {
diff --git a/chrome/browser/ash/file_manager/DEPS b/chrome/browser/ash/file_manager/DEPS index 013175cb..4534fa6 100644 --- a/chrome/browser/ash/file_manager/DEPS +++ b/chrome/browser/ash/file_manager/DEPS
@@ -101,6 +101,5 @@ specific_include_rules = { "file_manager_browsertest_base.cc": [ "+chrome/browser/ui/views/select_file_dialog_extension.h", - "+pdf/pdf_features.h", ], }
diff --git a/chrome/browser/ash/growth/DEPS b/chrome/browser/ash/growth/DEPS index 7f5608c5..4ab9f7b 100644 --- a/chrome/browser/ash/growth/DEPS +++ b/chrome/browser/ash/growth/DEPS
@@ -42,4 +42,10 @@ # Dependencies outside of //chrome: "+ui/message_center/message_center.h", -] \ No newline at end of file +] + +specific_include_rules = { + "campaigns_manager_interactive_uitest\.cc": [ + "+chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h", + ], +}
diff --git a/chrome/browser/ash/growth/campaigns_manager_interactive_uitest.cc b/chrome/browser/ash/growth/campaigns_manager_interactive_uitest.cc index 668e470..d561a29 100644 --- a/chrome/browser/ash/growth/campaigns_manager_interactive_uitest.cc +++ b/chrome/browser/ash/growth/campaigns_manager_interactive_uitest.cc
@@ -4,6 +4,8 @@ #include "ash/constants/ash_features.h" #include "ash/constants/ash_switches.h" +#include "ash/system/toast/system_nudge_view.h" +#include "ash/webui/system_apps/public/system_web_app_type.h" #include "base/callback_list.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -11,12 +13,15 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/feature_engagement/tracker_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h" #include "chrome/test/base/chromeos/crosier/interactive_ash_test.h" #include "chromeos/ash/components/growth/campaigns_constants.h" #include "chromeos/ash/components/growth/campaigns_manager.h" #include "components/feature_engagement/public/feature_constants.h" #include "components/feature_engagement/test/mock_tracker.h" #include "testing/gmock/include/gmock/gmock.h" +#include "ui/aura/env.h" +#include "ui/base/interaction/interactive_test.h" namespace { @@ -27,12 +32,62 @@ } )"; +// Targeting Personalization App. +constexpr char kCampaignsNudge[] = R"( +{ + "2": [ + { + "id": 100, + "targetings": [ + { + "runtime": { + "appsOpened": [ + {"appId": "glenkcidjgckcomnliblmkokolehpckn"} + ] + } + } + ], + "payload": { + "nudge": { + "title": "Title", + "body": "Body", + "duration": 2, + "image": { + "builtInIcon": 0 + }, + "arrow": 1, + "anchor": { + "activeAppWindowAnchorType": 0 + }, + "primaryButton": { + "label": "Yes", + "action": { + "type": 3, + "params": { + "url": "https://www.google.com", + "disposition": 0 + } + } + }, + "secondaryButton": { + "label": "No", + "action": {} + } + } + } + } + ] +} +)"; + base::FilePath GetCampaignsFilePath(const base::ScopedTempDir& dir) { return dir.GetPath().Append(kCampaignsFileName); } } // namespace +// CampaignsManagerInteractiveUiTest ------------------------------------------- + class CampaignsManagerInteractiveUiTest : public InteractiveAshTest { public: CampaignsManagerInteractiveUiTest() { @@ -88,9 +143,10 @@ GetActiveUserProfile())); } + base::ScopedTempDir temp_dir_; + private: base::test::ScopedFeatureList scoped_feature_list_; - base::ScopedTempDir temp_dir_; base::CallbackListSubscription create_services_subscription_; base::WeakPtrFactory<CampaignsManagerInteractiveUiTest> weak_ptr_factory_{ this}; @@ -132,3 +188,76 @@ growth::CampaignsManager::Get()->ClearEvent(growth::CampaignEvent::kAppOpened, "abcd"); } + +// CampaignsManagerInteractiveUiNudgeTest ---------------------------------- + +class CampaignsManagerInteractiveUiNudgeTest + : public CampaignsManagerInteractiveUiTest { + public: + CampaignsManagerInteractiveUiNudgeTest() { + base::WriteFile(GetCampaignsFilePath(temp_dir_), kCampaignsNudge); + } + + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + InteractiveAshTest::SetupContextWidget(); + + // Use SWA as targets and anchors in the tests. + InstallSystemApps(); + } + + protected: + auto LaunchSystemWebApp(ash::SystemWebAppType type) { + return Do( + [=]() { ash::LaunchSystemWebAppAsync(GetActiveUserProfile(), type); }); + } +}; + +IN_PROC_BROWSER_TEST_F(CampaignsManagerInteractiveUiNudgeTest, + AnchorPersonalizationApp) { + aura::Env* env = aura::Env::GetInstance(); + ASSERT_TRUE(env); + + RunTestSequence(InAnyContext(Steps(LaunchSystemWebApp( + ash::SystemWebAppType::PERSONALIZATION))), + WaitForWindowWithTitle(env, u"Wallpaper & style"), + WaitForShow(ash::SystemNudgeView::kBubbleIdForTesting)); +} + +IN_PROC_BROWSER_TEST_F(CampaignsManagerInteractiveUiNudgeTest, + NotShowOnSettingsApp) { + aura::Env* env = aura::Env::GetInstance(); + ASSERT_TRUE(env); + + RunTestSequence( + InAnyContext(Steps(LaunchSystemWebApp(ash::SystemWebAppType::SETTINGS))), + WaitForWindowWithTitle(env, u"Settings"), + EnsureNotPresent(ash::SystemNudgeView::kBubbleIdForTesting)); +} + +IN_PROC_BROWSER_TEST_F(CampaignsManagerInteractiveUiNudgeTest, + ClickPrimaryButtonInAnchoredNudge) { + aura::Env* env = aura::Env::GetInstance(); + ASSERT_TRUE(env); + + RunTestSequence( + InAnyContext( + Steps(LaunchSystemWebApp(ash::SystemWebAppType::PERSONALIZATION))), + WaitForShow(ash::SystemNudgeView::kBubbleIdForTesting), FlushEvents(), + PressButton(ash::SystemNudgeView::kPrimaryButtonIdForTesting), + WaitForHide(ash::SystemNudgeView::kBubbleIdForTesting), + WaitForWindowWithTitle(env, u"www.google.com")); +} + +IN_PROC_BROWSER_TEST_F(CampaignsManagerInteractiveUiNudgeTest, + ClickSecondaryButtonInAnchoredNudge) { + aura::Env* env = aura::Env::GetInstance(); + ASSERT_TRUE(env); + + RunTestSequence( + InAnyContext( + Steps(LaunchSystemWebApp(ash::SystemWebAppType::PERSONALIZATION))), + WaitForShow(ash::SystemNudgeView::kBubbleIdForTesting), FlushEvents(), + PressButton(ash::SystemNudgeView::kSecondaryButtonIdForTesting), + WaitForHide(ash::SystemNudgeView::kBubbleIdForTesting)); +}
diff --git a/chrome/browser/ash/login/wizard_controller_browsertest.cc b/chrome/browser/ash/login/wizard_controller_browsertest.cc index c0b450e..536c552 100644 --- a/chrome/browser/ash/login/wizard_controller_browsertest.cc +++ b/chrome/browser/ash/login/wizard_controller_browsertest.cc
@@ -1244,7 +1244,29 @@ ->clear_forced_re_enrollment_vpd_call_count()); } -IN_PROC_BROWSER_TEST_F(WizardControllerDeviceStateTest, +class WizardControllerDeviceLegacyTest + : public WizardControllerDeviceStateTest { + public: + WizardControllerDeviceLegacyTest( + const WizardControllerDeviceLegacyTest&) = delete; + WizardControllerDeviceLegacyTest& operator=( + const WizardControllerDeviceLegacyTest&) = delete; + + protected: + WizardControllerDeviceLegacyTest() = default; + ~WizardControllerDeviceLegacyTest() override = default; + + void SetUpCommandLine(base::CommandLine* command_line) override { + WizardControllerDeviceStateTest::SetUpCommandLine(command_line); + + // Explicitly test legacy state determination flow. + command_line->AppendSwitchASCII( + switches::kEnterpriseEnableUnifiedStateDetermination, + policy::AutoEnrollmentTypeChecker::kUnifiedStateDeterminationNever); + } +}; + +IN_PROC_BROWSER_TEST_F(WizardControllerDeviceLegacyTest, ServerAdvertisedReEnrollment) { base::Value::Dict device_state; device_state.Set( @@ -1277,7 +1299,7 @@ #else #define MAYBE_ControlFlowDeviceDisabled ControlFlowDeviceDisabled #endif -IN_PROC_BROWSER_TEST_F(WizardControllerDeviceStateTest, +IN_PROC_BROWSER_TEST_F(WizardControllerDeviceLegacyTest, MAYBE_ControlFlowDeviceDisabled) { CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_CALL(*mock_welcome_screen_, HideImpl()).Times(1); @@ -1710,6 +1732,82 @@ CheckCurrentScreen(DeviceDisabledScreenView::kScreenId); } +// Tests that when EnrollmentStateFetcher reports kDisabled and configures +// corresponding device state mode, we show device disabled screen after +// attempting to enter demo mode. +IN_PROC_BROWSER_TEST_F(WizardControllerUnifiedEnrollmentTest, + DisabledDemoMode) { + ScopedEnrollmentStateFetcherFactory fetcher_factory( + auto_enrollment_controller()); + + CheckCurrentScreen(WelcomeView::kScreenId); + EXPECT_FALSE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); + + EXPECT_CALL(*mock_welcome_screen_, HideImpl()); + EXPECT_CALL(*mock_network_screen_, ShowImpl()); + + WizardController::default_controller()->StartDemoModeSetup(); + + CheckCurrentScreen(NetworkScreenView::kScreenId); + EXPECT_TRUE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); + + EXPECT_CALL(*mock_network_screen_, HideImpl()); + EXPECT_CALL(*mock_demo_preferences_screen_, ShowImpl()); + + mock_network_screen_->ExitScreen(NetworkScreen::Result::CONNECTED); + + CheckCurrentScreen(DemoPreferencesScreenView::kScreenId); + EXPECT_TRUE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); + + EXPECT_CALL(*mock_demo_preferences_screen_, HideImpl()); + EXPECT_CALL(*mock_update_screen_, ShowImpl()); + + mock_demo_preferences_screen_->ExitScreen( + DemoPreferencesScreen::Result::COMPLETED); + + // Let update screen smooth time process (time = 0ms). + base::RunLoop().RunUntilIdle(); + + CheckCurrentScreen(UpdateView::kScreenId); + EXPECT_CALL(*mock_update_screen_, HideImpl()); + EXPECT_CALL(*mock_consolidated_consent_screen_, ShowImpl()); + + mock_update_screen_->RunExit(UpdateScreen::Result::UPDATE_NOT_REQUIRED); + + CheckCurrentScreen(ConsolidatedConsentScreenView::kScreenId); + EXPECT_TRUE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); + + EXPECT_CALL(*mock_consolidated_consent_screen_, HideImpl()); + EXPECT_CALL(*mock_auto_enrollment_check_screen_, ShowImpl()); + + mock_consolidated_consent_screen_->ExitScreen( + ConsolidatedConsentScreen::Result::ACCEPTED_DEMO_ONLINE); + + CheckCurrentScreen(AutoEnrollmentCheckScreenView::kScreenId); + EXPECT_TRUE(DemoSetupController::IsOobeDemoSetupFlowInProgress()); + + mock_auto_enrollment_check_screen_->RealShow(); + + fetcher_factory.WaitUntilEnrollmentStateFetcherCreated(); + + base::Value::Dict device_state; + device_state.Set(policy::kDeviceStateMode, + base::Value(policy::kDeviceStateModeDisabled)); + device_state.Set(policy::kDeviceStateDisabledMessage, + base::Value(kDisabledMessage)); + g_browser_process->local_state()->SetDict(prefs::kServerBackedDeviceState, + std::move(device_state)); + + EXPECT_CALL(*mock_auto_enrollment_check_screen_, HideImpl()); + EXPECT_CALL(*device_disabled_screen_view_, + Show(_, _, kDisabledMessage, false)); + + fetcher_factory.ReportEnrollmentState( + policy::AutoEnrollmentResult::kDisabled); + + CheckCurrentScreen(DeviceDisabledScreenView::kScreenId); +} + // Tests that when EnrollmentStateFetcher times out, we set state correctly, // show an error on enrollment check screen and that it is not possible to enter // guest mode (like in FRE). @@ -1779,6 +1877,11 @@ command_line->AppendSwitchASCII( switches::kEnterpriseEnableInitialEnrollment, policy::AutoEnrollmentTypeChecker::kInitialEnrollmentAlways); + + // Explicitly test legacy state determination flow. + command_line->AppendSwitchASCII( + switches::kEnterpriseEnableUnifiedStateDetermination, + policy::AutoEnrollmentTypeChecker::kUnifiedStateDeterminationNever); } // Test initial enrollment. This method is shared by the tests for initial @@ -2750,6 +2853,15 @@ WizardControllerDemoSetupDeviceDisabledTest() = default; ~WizardControllerDemoSetupDeviceDisabledTest() override = default; + void SetUpCommandLine(base::CommandLine* command_line) override { + WizardControllerDeviceStateTest::SetUpCommandLine(command_line); + + // Explicitly test legacy state determination flow. + command_line->AppendSwitchASCII( + switches::kEnterpriseEnableUnifiedStateDetermination, + policy::AutoEnrollmentTypeChecker::kUnifiedStateDeterminationNever); + } + // MixinBasedInProcessBrowserTest: void SetUpOnMainThread() override { WizardControllerDeviceStateTest::SetUpOnMainThread();
diff --git a/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker_unittest.cc b/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker_unittest.cc index d54a5fe..69ac9ba 100644 --- a/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker_unittest.cc +++ b/chrome/browser/ash/policy/enrollment/auto_enrollment_type_checker_unittest.cc
@@ -730,7 +730,7 @@ AutoEnrollmentTypeChecker::kUnifiedStateDeterminationOfficialBuild); EXPECT_EQ(AutoEnrollmentTypeChecker::IsUnifiedStateDeterminationEnabled(), - !kill_switch_enabled_ && google_branded_); + !kill_switch_enabled_ && IsOfficialGoogleOS()); } TEST_P(AutoEnrollmentTypeCheckerUnifiedStateDeterminationTestP, Never) {
diff --git a/chrome/browser/ash/system_web_apps/test_support/system_web_app_browsertest_base.h b/chrome/browser/ash/system_web_apps/test_support/system_web_app_browsertest_base.h index cb67596..ffaadf7 100644 --- a/chrome/browser/ash/system_web_apps/test_support/system_web_app_browsertest_base.h +++ b/chrome/browser/ash/system_web_apps/test_support/system_web_app_browsertest_base.h
@@ -109,8 +109,6 @@ bool wait_for_load, Browser** out_browser); - web_app::OsIntegrationManager::ScopedSuppressForTesting os_hooks_suppress_; - std::unique_ptr<TestSystemWebAppInstallation> installation_ = nullptr; };
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java index 79848ac6..fc23585 100644 --- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java +++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java
@@ -1161,6 +1161,16 @@ ResettersForTesting.register(() -> this.mImageFetcher = oldValue); } + /** Sets the preference value for supporting payments using Pix. */ + public void setFacilitatedPaymentsPixPref(boolean value) { + mPrefService.setBoolean(Pref.FACILITATED_PAYMENTS_PIX, value); + } + + /** Returns the preference value for supporting payments using Pix. */ + public boolean getFacilitatedPaymentsPixPref() { + return mPrefService.getBoolean(Pref.FACILITATED_PAYMENTS_PIX); + } + @NativeMethods interface Natives { long init(PersonalDataManager caller, @JniType("Profile*") Profile profile);
diff --git a/chrome/browser/banners/android/ambient_badge_manager_browsertest.cc b/chrome/browser/banners/android/ambient_badge_manager_browsertest.cc index d062209..9aefb85 100644 --- a/chrome/browser/banners/android/ambient_badge_manager_browsertest.cc +++ b/chrome/browser/banners/android/ambient_badge_manager_browsertest.cc
@@ -163,152 +163,15 @@ ~AmbientBadgeManagerBrowserTest() override = default; - void SetUp() override { - SetUpFeatureList(); - AndroidBrowserTest::SetUp(); - } - void SetUpOnMainThread() override { ASSERT_TRUE(embedded_test_server()->Start()); site_engagement::SiteEngagementScore::SetParamValuesForTesting(); + app_banner_manager_ = std::make_unique<TestAppBannerManager>( + web_contents(), &mock_segmentation_service_); AndroidBrowserTest::SetUpOnMainThread(); } - protected: - content::WebContents* web_contents() { - return chrome_test_utils::GetActiveWebContents(this); - } - - virtual void SetUpFeatureList() { - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{}, - /*disabled_features=*/{features::kAmbientBadgeSuppressFirstVisit, - features::kInstallPromptSegmentation}); - } - - void ResetEngagementForUrl(const GURL& url, double score) { - site_engagement::SiteEngagementService* service = - site_engagement::SiteEngagementService::Get( - Profile::FromBrowserContext(web_contents()->GetBrowserContext())); - service->ResetBaseScoreForURL(url, score); - } - - void RunTest(TestAppBannerManager* app_banner_manager, - const GURL& url, - AmbientBadgeManager::State expected_state) { - ResetEngagementForUrl(url, 10); - - base::RunLoop waiter; - - app_banner_manager->WaitForAmbientBadgeState(expected_state, - waiter.QuitClosure()); - ASSERT_TRUE(content::NavigateToURL(web_contents(), url)); - - waiter.Run(); - } - - base::test::ScopedFeatureList scoped_feature_list_; - - private: - // Disable the banners in the browser so it won't interfere with the test. - base::AutoReset<bool> disable_banner_trigger_; -}; - -IN_PROC_BROWSER_TEST_F(AmbientBadgeManagerBrowserTest, ShowAmbientBadge) { - auto app_banner_manager = - std::make_unique<TestAppBannerManager>(web_contents()); - - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL("/banners/manifest_test_page.html"), - AmbientBadgeManager::State::kShowing); -} - -IN_PROC_BROWSER_TEST_F(AmbientBadgeManagerBrowserTest, NoServiceWorker) { - auto app_banner_manager = - std::make_unique<TestAppBannerManager>(web_contents()); - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL( - "/banners/manifest_no_service_worker.html"), - AmbientBadgeManager::State::kPendingWorker); -} - -IN_PROC_BROWSER_TEST_F(AmbientBadgeManagerBrowserTest, - BlockedIfDismissRecently) { - auto app_banner_manager = - std::make_unique<TestAppBannerManager>(web_contents()); - - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL("/banners/manifest_test_page.html"), - AmbientBadgeManager::State::kShowing); - - // Explicitly dismiss the badge. - app_banner_manager->GetBadgeManagerForTest()->BadgeDismissed(); // IN-TEST - EXPECT_EQ(AmbientBadgeManager::State::kDismissed, - app_banner_manager->GetBadgeManagerForTest()->state()); // IN-TEST - - // Badge blocked because it was recently dismissed. - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL("/banners/manifest_test_page.html"), - AmbientBadgeManager::State::kBlocked); - - // Badge can show again after 91 days. - webapps::AppBannerManager::SetTimeDeltaForTesting(91); - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL("/banners/manifest_test_page.html"), - AmbientBadgeManager::State::kShowing); -} - -class AmbientBadgeManagerSecondVisitTest - : public AmbientBadgeManagerBrowserTest { - public: - AmbientBadgeManagerSecondVisitTest() = default; - - AmbientBadgeManagerSecondVisitTest( - const AmbientBadgeManagerSecondVisitTest&) = delete; - AmbientBadgeManagerSecondVisitTest& operator=( - const AmbientBadgeManagerSecondVisitTest&) = delete; - - ~AmbientBadgeManagerSecondVisitTest() override = default; - - void SetUpFeatureList() override { - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{features::kAmbientBadgeSuppressFirstVisit}, - /*disabled_features=*/{features::kInstallPromptSegmentation}); - } -}; - -IN_PROC_BROWSER_TEST_F(AmbientBadgeManagerSecondVisitTest, - SuppressedOnFirstVisit) { - auto app_banner_manager = - std::make_unique<TestAppBannerManager>(web_contents()); - - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL("/banners/manifest_test_page.html"), - AmbientBadgeManager::State::kPendingEngagement); - - // Load again, can show. - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL("/banners/manifest_test_page.html"), - AmbientBadgeManager::State::kShowing); -} - -class AmbientBadgeManagerSmartTest : public AmbientBadgeManagerBrowserTest { - public: - AmbientBadgeManagerSmartTest() = default; - - AmbientBadgeManagerSmartTest(const AmbientBadgeManagerSmartTest&) = delete; - AmbientBadgeManagerSmartTest& operator=(const AmbientBadgeManagerSmartTest&) = - delete; - - ~AmbientBadgeManagerSmartTest() override = default; - - void SetUpFeatureList() override { - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{features::kInstallPromptSegmentation}, - /*disabled_features=*/{features::kAmbientBadgeSuppressFirstVisit}); - } - segmentation_platform::ClassificationResult GetClassificationResult( std::string label) { segmentation_platform::ClassificationResult result( @@ -317,65 +180,90 @@ return result; } + protected: + content::WebContents* web_contents() { + return chrome_test_utils::GetActiveWebContents(this); + } + + AmbientBadgeManager* GetAmbientBadgeManager() { + return app_banner_manager_->GetBadgeManagerForTest(); + } + + void ResetEngagementForUrl(const GURL& url, double score) { + site_engagement::SiteEngagementService* service = + site_engagement::SiteEngagementService::Get( + Profile::FromBrowserContext(web_contents()->GetBrowserContext())); + service->ResetBaseScoreForURL(url, score); + } + + void SetSegmentationResult(std::string label) { + EXPECT_CALL(mock_segmentation_service_, GetClassificationResult(_, _, _, _)) + .WillOnce(RunOnceCallback<3>(GetClassificationResult(label))); + } + + void RunTest(const GURL& url, AmbientBadgeManager::State expected_state) { + ResetEngagementForUrl(url, 10); + + base::RunLoop waiter; + + app_banner_manager_->WaitForAmbientBadgeState(expected_state, + waiter.QuitClosure()); + ASSERT_TRUE(content::NavigateToURL(web_contents(), url)); + + waiter.Run(); + } + + private: + // Disable the banners in the browser so it won't interfere with the test. + base::AutoReset<bool> disable_banner_trigger_; + + std::unique_ptr<TestAppBannerManager> app_banner_manager_; segmentation_platform::MockSegmentationPlatformService mock_segmentation_service_; }; -IN_PROC_BROWSER_TEST_F(AmbientBadgeManagerSmartTest, ShowInstallMessages) { - EXPECT_CALL(mock_segmentation_service_, GetClassificationResult(_, _, _, _)) - .WillOnce(RunOnceCallback<3>(GetClassificationResult( - MLInstallabilityPromoter::kShowInstallPromptLabel))); +IN_PROC_BROWSER_TEST_F(AmbientBadgeManagerBrowserTest, ShowAmbientBadge) { + SetSegmentationResult(MLInstallabilityPromoter::kShowInstallPromptLabel); - auto app_banner_manager = std::make_unique<TestAppBannerManager>( - web_contents(), &mock_segmentation_service_); - - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL("/banners/manifest_test_page.html"), + RunTest(embedded_test_server()->GetURL("/banners/manifest_test_page.html"), AmbientBadgeManager::State::kShowing); } -IN_PROC_BROWSER_TEST_F(AmbientBadgeManagerSmartTest, +IN_PROC_BROWSER_TEST_F(AmbientBadgeManagerBrowserTest, BlockedBySegmentationResult) { - EXPECT_CALL(mock_segmentation_service_, GetClassificationResult(_, _, _, _)) - .WillOnce(RunOnceCallback<3>(GetClassificationResult("DontShow"))); + SetSegmentationResult(MLInstallabilityPromoter::kDontShowLabel); - auto app_banner_manager = std::make_unique<TestAppBannerManager>( - web_contents(), &mock_segmentation_service_); - - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL("/banners/manifest_test_page.html"), - AmbientBadgeManager::State::kSegmentation); + RunTest(embedded_test_server()->GetURL("/banners/manifest_test_page.html"), + AmbientBadgeManager::State::kSegmentationBlock); } -IN_PROC_BROWSER_TEST_F(AmbientBadgeManagerSmartTest, BlockedByGuardrail) { - EXPECT_CALL(mock_segmentation_service_, GetClassificationResult(_, _, _, _)) - .Times(testing::Exactly(2)) - .WillRepeatedly( - base::test::RunOnceCallbackRepeatedly<3>(GetClassificationResult( - MLInstallabilityPromoter::kShowInstallPromptLabel))); +IN_PROC_BROWSER_TEST_F(AmbientBadgeManagerBrowserTest, NoServiceWorker) { + SetSegmentationResult(MLInstallabilityPromoter::kShowInstallPromptLabel); - auto app_banner_manager = std::make_unique<TestAppBannerManager>( - web_contents(), &mock_segmentation_service_); + RunTest(embedded_test_server()->GetURL( + "/banners/manifest_no_service_worker.html"), + AmbientBadgeManager::State::kShowing); +} - // Showing OK for the first visit - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL("/banners/manifest_test_page.html"), +IN_PROC_BROWSER_TEST_F(AmbientBadgeManagerBrowserTest, + BlockedIfDismissRecently) { + SetSegmentationResult(MLInstallabilityPromoter::kShowInstallPromptLabel); + RunTest(embedded_test_server()->GetURL("/banners/manifest_test_page.html"), AmbientBadgeManager::State::kShowing); // Explicitly dismiss the badge. - app_banner_manager->GetBadgeManagerForTest()->BadgeDismissed(); // IN-TEST + GetAmbientBadgeManager()->BadgeDismissed(); // IN-TEST EXPECT_EQ(AmbientBadgeManager::State::kDismissed, - app_banner_manager->GetBadgeManagerForTest()->state()); // IN-TEST + GetAmbientBadgeManager()->state()); // IN-TEST // Badge blocked because it was recently dismissed. - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL("/banners/manifest_test_page.html"), + RunTest(embedded_test_server()->GetURL("/banners/manifest_test_page.html"), AmbientBadgeManager::State::kBlocked); // Badge can show again after 91 days. + SetSegmentationResult(MLInstallabilityPromoter::kShowInstallPromptLabel); webapps::AppBannerManager::SetTimeDeltaForTesting(91); - RunTest(app_banner_manager.get(), - embedded_test_server()->GetURL("/banners/manifest_test_page.html"), + RunTest(embedded_test_server()->GetURL("/banners/manifest_test_page.html"), AmbientBadgeManager::State::kShowing); }
diff --git a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AmbientBadgeManagerTest.java b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AmbientBadgeManagerTest.java index 46fdaf74..9fa43c28 100644 --- a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AmbientBadgeManagerTest.java +++ b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AmbientBadgeManagerTest.java
@@ -43,15 +43,12 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.base.test.util.Features.DisableFeatures; -import org.chromium.base.test.util.Features.EnableFeatures; import org.chromium.base.test.util.HistogramWatcher; import org.chromium.base.test.util.PackageManagerWrapper; import org.chromium.chrome.browser.ShortcutHelper; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.ProfileManager; import org.chromium.chrome.browser.tab.Tab; @@ -86,7 +83,6 @@ /** Tests the app banners. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@DisableFeatures({ChromeFeatureList.WEB_APP_AMBIENT_BADGE_SUPRESS_FIRST_VISIT}) public class AmbientBadgeManagerTest { @Rule public ChromeTabbedActivityTestRule mTabbedActivityTestRule = @@ -199,6 +195,7 @@ AppBannerManager.ignoreChromeChannelForTesting(); AppBannerManager.setTotalEngagementForTesting(10); + AppBannerManager.setOverrideSegmentationResultForTesting(true); mTestServer = EmbeddedTestServer.createAndStartServer( ApplicationProvider.getApplicationContext()); @@ -399,7 +396,8 @@ triggerInstallWebApp( mTabbedActivityTestRule, - WebappTestPage.getServiceWorkerUrlWithAction(mTestServer, "verify_appinstalled")); + WebappTestPage.getNonServiceWorkerUrlWithAction( + mTestServer, "verify_appinstalled")); // The appinstalled event should fire (and cause the title to change). new TabTitleObserver( @@ -427,7 +425,8 @@ ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL)); triggerInstallWebApp( mCustomTabActivityTestRule, - WebappTestPage.getServiceWorkerUrlWithAction(mTestServer, "verify_appinstalled")); + WebappTestPage.getNonServiceWorkerUrlWithAction( + mTestServer, "verify_appinstalled")); // The appinstalled event should fire (and cause the title to change). new TabTitleObserver( @@ -481,7 +480,7 @@ HistogramWatcher.newBuilder().expectNoRecords(INSTALL_PATH_HISTOGRAM_NAME).build(); // Visit a site that is a PWA. The ambient badge should show. - String webBannerUrl = WebappTestPage.getServiceWorkerUrl(mTestServer); + String webBannerUrl = WebappTestPage.getNonServiceWorkerUrl(mTestServer); resetEngagementForUrl(webBannerUrl, 10); Tab tab = mTabbedActivityTestRule.getActivity().getActivityTab(); new TabLoadObserver(tab).fullyLoadUrl(webBannerUrl); @@ -544,9 +543,7 @@ @Test @MediumTest public void testAmbientBadgeAppearWithServiceWorkerPage() throws Exception { - String webBannerUrl = - WebappTestPage.getServiceWorkerUrlWithAction( - mTestServer, "call_stashed_prompt_on_click"); + String webBannerUrl = WebappTestPage.getNonServiceWorkerUrl(mTestServer); resetEngagementForUrl(webBannerUrl, 10); navigateToUrlAndWaitForBannerManager(mTabbedActivityTestRule, webBannerUrl); @@ -560,9 +557,7 @@ public void testAmbientBadgeTriggeredWithListedRelatedApp() throws Exception { // The ambient badge should show if there is play app in related applications list but // preferred_related_applications is false. - String webBannerUrl = - WebappTestPage.getServiceWorkerUrlWithAction( - mTestServer, "call_stashed_prompt_on_click"); + String webBannerUrl = WebappTestPage.getNonServiceWorkerUrl(mTestServer); resetEngagementForUrl(webBannerUrl, 10); navigateToUrlAndWaitForBannerManager(mTabbedActivityTestRule, webBannerUrl); @@ -596,10 +591,8 @@ @SmallTest public void testAmbientBadgeDoesNotAppearWhenRelatedAppInstalled() throws Exception { String url = - WebappTestPage.getServiceWorkerUrlWithManifestAndAction( - mTestServer, - WEB_APP_MANIFEST_WITH_RELATED_APP_LIST, - "call_stashed_prompt_on_click"); + WebappTestPage.getNonServiceWorkerUrlWithManifest( + mTestServer, WEB_APP_MANIFEST_WITH_RELATED_APP_LIST); resetEngagementForUrl(url, 10); final Context contextToRestore = ContextUtils.getApplicationContext(); @@ -617,32 +610,28 @@ @Test @SmallTest - @EnableFeatures({ChromeFeatureList.WEB_APP_AMBIENT_BADGE_SUPRESS_FIRST_VISIT}) - public void testAmbientBadgeSuppressedOnFirstVisit() throws Exception { - String url = - WebappTestPage.getServiceWorkerUrlWithAction( - mTestServer, "call_stashed_prompt_on_click"); + public void testMlShowAmbientBadge() throws Exception { + String url = WebappTestPage.getNonServiceWorkerUrl(mTestServer); resetEngagementForUrl(url, 10); + AppBannerManager.setOverrideSegmentationResultForTesting(false); navigateToUrlAndWaitForBannerManager(mTabbedActivityTestRule, url); assertAppBannerPipelineStatus(AppBannerManagerState.PENDING_PROMPT_NOT_CANCELED); Tab tab = mTabbedActivityTestRule.getActivity().getActivityTab(); - waitForBadgeStatus(tab, AmbientBadgeState.PENDING_ENGAGEMENT); - // Advance 3 days and navigate to |url| again, ambient badge should show. + // Blocked by segmentation result. + waitForBadgeStatus(tab, AmbientBadgeState.SEGMENTATION_BLOCK); + checkAmbientBadgePromptNotExist(mTabbedActivityTestRule); + + // Advance 3 days and navigate to |url| again AppBannerManager.setTimeDeltaForTesting(3); + AppBannerManager.setOverrideSegmentationResultForTesting(true); mTabbedActivityTestRule.loadUrl(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL); navigateToUrlAndWaitForBannerManager(mTabbedActivityTestRule, url); + waitForBadgeStatus(tab, AmbientBadgeState.SHOWING); waitUntilAmbientBadgePromptAppears(mTabbedActivityTestRule); - - // Advance 31 more days and navigate to |url| again, no ambient badge. - AppBannerManager.setTimeDeltaForTesting(35); - mTabbedActivityTestRule.loadUrl(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL); - navigateToUrlAndWaitForBannerManager(mTabbedActivityTestRule, url); - waitForBadgeStatus(tab, AmbientBadgeState.PENDING_ENGAGEMENT); - checkAmbientBadgePromptNotExist(mTabbedActivityTestRule); } }
diff --git a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java index 55ee585b..23514b4 100644 --- a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java +++ b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -45,12 +45,10 @@ import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.Features.DisableFeatures; import org.chromium.chrome.browser.ShortcutHelper; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.customtabs.CustomTabsIntentTestUtils; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.ProfileManager; import org.chromium.chrome.browser.tab.Tab; @@ -84,7 +82,6 @@ /** Tests the app banners. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@DisableFeatures({ChromeFeatureList.WEB_APP_AMBIENT_BADGE_SUPRESS_FIRST_VISIT}) public class AppBannerManagerTest { @Rule public ChromeTabbedActivityTestRule mTabbedActivityTestRule = @@ -200,6 +197,7 @@ AppBannerManager.ignoreChromeChannelForTesting(); AppBannerManager.setTotalEngagementForTesting(10); + AppBannerManager.setOverrideSegmentationResultForTesting(true); mTestServer = EmbeddedTestServer.createAndStartServer( ApplicationProvider.getApplicationContext());
diff --git a/chrome/browser/banners/app_banner_manager_browsertest_base.cc b/chrome/browser/banners/app_banner_manager_browsertest_base.cc index cee6b41d..5576197 100644 --- a/chrome/browser/banners/app_banner_manager_browsertest_base.cc +++ b/chrome/browser/banners/app_banner_manager_browsertest_base.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "chrome/browser/banners/app_banner_manager_browsertest_base.h" + #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_utils.h" #include "net/base/url_util.h"
diff --git a/chrome/browser/banners/app_banner_manager_browsertest_base.h b/chrome/browser/banners/app_banner_manager_browsertest_base.h index 02086b8..57adc75 100644 --- a/chrome/browser/banners/app_banner_manager_browsertest_base.h +++ b/chrome/browser/banners/app_banner_manager_browsertest_base.h
@@ -58,7 +58,7 @@ const std::string& value); #if !BUILDFLAG(IS_ANDROID) - web_app::OsIntegrationTestOverrideBlockingRegistration os_hooks_suppress_; + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; #endif };
diff --git a/chrome/browser/chromeos/extensions/info_private_lacros_apitest.cc b/chrome/browser/chromeos/extensions/info_private_lacros_apitest.cc new file mode 100644 index 0000000..ff4379c --- /dev/null +++ b/chrome/browser/chromeos/extensions/info_private_lacros_apitest.cc
@@ -0,0 +1,136 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/test/test_future.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "chromeos/crosapi/mojom/test_controller.mojom-test-utils.h" +#include "chromeos/lacros/lacros_service.h" +#include "content/public/test/browser_test.h" + +namespace { + +bool IsSupportedAsh() { + return (chromeos::LacrosService::Get() + ->GetInterfaceVersion<crosapi::mojom::TestController>() >= + static_cast<int>(crosapi::mojom::TestController::MethodMinVersions:: + kEnableStatisticsProviderForTestingMinVersion)); +} + +} // namespace + +// Tests chromeosInfoPrivate.get function for the properties provided by +// chromeos machine statistics. +class ChromeOSInfoPrivateMachineStatisticsPropertyGetFunctionTest + : public extensions::ExtensionApiTest { + public: + ChromeOSInfoPrivateMachineStatisticsPropertyGetFunctionTest() = default; + + ChromeOSInfoPrivateMachineStatisticsPropertyGetFunctionTest( + const ChromeOSInfoPrivateMachineStatisticsPropertyGetFunctionTest&) = + delete; + ChromeOSInfoPrivateMachineStatisticsPropertyGetFunctionTest& operator=( + const ChromeOSInfoPrivateMachineStatisticsPropertyGetFunctionTest&) = + delete; + ~ChromeOSInfoPrivateMachineStatisticsPropertyGetFunctionTest() override = + default; + + void SetUpOnMainThread() override { + if (!IsSupportedAsh()) { + GTEST_SKIP() << "Unsupported Ash version."; + } + + auto& test_controller = chromeos::LacrosService::Get() + ->GetRemote<crosapi::mojom::TestController>(); + base::test::TestFuture<void> future; + test_controller->EnableStatisticsProviderForTesting(/*enable=*/true, + future.GetCallback()); + EXPECT_TRUE(future.Wait()); + + extensions::ExtensionApiTest::SetUpOnMainThread(); + } + + void TearDownOnMainThread() override { + if (!IsSupportedAsh()) { + return; + } + + auto& test_controller = chromeos::LacrosService::Get() + ->GetRemote<crosapi::mojom::TestController>(); + base::test::TestFuture<void> future; + test_controller->ClearAllMachineStatistics(future.GetCallback()); + EXPECT_TRUE(future.WaitAndClear()); + test_controller->EnableStatisticsProviderForTesting(/*enable=*/false, + future.GetCallback()); + EXPECT_TRUE(future.Wait()); + + extensions::ExtensionApiTest::TearDownOnMainThread(); + } +}; + +IN_PROC_BROWSER_TEST_F( + ChromeOSInfoPrivateMachineStatisticsPropertyGetFunctionTest, + TestPropertiesUnset) { + auto& test_controller = chromeos::LacrosService::Get() + ->GetRemote<crosapi::mojom::TestController>(); + base::test::TestFuture<void> future; + test_controller->ClearAllMachineStatistics(future.GetCallback()); + EXPECT_TRUE(future.Wait()); + + ASSERT_TRUE( + RunExtensionTest("chromeos_info_private/extended", + {.custom_arg = "Machine Statistics Properties - Unset", + .launch_as_platform_app = true})) + << message_; +} + +IN_PROC_BROWSER_TEST_F( + ChromeOSInfoPrivateMachineStatisticsPropertyGetFunctionTest, + TestDeviceRequisitionRemora) { + auto& test_controller = chromeos::LacrosService::Get() + ->GetRemote<crosapi::mojom::TestController>(); + base::test::TestFuture<bool> future; + test_controller->SetMachineStatistic( + crosapi::mojom::MachineStatisticKeyType::kOemDeviceRequisitionKey, + "remora", future.GetCallback()); + ASSERT_TRUE(future.Take()); + + ASSERT_TRUE(RunExtensionTest("chromeos_info_private/extended", + {.custom_arg = "Device Requisition - Remora", + .launch_as_platform_app = true})) + << message_; +} + +IN_PROC_BROWSER_TEST_F( + ChromeOSInfoPrivateMachineStatisticsPropertyGetFunctionTest, + TestHWID) { + auto& test_controller = chromeos::LacrosService::Get() + ->GetRemote<crosapi::mojom::TestController>(); + base::test::TestFuture<bool> future; + test_controller->SetMachineStatistic( + crosapi::mojom::MachineStatisticKeyType::kHardwareClassKey, "test_hw", + future.GetCallback()); + ASSERT_TRUE(future.Take()); + + ASSERT_TRUE( + RunExtensionTest("chromeos_info_private/extended", + {.custom_arg = "HWID", .launch_as_platform_app = true})) + << message_; +} + +IN_PROC_BROWSER_TEST_F( + ChromeOSInfoPrivateMachineStatisticsPropertyGetFunctionTest, + TestCustomizationID) { + auto& test_controller = chromeos::LacrosService::Get() + ->GetRemote<crosapi::mojom::TestController>(); + base::test::TestFuture<bool> future; + test_controller->SetMachineStatistic( + crosapi::mojom::MachineStatisticKeyType::kCustomizationIdKey, + "test_customization_id", future.GetCallback()); + ASSERT_TRUE(future.Take()); + + ASSERT_TRUE(RunExtensionTest( + "chromeos_info_private/extended", + {.custom_arg = "CustomizationId", .launch_as_platform_app = true})) + << message_; +}
diff --git a/chrome/browser/content_settings/DEPS b/chrome/browser/content_settings/DEPS deleted file mode 100644 index 327971a..0000000 --- a/chrome/browser/content_settings/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+pdf/pdf_features.h", -] \ No newline at end of file
diff --git a/chrome/browser/dips/dips_bounce_detector.cc b/chrome/browser/dips/dips_bounce_detector.cc index a02424bc..44704287 100644 --- a/chrome/browser/dips/dips_bounce_detector.cc +++ b/chrome/browser/dips/dips_bounce_detector.cc
@@ -315,9 +315,8 @@ void DIPSRedirectContext::HandleUncommitted( DIPSNavigationStart navigation_start, - std::vector<DIPSRedirectInfoPtr> server_redirects) { - // Uncommitted navigations leave the user on the last-committed page; use that - // for `final_url`. + std::vector<DIPSRedirectInfoPtr> server_redirects, + GURL final_url) { absl::visit( // base::Overloaded{ [&](DIPSRedirectInfoPtr client_redirect) { @@ -329,8 +328,6 @@ DIPSRedirectContext temp_context(handler_, issue_handler_, initial_url_, GetRedirectChainLength()); - // Copy the URL of `client_redirect` before moving it. - GURL final_url = client_redirect->url; temp_context.AppendClientRedirect(std::move(client_redirect)); temp_context.AppendServerRedirects(std::move(server_redirects)); temp_context.ReportIssue(final_url); @@ -346,11 +343,9 @@ previous_nav_last_committed_url, /*redirect_prefix_count=*/0); temp_context.AppendServerRedirects(std::move(server_redirects)); - temp_context.ReportIssue( - /*final_url=*/previous_nav_last_committed_url); - temp_context.EndChain( - /*final_url=*/std::move(previous_nav_last_committed_url), - /*current_page_has_sticky_activation=*/false); + temp_context.ReportIssue(final_url); + temp_context.EndChain(std::move(final_url), + /*current_page_has_sticky_activation=*/false); }, }, std::move(navigation_start)); @@ -970,17 +965,9 @@ std::move(server_state->navigation_start), std::move(redirects), navigation_handle->GetURL(), current_page_has_sticky_activation); } else { - // For uncommitted navigations, treat the last URL visited as a server - // redirect, so it is considered a potential tracker. - const size_t i = access_types.size() - 1; - redirects.push_back(std::make_unique<DIPSRedirectInfo>( - /*url=*/navigation_handle->GetRedirectChain()[i], - /*redirect_type=*/DIPSRedirectType::kServer, - /*access_type=*/access_types[i], - /*source_id=*/navigation_handle->GetRedirectSourceId(i), - /*time=*/clock_->Now())); committed_redirect_context_.HandleUncommitted( - std::move(server_state->navigation_start), std::move(redirects)); + std::move(server_state->navigation_start), std::move(redirects), + navigation_handle->GetURL()); } if (navigation_handle->HasCommitted()) {
diff --git a/chrome/browser/dips/dips_bounce_detector.h b/chrome/browser/dips/dips_bounce_detector.h index 4ccb8fe..ef5de14 100644 --- a/chrome/browser/dips/dips_bounce_detector.h +++ b/chrome/browser/dips/dips_bounce_detector.h
@@ -94,7 +94,8 @@ // navigation. It will take into account the length and initial URL of the // current chain (without modifying it). void HandleUncommitted(DIPSNavigationStart navigation_start, - std::vector<DIPSRedirectInfoPtr> server_redirects); + std::vector<DIPSRedirectInfoPtr> server_redirects, + GURL final_url); // Either calls for termination of the in-progress redirect chain, with a // start of a new one, or extends it, according to the value of
diff --git a/chrome/browser/dips/dips_bounce_detector_browsertest.cc b/chrome/browser/dips/dips_bounce_detector_browsertest.cc index 39b5e95..8796fb2f5 100644 --- a/chrome/browser/dips/dips_bounce_detector_browsertest.cc +++ b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
@@ -20,7 +20,6 @@ #include "base/run_loop.h" #include "base/strings/escape.h" #include "base/strings/strcat.h" -#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/task/single_thread_task_runner.h" #include "base/test/bind.h" @@ -71,7 +70,6 @@ #include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_utils.h" #include "net/dns/mock_host_resolver.h" -#include "net/http/http_status_code.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" @@ -173,20 +171,6 @@ return origins; } -// /nocontent-set-cookie -// Returns a HTTP 204 No Content response that sets a cookie. -std::unique_ptr<net::test_server::HttpResponse> HandleNoContentSetCookie( - const net::test_server::HttpRequest& request) { - if (request.relative_url != "/nocontent-set-cookie") { - return nullptr; - } - - auto http_response = std::make_unique<net::test_server::BasicHttpResponse>(); - http_response->set_code(net::HTTP_NO_CONTENT); - http_response->AddCustomHeader("Set-Cookie", "no-content=true"); - return http_response; -} - } // namespace // Keeps a log of DidStartNavigation, OnCookiesAccessed, and DidFinishNavigation @@ -2855,33 +2839,6 @@ ->RemoveObserver(logger); } -// Verifies that a HTTP 204 (No Content) response is treated like a bounce. -IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest, NoContentSetCookie) { - net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); - https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES); - https_server.AddDefaultHandlers(kChromeTestDataDir); - https_server.RegisterRequestHandler( - base::BindRepeating(&HandleNoContentSetCookie)); - ASSERT_TRUE(https_server.Start()); - content::WebContents* web_contents = GetActiveWebContents(); - - GURL committed_url = https_server.GetURL("a.test", "/title1.html"); - RedirectChainObserver observer( - DIPSService::Get(web_contents->GetBrowserContext()), committed_url, - /*expected_match_count=*/2); - ASSERT_TRUE(content::NavigateToURL(web_contents, committed_url)); - - GURL nocontent_url = https_server.GetURL("b.test", "/nocontent-set-cookie"); - ASSERT_TRUE( - content::NavigateToURL(web_contents, nocontent_url, committed_url)); - observer.Wait(); - - base::test::TestFuture<const std::vector<std::string>&> deleted_sites; - DIPSService::Get(web_contents->GetBrowserContext()) - ->DeleteEligibleSitesImmediately(deleted_sites.GetCallback()); - ASSERT_THAT(deleted_sites.Get(), ElementsAre("b.test")); -} - class DIPSThrottlingBrowserTest : public DIPSBounceDetectorBrowserTest { public: void SetUpOnMainThread() override {
diff --git a/chrome/browser/dips/dips_bounce_detector_unittest.cc b/chrome/browser/dips/dips_bounce_detector_unittest.cc index 4e6ba6a..012163c2 100644 --- a/chrome/browser/dips/dips_bounce_detector_unittest.cc +++ b/chrome/browser/dips/dips_bounce_detector_unittest.cc
@@ -631,9 +631,8 @@ EndPendingRedirectChain(); EXPECT_THAT(redirects(), testing::ElementsAre( - ("[1/3] a.test/ -> b.test/ (None) -> a.test/"), - ("[2/3] a.test/ -> c.test/ (None) -> a.test/"), - ("[3/3] a.test/ -> d.test/ (None) -> a.test/"), + ("[1/2] a.test/ -> b.test/ (None) -> d.test/"), + ("[2/2] a.test/ -> c.test/ (None) -> d.test/"), ("[1/1] a.test/ -> e.test/ (None) -> f.test/"))); EXPECT_THAT(GetRecordedBounces(), testing::UnorderedElementsAre( @@ -641,8 +640,6 @@ /*stateful=*/false), MakeBounceTuple("http://c.test", mocked_bounce_time, /*stateful=*/false), - MakeBounceTuple("http://d.test", mocked_bounce_time, - /*stateful=*/false), MakeBounceTuple("http://e.test", mocked_bounce_time, /*stateful=*/false))); EXPECT_EQ(stateful_bounce_count(), 0); @@ -665,9 +662,8 @@ EndPendingRedirectChain(); EXPECT_THAT(redirects(), testing::ElementsAre( - ("[1/3] a.test/ -> b.test/ (None) -> b.test/"), - ("[2/3] a.test/ -> c.test/ (None) -> b.test/"), - ("[3/3] a.test/ -> d.test/ (None) -> b.test/"), + ("[1/2] a.test/ -> b.test/ (None) -> d.test/"), + ("[2/2] a.test/ -> c.test/ (None) -> d.test/"), ("[1/2] a.test/ -> b.test/ (None) -> f.test/"), ("[2/2] a.test/ -> e.test/ (None) -> f.test/"))); EXPECT_THAT(GetRecordedBounces(), @@ -676,8 +672,6 @@ /*stateful=*/false), MakeBounceTuple("http://c.test", mocked_bounce_time, /*stateful=*/false), - MakeBounceTuple("http://d.test", mocked_bounce_time, - /*stateful=*/false), MakeBounceTuple("http://e.test", mocked_bounce_time, /*stateful=*/false))); EXPECT_EQ(stateful_bounce_count(), 0); @@ -728,8 +722,7 @@ .RedirectTo("http://d.test") .AccessCookie(CookieOperation::kChange) .Finish(false); - EXPECT_THAT(GetReportedSites(), - testing::ElementsAre("b.test, c.test, d.test")); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test, c.test")); // Because the previous navigation didn't commit, the following chain still // starts from http://a.test/. @@ -739,7 +732,7 @@ .AccessCookie(CookieOperation::kChange) .Finish(true); EXPECT_THAT(GetReportedSites(), - testing::ElementsAre("b.test, c.test, d.test", "e.test")); + testing::ElementsAre("b.test, c.test", "e.test")); } TEST_F(DIPSBounceDetectorTest, @@ -862,14 +855,13 @@ .RedirectTo("http://c.test") .AccessCookie(CookieOperation::kChange) .Finish(false); - EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test, c.test")); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test")); // Navigate without a click (i.e. by C-redirecting) to d.test. // NOTE: Because the previous navigation didn't commit, the chain still // starts from http://a.test/. NavigateTo("http://d.test", kNoUserGesture); - EXPECT_THAT(GetReportedSites(), - testing::ElementsAre("b.test, c.test", "a.test")); + EXPECT_THAT(GetReportedSites(), testing::ElementsAre("b.test", "a.test")); } const std::vector<std::string>& GetAllRedirectMetrics() { @@ -1289,7 +1281,8 @@ ASSERT_EQ(chains.size(), 0u); context.HandleUncommitted( GURL("http://d.test/"), - MakeServerRedirects({"http://e.test/", "http://f.test/"})); + MakeServerRedirects({"http://e.test/", "http://f.test/"}), + GURL("http://g.test/")); ASSERT_EQ(chains.size(), 1u); context.AppendCommitted(GURL("http://h.test/"), MakeServerRedirects({"http://i.test/"}), @@ -1301,7 +1294,7 @@ // First, the uncommitted (middle) chain. EXPECT_THAT(chains[0].first, AllOf(HasInitialUrl("http://d.test/"), - HasFinalUrl("http://d.test/"), HasLength(2u))); + HasFinalUrl("http://g.test/"), HasLength(2u))); EXPECT_THAT(chains[0].second, ElementsAre(HasUrl("http://e.test/"), HasUrl("http://f.test/"))); // Then the initially-started chain. @@ -1332,7 +1325,8 @@ // Uncommitted navigation: context.HandleUncommitted( MakeClientRedirect("http://d.test/"), - MakeServerRedirects({"http://e.test/", "http://f.test/"})); + MakeServerRedirects({"http://e.test/", "http://f.test/"}), + GURL("http://g.test/")); ASSERT_EQ(chains.size(), 1u); context.AppendCommitted(MakeClientRedirect("http://h.test/"), MakeServerRedirects({"http://i.test/"}), @@ -1346,7 +1340,7 @@ // plus the uncommitted part (3 redirects, starting from d.test). EXPECT_THAT(chains[0].first, AllOf(HasInitialUrl("http://a.test/"), - HasFinalUrl("http://d.test/"), HasLength(5u))); + HasFinalUrl("http://g.test/"), HasLength(5u))); // But only the 3 uncommitted redirects are included in the vector. EXPECT_THAT(chains[0].second, ElementsAre(HasUrl("http://d.test/"), HasUrl("http://e.test/"), @@ -1377,18 +1371,26 @@ false); ASSERT_EQ(chains.size(), 1u); - context.EndChain(GURL("http://e.test/"), false); + context.HandleUncommitted(GURL("http://c.test/"), {}, GURL("http://d.test/")); ASSERT_EQ(chains.size(), 2u); + context.EndChain(GURL("http://e.test/"), false); + ASSERT_EQ(chains.size(), 3u); + EXPECT_THAT(chains[0].first, AllOf(HasInitialUrl("http://a.test/"), HasFinalUrl("http://b.test/"), HasLength(0u))); EXPECT_THAT(chains[0].second, IsEmpty()); EXPECT_THAT(chains[1].first, + AllOf(HasInitialUrl("http://c.test/"), + HasFinalUrl("http://d.test/"), HasLength(0u))); + EXPECT_THAT(chains[1].second, IsEmpty()); + + EXPECT_THAT(chains[2].first, AllOf(HasInitialUrl("http://b.test/"), HasFinalUrl("http://e.test/"), HasLength(0u))); - EXPECT_THAT(chains[1].second, IsEmpty()); + EXPECT_THAT(chains[2].second, IsEmpty()); } TEST(DIPSRedirectContextTest, AddLateCookieAccess) {
diff --git a/chrome/browser/dips/dips_test_utils.cc b/chrome/browser/dips/dips_test_utils.cc index 2f8d5b1..fd81eae 100644 --- a/chrome/browser/dips/dips_test_utils.cc +++ b/chrome/browser/dips/dips_test_utils.cc
@@ -164,10 +164,8 @@ } RedirectChainObserver::RedirectChainObserver(DIPSService* service, - GURL final_url, - size_t expected_match_count) - : final_url_(std::move(final_url)), - expected_match_count_(expected_match_count) { + GURL final_url) + : final_url_(std::move(final_url)) { obs_.Observe(service); } @@ -176,8 +174,7 @@ void RedirectChainObserver::OnChainHandled( const DIPSRedirectChainInfoPtr& chain) { handle_call_count++; - if (chain->final_url == final_url_ && - ++match_count_ == expected_match_count_) { + if (chain->final_url == final_url_) { run_loop_.Quit(); } }
diff --git a/chrome/browser/dips/dips_test_utils.h b/chrome/browser/dips/dips_test_utils.h index f8bd9075..070eb64 100644 --- a/chrome/browser/dips/dips_test_utils.h +++ b/chrome/browser/dips/dips_test_utils.h
@@ -180,9 +180,7 @@ class RedirectChainObserver : public DIPSService::Observer { public: - explicit RedirectChainObserver(DIPSService* service, - GURL final_url, - size_t expected_match_count = 1); + explicit RedirectChainObserver(DIPSService* service, GURL final_url); ~RedirectChainObserver() override; void OnChainHandled(const DIPSRedirectChainInfoPtr& chain) override; @@ -193,8 +191,6 @@ private: GURL final_url_; - size_t match_count_ = 0; - size_t expected_match_count_; base::RunLoop run_loop_; base::ScopedObservation<DIPSService, Observer> obs_{this}; };
diff --git a/chrome/browser/download/DEPS b/chrome/browser/download/DEPS deleted file mode 100644 index 487e1f81..0000000 --- a/chrome/browser/download/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+pdf/pdf_features.h" -] \ No newline at end of file
diff --git a/chrome/browser/download/download_browsertest_utils.cc b/chrome/browser/download/download_browsertest_utils.cc index 048a6cff..338624a 100644 --- a/chrome/browser/download/download_browsertest_utils.cc +++ b/chrome/browser/download/download_browsertest_utils.cc
@@ -3,13 +3,12 @@ // found in the LICENSE file. #include "chrome/browser/download/download_browsertest_utils.h" -#include "base/memory/raw_ptr.h" -#include "base/strings/utf_string_conversions.h" -#include "content/public/test/browser_test_utils.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/memory/raw_ptr.h" #include "base/path_service.h" +#include "base/strings/utf_string_conversions.h" #include "base/test/test_file_util.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/profiles/profile.h" @@ -21,6 +20,7 @@ #include "chrome/test/base/ui_test_utils.h" #include "components/prefs/pref_service.h" #include "content/public/browser/download_request_utils.h" +#include "content/public/test/browser_test_utils.h" #include "net/dns/mock_host_resolver.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "third_party/blink/public/common/switches.h"
diff --git a/chrome/browser/download/download_browsertest_utils.h b/chrome/browser/download/download_browsertest_utils.h index 4a897e86..7e9e0f51 100644 --- a/chrome/browser/download/download_browsertest_utils.h +++ b/chrome/browser/download/download_browsertest_utils.h
@@ -11,6 +11,7 @@ #include "base/memory/raw_ptr.h" #include "chrome/browser/download/download_test_file_activity_observer.h" #include "chrome/browser/extensions/install_verifier.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/download_test_observer.h" #include "content/public/test/slow_download_http_response.h" @@ -269,6 +270,8 @@ } private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; + // Location of the test data. base::FilePath test_dir_;
diff --git a/chrome/browser/extensions/DEPS b/chrome/browser/extensions/DEPS index 18f2f471..99e9489 100644 --- a/chrome/browser/extensions/DEPS +++ b/chrome/browser/extensions/DEPS
@@ -4,7 +4,6 @@ "+components/guest_view/common", "+components/live_caption", "+extensions/strings/grit/extensions_strings.h", - "+pdf/pdf_features.h", "+services/network/public", # For access to testing command line switches.
diff --git a/chrome/browser/extensions/api/DEPS b/chrome/browser/extensions/api/DEPS index 3fafb25..aa705a3 100644 --- a/chrome/browser/extensions/api/DEPS +++ b/chrome/browser/extensions/api/DEPS
@@ -3,7 +3,6 @@ "+components/live_caption", "+services/device/public", "+components/device_reauth", - "+pdf/pdf_features.h", # Enable remote assistance on Chrome OS "+remoting/host", ]
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_util.cc b/chrome/browser/extensions/api/autofill_private/autofill_util.cc index 83abbed7..06da262 100644 --- a/chrome/browser/extensions/api/autofill_private/autofill_util.cc +++ b/chrome/browser/extensions/api/autofill_private/autofill_util.cc
@@ -313,7 +313,8 @@ card.image_src = card_art_image ? webui::GetBitmapDataUrl(card_art_image->AsBitmap()) : CardNetworkToIconResourceIdString(credit_card.network()); - if (credit_card.IsCardEligibleForBenefits() && + if (personal_data.payments_data_manager().IsCardEligibleForBenefits( + credit_card) && credit_card.product_terms_url().is_valid()) { card.product_terms_url = credit_card.product_terms_url().spec(); }
diff --git a/chrome/browser/extensions/api/management/management_apitest.cc b/chrome/browser/extensions/api/management/management_apitest.cc index 91b6551..2ebd67ff 100644 --- a/chrome/browser/extensions/api/management/management_apitest.cc +++ b/chrome/browser/extensions/api/management/management_apitest.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/web_applications/extension_status_utils.h" #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" #include "chrome/browser/web_applications/test/fake_web_app_ui_manager.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_provider.h" @@ -142,8 +143,7 @@ protected: base::AutoReset<bool> enable_chrome_apps_; - // Stop test from installing OS hooks. - web_app::OsIntegrationManager::ScopedSuppressForTesting os_hooks_suppress_; + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; }; INSTANTIATE_TEST_SUITE_P(PersistentBackground, @@ -207,7 +207,7 @@ protected: static const char kManifest[]; static const char kAppManifest[]; - web_app::OsIntegrationManager::ScopedSuppressForTesting os_hooks_suppress_; + void SetUpOnMainThread() override { ExtensionManagementApiTest::SetUpOnMainThread(); https_test_server_.ServeFilesFromDirectory(test_data_dir_);
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 7b0c25d..6ec196e 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -787,6 +787,10 @@ (*s_allowlist)[::ash::prefs::kIsolatedWebAppsEnabled] = settings_api::PrefType::kBoolean; + // App - On-Device Parental Controls + (*s_allowlist)[::ash::prefs::kOnDeviceAppControlsSetupCompleted] = + settings_api::PrefType::kBoolean; + // Ambient Mode. (*s_allowlist)[ash::ambient::prefs::kAmbientModeEnabled] = settings_api::PrefType::kBoolean;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 53545e6..481449ba 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -4826,11 +4826,6 @@ "expiry_milestone": 125 }, { - "name": "history-journeys-labels", - "owners": [ "tommycli@chromium.org", "chrome-journeys@google.com" ], - "expiry_milestone": 125 - }, - { "name": "history-journeys-show-all-clusters", "owners": [ "sophiechang@chromium.org", "chrome-journeys@google.com", "chrome-intelligence-core@google.com" ], "expiry_milestone": 125 @@ -5653,13 +5648,6 @@ "expiry_milestone": 114 }, { - "name": "ml-mobile-pwa-prompt", - "owners": [ - "eirage@chromium.org", "mwi-team-core@google.com" - ], - "expiry_milestone": 120 - }, - { "name": "modern-tab-strip", "owners": [ "bling-flags@google.com" ], "expiry_milestone": 125 @@ -7287,7 +7275,7 @@ { "name": "request-desktop-site-window-setting", "owners": [ "shuyng@google.com", "skavuluru@google.com", "clank-app-team@google.com" ], - "expiry_milestone": 126 + "expiry_milestone": 130 }, { "name": "reset-shortcut-customizations", @@ -7671,7 +7659,7 @@ { "name": "site-instance-groups-for-data-urls", "owners": [ "yangsharon@chromium.org", "site-isolation-dev@chromium.org" ], - "expiry_milestone": 125 + "expiry_milestone": 140 }, { "_comment1": "Shipping some form of Site Isolation to Android is tracked",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index a4c8048..f85b326 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2175,10 +2175,6 @@ const char kJourneysName[] = "History Journeys"; const char kJourneysDescription[] = "Enables the History Journeys UI."; -const char kJourneysLabelsName[] = "History Journeys Labels"; -const char kJourneysLabelsDescription[] = - "Enables labels for Journeys within the History Journeys UI."; - const char kJourneysShowAllClustersName[] = "History Journeys Show All Clusters"; const char kJourneysShowAllClustersDescription[] = @@ -4173,12 +4169,6 @@ const char kMessagesForAndroidStackingAnimationDescription[] = "When enabled, Messages UI will use the new stacking animation."; -const char kMobilePWAInstallPromptMlName[] = - "Use ML to show mobile PWA install prompt"; -const char kMobilePWAInstallPromptMlDescription[] = - "When enabled, will use ML result to decide whether mobile PWA install " - "prompt should be shown."; - const char kMouseAndTrackpadDropdownMenuName[] = "Android Mouse & Trackpad Drop-down Text Selection Menu"; const char kMouseAndTrackpadDropdownMenuDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 6c05e84..8df54ba7 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1246,9 +1246,6 @@ extern const char kJourneysName[]; extern const char kJourneysDescription[]; -extern const char kJourneysLabelsName[]; -extern const char kJourneysLabelsDescription[]; - extern const char kJourneysShowAllClustersName[]; extern const char kJourneysShowAllClustersDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 946dedd..0529325 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -178,7 +178,6 @@ &kCacheActivityTaskID, &kCastDeviceFilter, &kClearOmniboxFocusAfterNavigation, - &kCreateNewTabInitializeRenderer, &kCCTClientDataHeader, &kCCTEmbedderSpecialBehaviorTrigger, &kCCTExtendTrustedCdnPublisher, @@ -364,7 +363,6 @@ &syncer::kSyncShowIdentityErrorsForSignedInUsers, &syncer::kWebApkBackupAndRestoreBackend, &tab_groups::kTabGroupSyncAndroid, - &webapps::features::kAmbientBadgeSuppressFirstVisit, &webapps::features::kPwaUniversalInstallUi, &webapps::features::kWebApkInstallFailureNotification, &network::features::kPrivateStateTokens, @@ -426,7 +424,7 @@ "AndroidHatsRefactor", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kAndroidHub, "AndroidHub", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kAndroidHub, "AndroidHub", base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kAndroidImprovedBookmarks, "AndroidImprovedBookmarks", @@ -493,10 +491,6 @@ "ClearOmniboxFocusAfterNavigation", base::FEATURE_ENABLED_BY_DEFAULT); -BASE_FEATURE(kCreateNewTabInitializeRenderer, - "CreateNewTabInitializeRenderer", - base::FEATURE_DISABLED_BY_DEFAULT); - BASE_FEATURE(kCCTClientDataHeader, "CCTClientDataHeader", base::FEATURE_DISABLED_BY_DEFAULT); @@ -837,7 +831,7 @@ BASE_FEATURE(kTabAndLinkDragDropAndroid, "TabAndLinkDragDropAndroid", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kTabGroupPaneAndroid, "TabGroupPaneAndroid",
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index ab4f5ab..68ab7b9 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -44,7 +44,6 @@ BASE_DECLARE_FEATURE(kBrowserControlsEarlyResize); BASE_DECLARE_FEATURE(kCacheActivityTaskID); BASE_DECLARE_FEATURE(kClearOmniboxFocusAfterNavigation); -BASE_DECLARE_FEATURE(kCreateNewTabInitializeRenderer); BASE_DECLARE_FEATURE(kCastDeviceFilter); BASE_DECLARE_FEATURE(kCCTClientDataHeader); BASE_DECLARE_FEATURE(kCCTEmbedderSpecialBehaviorTrigger);
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 a28a6e21..d42f001 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
@@ -258,8 +258,6 @@ public static final String CONTEXT_MENU_TRANSLATE_WITH_GOOGLE_LENS = "ContextMenuTranslateWithGoogleLens"; public static final String CORMORANT = "Cormorant"; - public static final String CREATE_NEW_TAB_INITIALIZE_RENDERER = - "CreateNewTabInitializeRenderer"; public static final String DARKEN_WEBSITES_CHECKBOX_IN_THEMES_SETTING = "DarkenWebsitesCheckboxInThemesSetting"; public static final String DATA_SHARING = "DataSharing"; @@ -502,8 +500,6 @@ public static final String VOICE_SEARCH_AUDIO_CAPTURE_POLICY = "VoiceSearchAudioCapturePolicy"; public static final String WEB_APK_ALLOW_ICON_UPDATE = "WebApkAllowIconUpdate"; public static final String WEB_APK_BACKUP_AND_RESTORE_BACKEND = "WebApkBackupAndRestoreBackend"; - public static final String WEB_APP_AMBIENT_BADGE_SUPRESS_FIRST_VISIT = - "AmbientBadgeSuppressFirstVisit"; public static final String WEB_APK_INSTALL_FAILURE_NOTIFICATION = "WebApkInstallFailureNotification"; public static final String WEB_AUTHN_ENABLE_CABLE_AUTHENTICATOR = @@ -521,7 +517,7 @@ newCachedFlag(ANDROID_APP_INTEGRATION, false); public static final CachedFlag sAndroidElegantTextHeight = newCachedFlag(ANDROID_ELEGANT_TEXT_HEIGHT, false); - public static final CachedFlag sAndroidHub = newCachedFlag(ANDROID_HUB, false); + public static final CachedFlag sAndroidHub = newCachedFlag(ANDROID_HUB, true); public static final CachedFlag sAndroidTabGroupStableIds = newCachedFlag(ANDROID_TAB_GROUP_STABLE_IDS, false); public static final CachedFlag sAppSpecificHistory = newCachedFlag(APP_SPECIFIC_HISTORY, false); @@ -639,7 +635,7 @@ public static final CachedFlag sTabGroupSyncAndroid = newCachedFlag(TAB_GROUP_SYNC_ANDROID, false); public static final CachedFlag sTabLinkDragDropAndroid = - newCachedFlag(TAB_LINK_DRAG_DROP_ANDROID, false); + newCachedFlag(TAB_LINK_DRAG_DROP_ANDROID, true); public static final CachedFlag sTabResumptionModuleAndroid = newCachedFlag(TAB_RESUMPTION_MODULE_ANDROID, false); public static final CachedFlag sTabStateFlatBuffer = newCachedFlag(TAB_STATE_FLATBUFFER, false);
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index d52aaac..ed7f2f4 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -235,6 +235,12 @@ LAZY_INSTANCE_INITIALIZER; #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_WIN) +// Needs to be kept in sync with the writer in PlatformExperienceHelper. +const char kPlatformExperienceHelperHistogramAllocatorName[] = + "PlatformExperienceHelperMetrics"; +#endif // BUILDFLAG(IS_WIN) + void RegisterFileMetricsPreferences(PrefRegistrySimple* registry) { metrics::FileMetricsProvider::RegisterSourcePrefs(registry, kBrowserMetricsName); @@ -251,6 +257,8 @@ metrics::FileMetricsProvider::RegisterSourcePrefs( registry, notification_helper::kNotificationHelperHistogramAllocatorName); + metrics::FileMetricsProvider::RegisterSourcePrefs( + registry, kPlatformExperienceHelperHistogramAllocatorName); #endif } @@ -362,13 +370,16 @@ metrics::FileMetricsProvider::ASSOCIATE_CURRENT_RUN, installer::kSetupHistogramAllocatorName)); - // When metrics reporting is enabled, register the notification_helper metrics - // files; otherwise delete any existing files in order to preserve user - // privacy. + // When metrics reporting is enabled, register the notification_helper + // and platform experience helper metrics files; otherwise delete any + // existing files in order to preserve user privacy. if (!user_data_dir.empty()) { base::FilePath notification_helper_metrics_upload_dir = user_data_dir.AppendASCII( notification_helper::kNotificationHelperHistogramAllocatorName); + base::FilePath platform_experience_helper_metrics_upload_dir = + user_data_dir.AppendASCII( + kPlatformExperienceHelperHistogramAllocatorName); if (metrics_reporting_enabled) { file_metrics_provider->RegisterSource( @@ -377,6 +388,12 @@ metrics::FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR, metrics::FileMetricsProvider::ASSOCIATE_CURRENT_RUN, notification_helper::kNotificationHelperHistogramAllocatorName)); + file_metrics_provider->RegisterSource( + metrics::FileMetricsProvider::Params( + platform_experience_helper_metrics_upload_dir, + metrics::FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_DIR, + metrics::FileMetricsProvider::ASSOCIATE_CURRENT_RUN, + kPlatformExperienceHelperHistogramAllocatorName)); } else { base::ThreadPool::PostTask( FROM_HERE, @@ -384,6 +401,12 @@ base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::GetDeletePathRecursivelyCallback( std::move(notification_helper_metrics_upload_dir))); + base::ThreadPool::PostTask( + FROM_HERE, + {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::GetDeletePathRecursivelyCallback( + std::move(platform_experience_helper_metrics_upload_dir))); } } #endif
diff --git a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc index c0be92ca..50dfd16c 100644 --- a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc +++ b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
@@ -35,6 +35,7 @@ #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/common/chrome_features.h" @@ -1072,6 +1073,7 @@ } private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; base::test::ScopedFeatureList scoped_feature_list_; };
diff --git a/chrome/browser/pdf/DEPS b/chrome/browser/pdf/DEPS index 502b0d5..b320e01 100644 --- a/chrome/browser/pdf/DEPS +++ b/chrome/browser/pdf/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+chrome/browser/profiles/profile.h", - "+pdf/pdf_features.h", ] specific_include_rules = {
diff --git a/chrome/browser/plugins/DEPS b/chrome/browser/plugins/DEPS deleted file mode 100644 index cc864aa..0000000 --- a/chrome/browser/plugins/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+pdf/pdf_features.h", -]
diff --git a/chrome/browser/printing/DEPS b/chrome/browser/printing/DEPS index 28c8ff5d..1f4600f 100644 --- a/chrome/browser/printing/DEPS +++ b/chrome/browser/printing/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+pdf/pdf.h", # Test only. - "+pdf/pdf_features.h", # Test only ] specific_include_rules = {
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_settings_browsertest.cc b/chrome/browser/privacy_sandbox/tracking_protection_settings_browsertest.cc index 3d5a667..a487198 100644 --- a/chrome/browser/privacy_sandbox/tracking_protection_settings_browsertest.cc +++ b/chrome/browser/privacy_sandbox/tracking_protection_settings_browsertest.cc
@@ -20,14 +20,8 @@ class TrackingProtectionSettingsMetricsBrowserTest : public InProcessBrowserTest { - public: - TrackingProtectionSettingsMetricsBrowserTest() { - feature_list_.InitAndEnableFeature(privacy_sandbox::kIpProtectionV1); - } - protected: base::HistogramTester histogram_tester_; - base::test::ScopedFeatureList feature_list_; }; IN_PROC_BROWSER_TEST_F(TrackingProtectionSettingsMetricsBrowserTest, @@ -36,6 +30,8 @@ false, 1); histogram_tester_.ExpectUniqueSample("Settings.IpProtection.Enabled", false, 1); + histogram_tester_.ExpectUniqueSample( + "Settings.FingerprintingProtection.Enabled", false, 1); } class TrackingProtectionSettingsForEnterpriseBrowserTest
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_settings_factory.cc b/chrome/browser/privacy_sandbox/tracking_protection_settings_factory.cc index 7caf2104..f5b2d80 100644 --- a/chrome/browser/privacy_sandbox/tracking_protection_settings_factory.cc +++ b/chrome/browser/privacy_sandbox/tracking_protection_settings_factory.cc
@@ -55,11 +55,12 @@ } else { base::UmaHistogramBoolean("Settings.TrackingProtection.Enabled", false); } - if (base::FeatureList::IsEnabled(privacy_sandbox::kIpProtectionV1)) { - base::UmaHistogramBoolean( - "Settings.IpProtection.Enabled", - profile->GetPrefs()->GetBoolean(prefs::kIpProtectionEnabled)); - } + base::UmaHistogramBoolean( + "Settings.IpProtection.Enabled", + profile->GetPrefs()->GetBoolean(prefs::kIpProtectionEnabled)); + base::UmaHistogramBoolean("Settings.FingerprintingProtection.Enabled", + profile->GetPrefs()->GetBoolean( + prefs::kFingerprintingProtectionEnabled)); } return std::make_unique<privacy_sandbox::TrackingProtectionSettings>(
diff --git a/chrome/browser/renderer_context_menu/DEPS b/chrome/browser/renderer_context_menu/DEPS deleted file mode 100644 index 487e1f81..0000000 --- a/chrome/browser/renderer_context_menu/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+pdf/pdf_features.h" -] \ No newline at end of file
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index 9790051..50fb748 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -58,6 +58,7 @@ #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_command_scheduler.h" #include "chrome/browser/web_applications/web_app_install_info.h" @@ -428,7 +429,7 @@ } private: - web_app::OsIntegrationManager::ScopedSuppressForTesting os_hooks_suppress_; + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; base::test::ScopedFeatureList scoped_feature_list_; AllowPreCommitInputFlagMixin allow_pre_commit_input_flag_mixin_{mixin_host_}; };
diff --git a/chrome/browser/resources/ash/settings/common/types.ts b/chrome/browser/resources/ash/settings/common/types.ts index 46ee940..13176a0 100644 --- a/chrome/browser/resources/ash/settings/common/types.ts +++ b/chrome/browser/resources/ash/settings/common/types.ts
@@ -11,3 +11,6 @@ export interface PrefsState { [key: string]: any; } + +export type UserActionSettingPrefChangeEvent = + CustomEvent<{prefKey: string, value: any}>;
diff --git a/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html b/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html index 2132ed0..1ac1a1f 100644 --- a/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html +++ b/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html
@@ -321,6 +321,14 @@ warning$="[[showRestrictedConnectivity_(managedProperties_, deviceState_)]]" disabled="[[disabled_]]"> + <template is="dom-if" if="[[isApnManaged_(globalPolicy)]]"> + <!-- TODO(b/335486874): Fix tooltip in RTL. --> + <cr-tooltip-icon id="apnManagedIcon" + tooltip-text="$i18n{controlledSettingPolicy}" + icon-class="cr20:domain" + tooltip-position="left"> + </cr-tooltip-icon> + </template> </cr-link-row> </template> </template>
diff --git a/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.ts b/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.ts index db62a93..c212fe7 100644 --- a/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.ts +++ b/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.ts
@@ -8,6 +8,7 @@ * for a network. */ +import 'chrome://resources/ash/common/cr_elements/policy/cr_tooltip_icon.js'; import 'chrome://resources/ash/common/network/cr_policy_network_indicator_mojo.js'; import 'chrome://resources/ash/common/network/network_apnlist.js'; import 'chrome://resources/ash/common/network/network_choose_mobile.js'; @@ -321,6 +322,14 @@ }, }, + isApnPoliciesEnabled_: { + type: Boolean, + value() { + return loadTimeData.valueExists('isApnPoliciesEnabled') && + loadTimeData.getBoolean('isApnPoliciesEnabled'); + }, + }, + passpointSubscription_: { type: Object, notify: true, @@ -408,6 +417,7 @@ private suppressTextMessagesOverride_: boolean; private isCellularCarrierLockEnabled_: boolean; private isPasspointSettingsEnabled_: boolean; + private isApnPoliciesEnabled_: boolean; private isRevampWayfindingEnabled_: boolean; private isSecondaryUser_: boolean; private isTrafficCountersEnabled_: boolean; @@ -1273,6 +1283,16 @@ this.isCellular_(this.managedProperties_); } + private isApnManaged_(globalPolicy: GlobalPolicy|undefined): boolean { + if (!this.isApnPoliciesEnabled_) { + return false; + } + if (!globalPolicy) { + return false; + } + return !globalPolicy.allowApnModification; + } + private shouldShowApnList_(): boolean { return !this.isApnRevampEnabled_ && this.isCellular_(this.managedProperties_);
diff --git a/chrome/browser/resources/ash/settings/os_apps_page/os_apps_page.html b/chrome/browser/resources/ash/settings/os_apps_page/os_apps_page.html index ce62a982..8b0c409 100644 --- a/chrome/browser/resources/ash/settings/os_apps_page/os_apps_page.html +++ b/chrome/browser/resources/ash/settings/os_apps_page/os_apps_page.html
@@ -1,10 +1,12 @@ <style include="settings-shared"> - :host-context(body.revamp-wayfinding-enabled) #androidAppsRowIcon { + :host-context(body.revamp-wayfinding-enabled) #androidAppsRowIcon, + :host-context(body.revamp-wayfinding-enabled) #parentalControlsRowIcon { margin-inline-end: 16px; --iron-icon-fill-color: var(--cros-sys-primary); } - #androidApps[actionable]:hover { + #androidApps[actionable]:hover, + #appParentalControls[actionable]:hover { background-color: var(--cr-hover-background-color); cursor: pointer; } @@ -30,13 +32,41 @@ </cr-link-row> </template> <template is="dom-if" if="[[isAppParentalControlsFeatureAvailable_]]"> - <cr-link-row id="appParentalControlsRow" class="settings-box" - start-icon="[[rowIcons_.manageApps]]" - label="$i18n{appParentalControlsTitle}" - on-click="onClickParentalControls_" - role-description="$i18n{subpageArrowRoleDescription}" - sub-label="$i18n{appParentalControlsSubtitle}"> - </cr-link-row> + <div id="appParentalControls" + class="settings-box" + actionable$="[[prefs.on_device_app_controls.setup_completed.value]]" + on-click="onClickParentalControls_"> + <iron-icon id="parentalControlsRowIcon" + icon="[[rowIcons_.manageApps]]"> + </iron-icon> + <div class="start settings-box-text"> + $i18n{appParentalControlsTitle} + <div class="secondary">$i18n{appParentalControlsSubtitle}</div> + </div> + <template is="dom-if" + if="[[!prefs.on_device_app_controls.setup_completed.value]]"> + <div class="separator"></div> + <cr-button + on-click="setUpParentalControls_" + aria-label="$i18n{appParentalControlsTitle}" + aria-roledescription="$i18n{appParentalControlsSetUpButton}"> + $i18n{appParentalControlsSetUpButton} + </cr-button> + </template> + <template is="dom-if" + if="[[prefs.on_device_app_controls.setup_completed.value]]"> + <cr-icon-button class="subpage-arrow" + aria-label="$i18n{appParentalControlsTitle}" + aria-describedby="secondaryText" + aria-roledescription="$i18n{subpageArrowRoleDescription}"> + </cr-icon-button> + <div class="separator"></div> + <cr-toggle id="toggle" + checked="[[prefs.on_device_app_controls.setup_completed.value]]" + on-change="disableParentalControls_"> + </cr-toggle> + </template> + </div> </template> <template is="dom-if" if="[[showAndroidApps_]]"> <template is="dom-if" if="[[isPlayStoreAvailable_]]" restamp> @@ -68,7 +98,7 @@ </template> <template is="dom-if" if="[[!androidAppsInfo.playStoreEnabled]]"> <div class="separator"></div> - <cr-button id="enable" + <cr-button id="arcEnable" disabled="[[isEnforced_(prefs.arc.enabled)]]" on-click="onEnableAndroidAppsClick_" aria-label="$i18n{androidAppsPageTitle}"
diff --git a/chrome/browser/resources/ash/settings/os_apps_page/os_apps_page.ts b/chrome/browser/resources/ash/settings/os_apps_page/os_apps_page.ts index bf596dd..e0d3583d 100644 --- a/chrome/browser/resources/ash/settings/os_apps_page/os_apps_page.ts +++ b/chrome/browser/resources/ash/settings/os_apps_page/os_apps_page.ts
@@ -327,7 +327,21 @@ } private onClickParentalControls_(): void { - Router.getInstance().navigateTo(routes.APP_PARENTAL_CONTROLS); + const isParentalControlsSetup = + this.getPref('on_device_app_controls.setup_completed').value; + if (isParentalControlsSetup) { + Router.getInstance().navigateTo(routes.APP_PARENTAL_CONTROLS); + } + } + + private setUpParentalControls_(e: Event): void { + this.setPrefValue('on_device_app_controls.setup_completed', true); + // Stop propagation to keep the subpage from opening. + e.stopPropagation(); + } + + private disableParentalControls_(): void { + this.setPrefValue('on_device_app_controls.setup_completed', false); } private onClickManageIsolatedWebApps_(): void {
diff --git a/chrome/browser/resources/ash/settings/os_settings_ui/os_settings_ui.ts b/chrome/browser/resources/ash/settings/os_settings_ui/os_settings_ui.ts index 3d0fdb86..abbe927 100644 --- a/chrome/browser/resources/ash/settings/os_settings_ui/os_settings_ui.ts +++ b/chrome/browser/resources/ash/settings/os_settings_ui/os_settings_ui.ts
@@ -36,6 +36,7 @@ import {setGlobalScrollTarget} from '../common/global_scroll_target_mixin.js'; import {isRevampWayfindingEnabled} from '../common/load_time_booleans.js'; import {RouteObserverMixin} from '../common/route_observer_mixin.js'; +import type {UserActionSettingPrefChangeEvent} from '../common/types.js'; import {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSettingChange, recordSettingChangeForUnmappedPref} from '../metrics_recorder.js'; import {convertPrefToSettingMetric} from '../metrics_utils.js'; import {createPageAvailability, OsPageAvailability} from '../os_page_availability.js'; @@ -58,6 +59,7 @@ 'scroll-to-top': CustomEvent<{top: number, callback: () => void}>; 'user-action-setting-change': CustomEvent<{prefKey: string, prefValue: any}>; + 'user-action-setting-pref-change': UserActionSettingPrefChangeEvent; } } @@ -229,7 +231,10 @@ }); this.addEventListener('refresh-pref', this.onRefreshPref_); - this.addEventListener('user-action-setting-change', this.onSettingChange_); + + this.addEventListener('user-action-setting-pref-change', this.syncPrefChange_.bind(this)); + + this.addEventListener('user-action-setting-change', this.recordChangedSetting_.bind(this)); this.addEventListener( 'search-changed', @@ -395,7 +400,12 @@ this.$.prefs.refresh(e.detail); } - private onSettingChange_(e: CustomEvent<{prefKey: string, prefValue: any}>): + /** + * Callback for the `user-action-setting-change` event which is emitted by + * the `settings-prefs` singleton after a pref-based setting is updated via + * some user action. Records the changed setting to relevant metrics. + */ + private recordChangedSetting_(e: CustomEvent<{prefKey: string, prefValue: any}>): void { const {prefKey, prefValue} = e.detail; const settingMetric = convertPrefToSettingMetric(prefKey, prefValue); @@ -410,6 +420,17 @@ } /** + * Callback for the `user-action-setting-pref-change` event which is emitted + * by settings pref control components when the prefs state should be synced + * after some user action (e.g. a toggle was turned on). Updates the prefs + * state and syncs it with the `settings-prefs` singleton. + */ + private syncPrefChange_(event: UserActionSettingPrefChangeEvent): void { + const {prefKey, value} = event.detail; + this.set(`prefs.${prefKey}.value`, value); + } + + /** * Called when a menu item is selected. */ private onMenuItemSelected_(e: CustomEvent<{selected: string}>): void {
diff --git a/chrome/browser/resources/chromeos/accessibility/common/testing/e2e_test_base.js b/chrome/browser/resources/chromeos/accessibility/common/testing/e2e_test_base.js index a78db52..61e867f 100644 --- a/chrome/browser/resources/chromeos/accessibility/common/testing/e2e_test_base.js +++ b/chrome/browser/resources/chromeos/accessibility/common/testing/e2e_test_base.js
@@ -38,7 +38,7 @@ #include "chrome/common/extensions/extension_constants.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" - #include "extensions/browser/extension_host.h" + #include "extensions/browser/test_extension_console_observer.h" #include "extensions/browser/process_manager.h" `); } @@ -62,7 +62,7 @@ testGenPostamble() { GEN(` if (fail_on_console_error) { - EXPECT_EQ(0u, console_observer.messages().size()) + EXPECT_EQ(0u, console_observer.GetErrorCount()) << "Found console.warn or console.error with message: " << console_observer.GetMessageAt(0); } @@ -76,31 +76,18 @@ GEN(` WaitForExtension(extension_misc::${extensionIdName}, std::move(load_cb)); - extensions::ExtensionHost* host = - extensions::ProcessManager::Get(GetProfile()) - ->GetBackgroundHostForExtension( - extension_misc::${extensionIdName}); - bool fail_on_console_error = ${failOnConsoleError}; // Convert |allowedMessages| into a C++ set. base::flat_set<std::u16string> allowed_messages({${messages}}); - content::WebContentsConsoleObserver console_observer(host->host_contents()); + extensions::TestExtensionConsoleObserver + console_observer(GetProfile(), extension_misc::${extensionIdName}, + fail_on_console_error); // In most cases, A11y extensions should not log warnings or errors. // However, informational messages may be logged in some cases and should // be specified in |allowed_messages|. All other messages should cause test // failures. - auto filter = - [](const base::flat_set<std::u16string>& allowed, - const content::WebContentsConsoleObserver::Message& message) { - if (allowed.contains(message.message)) - return false; - - return message.log_level == - blink::mojom::ConsoleMessageLevel::kWarning || - message.log_level == blink::mojom::ConsoleMessageLevel::kError; - }; if (fail_on_console_error) { - console_observer.SetFilter(base::BindRepeating(filter, allowed_messages)); + console_observer.SetAllowedErrorMessages(allowed_messages); } `); }
diff --git a/chrome/browser/resources/commerce/product_specifications/BUILD.gn b/chrome/browser/resources/commerce/product_specifications/BUILD.gn index 40ea30c2..663574e 100644 --- a/chrome/browser/resources/commerce/product_specifications/BUILD.gn +++ b/chrome/browser/resources/commerce/product_specifications/BUILD.gn
@@ -12,6 +12,7 @@ # Files holding a Polymer element definition and have an equivalent .html file. web_component_files = [ "app.ts", + "product_selector.ts", "table.ts", ] @@ -22,6 +23,7 @@ "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_components/color_change_listener:build_ts", "//ui/webui/resources/cr_components/commerce:build_ts", + "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", "//ui/webui/resources/mojo:build_ts", ]
diff --git a/chrome/browser/resources/commerce/product_specifications/app.ts b/chrome/browser/resources/commerce/product_specifications/app.ts index 3c69745..9a97842 100644 --- a/chrome/browser/resources/commerce/product_specifications/app.ts +++ b/chrome/browser/resources/commerce/product_specifications/app.ts
@@ -3,6 +3,7 @@ // found in the LICENSE file. import '../strings.m.js'; +import './product_selector.js'; import './table.js'; import {ColorChangeUpdater} from 'chrome://resources/cr_components/color_change_listener/colors_css_updater.js'; @@ -74,7 +75,7 @@ this.specsTable_ = { columns: productSpecs.products.map(p => { return { - title: p.title, + selectedItem: {title: p.title, url: '', imageUrl: p.imageUrl.url}, }; }), rows,
diff --git a/chrome/browser/resources/commerce/product_specifications/product_selector.html b/chrome/browser/resources/commerce/product_specifications/product_selector.html new file mode 100644 index 0000000..43e95cf --- /dev/null +++ b/chrome/browser/resources/commerce/product_specifications/product_selector.html
@@ -0,0 +1,61 @@ +<style include="cr-shared-style"> + :host { + --product-selector-width: 250px; + } + + #currentProductContainer, + #selectionContainer { + box-sizing: border-box; + display: block; + overflow: clip; + width: var(--product-selector-width); + } + + #currentProductContainer { + border-radius: 10px; + height: 50px; + } + + #selectionContainer { + padding: 0 8px; + } + + cr-action-menu { + --cr-menu-border-radius: 10px; + } + + #currentItemButton { + --cr-section-vertical-padding: 0; + } +</style> + +<div id="currentProductContainer"> + <cr-expand-button id="currentItemButton" on-click="onShowMenu" no-hover> + <cr-url-list-item id="currentProduct" size="medium" + url="[[selectedItem.url]]" title="[[selectedItem.title]]" + description="[[selectedItem.url]]" no-hover> + </cr-url-list-item> + </cr-expand-button> +</div> + +<cr-lazy-render id="productSelectionMenu"> + <template> + <cr-action-menu> + <div id="selectionContainer"> + <template is="dom-if" if="[[openTabs.length]]" restamp> + <cr-expand-button expanded="{{openTabsExpanded}}" no-hover> + $i18n{openTabsSectionTitle} + </cr-expand-button> + <iron-collapse opened="[[openTabsExpanded]]"> + <template is="dom-repeat" items="[[openTabs]]"> + <cr-url-list-item class="dropdown-item" size="medium" + url="[[item.url]]" title="[[item.title]]" + description="[[item.url]]" no-hover> + </cr-url-list-item> + </template> + </iron-collapse> + </template> + </div> + </cr-action-menu> + </template> +</cr-lazy-render>
diff --git a/chrome/browser/resources/commerce/product_specifications/product_selector.ts b/chrome/browser/resources/commerce/product_specifications/product_selector.ts new file mode 100644 index 0000000..33ef74c9 --- /dev/null +++ b/chrome/browser/resources/commerce/product_specifications/product_selector.ts
@@ -0,0 +1,92 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js'; +import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.js'; +import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js'; +import 'chrome://resources/cr_elements/cr_shared_style.css.js'; +import 'chrome://resources/cr_elements/cr_url_list_item/cr_url_list_item.js'; +import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js'; + +import type {BrowserProxy} from 'chrome://resources/cr_components/commerce/browser_proxy.js'; +import {BrowserProxyImpl} from 'chrome://resources/cr_components/commerce/browser_proxy.js'; +import {AnchorAlignment} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js'; +import type {CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js'; +import type {CrExpandButtonElement} from 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.js'; +import type {CrLazyRenderElement} from 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js'; +import type {CrUrlListItemElement} from 'chrome://resources/cr_elements/cr_url_list_item/cr_url_list_item.js'; +import {mojoString16ToString} from 'chrome://resources/js/mojo_type_util.js'; +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {getTemplate} from './product_selector.html.js'; + +export interface UrlListEntry { + title: string; + url: string; + imageUrl: string; +} + +export interface ProductSelectorElement { + $: { + currentItemButton: CrExpandButtonElement, + currentProduct: CrUrlListItemElement, + currentProductContainer: HTMLElement, + productSelectionMenu: CrLazyRenderElement<CrActionMenuElement>, + }; +} + +export class ProductSelectorElement extends PolymerElement { + static get is() { + return 'product-selector'; + } + + static get template() { + return getTemplate(); + } + + static get properties() { + return { + selectedItem: Object, + openTabs: { + type: Array, + value: () => [], + }, + openTabsExpanded: { + type: Boolean, + value: true, + }, + }; + } + + private shoppingApi_: BrowserProxy = BrowserProxyImpl.getInstance(); + + selectedItem: UrlListEntry; + openTabs: UrlListEntry[]; + + private openTabsExpanded: boolean; + + private async onShowMenu() { + const {urlInfos} = await this.shoppingApi_.getUrlInfosForOpenTabs(); + this.openTabs = urlInfos.map(({title, url}) => ({ + title: mojoString16ToString(title), + url: url.url, + imageUrl: url.url, + })); + + const rect = this.$.currentProductContainer.getBoundingClientRect(); + this.$.productSelectionMenu.get().showAt(this.$.currentProductContainer, { + anchorAlignmentX: AnchorAlignment.CENTER, + top: rect.bottom, + left: rect.left, + }); + } +} + +declare global { + interface HTMLElementTagNameMap { + 'product-selector': ProductSelectorElement; + } +} + +customElements.define(ProductSelectorElement.is, ProductSelectorElement);
diff --git a/chrome/browser/resources/commerce/product_specifications/table.html b/chrome/browser/resources/commerce/product_specifications/table.html index 7ff3002..7534fb0 100644 --- a/chrome/browser/resources/commerce/product_specifications/table.html +++ b/chrome/browser/resources/commerce/product_specifications/table.html
@@ -4,6 +4,7 @@ } .col { width: 220px; + text-align: start; } .col-card { display: flex; @@ -16,11 +17,13 @@ padding-bottom: 24px; } </style> + <table> <thead> <template is="dom-repeat" items="[[columns]]" as="column"> <th class="col"> - <div class="col-card">[[column.title]]</div> + <product-selector selected-item="[[column.selectedItem]]"> + </product-selector> </th> </template> </thead>
diff --git a/chrome/browser/resources/commerce/product_specifications/table.ts b/chrome/browser/resources/commerce/product_specifications/table.ts index c2ed1832..86c4acf6 100644 --- a/chrome/browser/resources/commerce/product_specifications/table.ts +++ b/chrome/browser/resources/commerce/product_specifications/table.ts
@@ -4,6 +4,7 @@ import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import type {UrlListEntry} from './product_selector.js'; import {getTemplate} from './table.html.js'; /** Describes a row in a ProductSpecs table. */ @@ -13,7 +14,7 @@ } /** Describes a column in a ProductSpecs table. */ export interface TableColumn { - title: string; + selectedItem: UrlListEntry; } /** Element for rendering a ProductSpecs table. */
diff --git a/chrome/browser/resources/compose/app.html b/chrome/browser/resources/compose/app.html index 3733c95..5457fc1 100644 --- a/chrome/browser/resources/compose/app.html +++ b/chrome/browser/resources/compose/app.html
@@ -199,7 +199,7 @@ border-bottom: solid 1px var(--color-compose-dialog-divider); } - :host(:not([enable-ui-refinements])) :host([loading-indicator-shown_]) #body { + :host(:not([enable-ui-refinements])[loading-indicator-shown_]) #body { /* When loading, the heights of contents within #body are in flux due to * animations. Force the entire #body to be visible to prevent scrollbars * from flickering, and remove scrollbar width from padding. */
diff --git a/chrome/browser/resources/downloads/icons.html b/chrome/browser/resources/downloads/icons.html index 1232f1aa..ad3f0bb6 100644 --- a/chrome/browser/resources/downloads/icons.html +++ b/chrome/browser/resources/downloads/icons.html
@@ -10,6 +10,10 @@ d="M 8.25 21 L 3 15.75 L 3 8.25 L 8.25 3 L 15.75 3 L 21 8.25 L 21 15.75 L 15.75 21 Z M 9.148438 16.25 L 12 13.398438 L 14.851562 16.25 L 16.25 14.851562 L 13.398438 12 L 16.25 9.148438 L 14.851562 7.75 L 12 10.601562 L 9.148438 7.75 L 7.75 9.148438 L 10.601562 12 L 7.75 14.851562 Z M 9.148438 16.25"> </path> </g> + <g id="shield"> + <path fill="#0b57d0" fill-opacity="1" fill-rule="nonzero" d="M12 22.210938c-2.375-.597657-4.335938-1.949219-5.882812-4.066407-1.546876-2.113281-2.320313-4.460937-2.320313-7.042969V4.859375L12 1.789062l8.203125 3.070313v6.242187c0 2.582032-.773437 4.929688-2.320313 7.042969C16.335938 20.261719 14.375 21.613281 12 22.210938Zm0-2.375c1.589844-.527344 2.917969-1.511719 3.992188-2.964844C17.066406 15.421875 17.695312 13.796875 17.878906 12H12V4.207031L6.070312 6.433594v5.117187c0 .125.019532.273438.050782.449219H12Zm0 0"> + </path> + </g> </defs> </svg> </iron-iconset-svg>
diff --git a/chrome/browser/resources/downloads/item.html b/chrome/browser/resources/downloads/item.html index a11b9cef..a5491fb 100644 --- a/chrome/browser/resources/downloads/item.html +++ b/chrome/browser/resources/downloads/item.html
@@ -604,7 +604,7 @@ <!-- TODO(crbug.com/333734490): Replace icon with branded gshield icon. --> <cr-link-row id="esb-download-row-promo" - start-icon="downloads:dangerous" + start-icon="downloads:shield" external on-click="onEsbPromotionClick_" button-aria-description="$i18n{esbDownloadRowPromoA11y}"
diff --git a/chrome/browser/resources/history/BUILD.gn b/chrome/browser/resources/history/BUILD.gn index 82a5cc89..be60413 100644 --- a/chrome/browser/resources/history/BUILD.gn +++ b/chrome/browser/resources/history/BUILD.gn
@@ -55,6 +55,7 @@ ts_deps = [ "//third_party/polymer/v3_0:library", + "//ui/webui/resources/cr_components/history:build_ts", "//ui/webui/resources/cr_components/history_clusters:build_ts", "//ui/webui/resources/cr_components/history_embeddings:build_ts", "//ui/webui/resources/cr_components/managed_footnote:build_ts",
diff --git a/chrome/browser/resources/history/app.ts b/chrome/browser/resources/history/app.ts index 14de854..c260f67 100644 --- a/chrome/browser/resources/history/app.ts +++ b/chrome/browser/resources/history/app.ts
@@ -19,8 +19,9 @@ import './side_bar.js'; import './strings.m.js'; -import type {HistoryEmbeddingsMoreActionsClickEvent} from 'chrome://resources/cr_components/history_embeddings/history_embeddings.js'; +import {HistoryResultType} from 'chrome://resources/cr_components/history/constants.js'; import type {Suggestion} from 'chrome://resources/cr_components/history_embeddings/filter_chips.js'; +import type {HistoryEmbeddingsMoreActionsClickEvent} from 'chrome://resources/cr_components/history_embeddings/history_embeddings.js'; import type {CrDrawerElement} from 'chrome://resources/cr_elements/cr_drawer/cr_drawer.js'; import type {CrLazyRenderElement} from 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js'; import type {FindShortcutMixinInterface} from 'chrome://resources/cr_elements/find_shortcut_mixin.js'; @@ -290,6 +291,9 @@ document, 'keydown', (e: Event) => this.onKeyDown_(e as KeyboardEvent)); this.eventTracker_.add( document, 'visibilitychange', this.onVisibilityChange_.bind(this)); + this.eventTracker_.add( + document, 'record-history-link-click', + this.onRecordHistoryLinkClick_.bind(this)); this.addWebUiListener( 'sign-in-state-changed', (signedIn: boolean) => this.onSignInStateChanged_(signedIn)); @@ -462,6 +466,48 @@ } } + private onRecordHistoryLinkClick_( + e: CustomEvent<{resultType: HistoryResultType, index: number}>) { + // All of the above code only applies to History search results, not the + // zero-query state. Check queryResult_ instead of queryState_ to key on + // actually displayed results rather than the latest user input, which may + // not have finished loading yet. + if (!this.queryResult_.info || !this.queryResult_.info.term) { + return; + } + + this.browserService_!.recordHistogram( + 'History.SearchResultClicked.Type', e.detail.resultType, + HistoryResultType.END); + + // MetricsHandler uses a 100 bucket limit, so the max index is 99. + const maxIndex = 99; + const clampedIndex = Math.min(e.detail.index, 99); + this.browserService_!.recordHistogram( + 'History.SearchResultClicked.Index', clampedIndex, maxIndex); + + switch (e.detail.resultType) { + case HistoryResultType.TRADITIONAL: { + this.browserService_!.recordHistogram( + 'History.SearchResultClicked.Index.Traditional', clampedIndex, + maxIndex); + break; + } + case HistoryResultType.GROUPED: { + this.browserService_!.recordHistogram( + 'History.SearchResultClicked.Index.Grouped', clampedIndex, + maxIndex); + break; + } + case HistoryResultType.EMBEDDINGS: { + this.browserService_!.recordHistogram( + 'History.SearchResultClicked.Index.Embeddings', clampedIndex, + maxIndex); + break; + } + } + } + private onDeleteCommand_() { if (this.$.toolbar.count === 0 || this.pendingDelete_) { return;
diff --git a/chrome/browser/resources/history/history_item.html b/chrome/browser/resources/history/history_item.html index b2aeff133..1fd97b3c 100644 --- a/chrome/browser/resources/history/history_item.html +++ b/chrome/browser/resources/history/history_item.html
@@ -220,7 +220,7 @@ <a href="[[item.url]]" id="link" class="website-link" focus-row-control focus-type="link" title="[[item.title]]" on-click="onLinkClick_" - on-contextmenu="onLinkRightClick_" + on-auxclick="onLinkClick_" on-contextmenu="onLinkRightClick_" aria-describedby$="[[ariaDescribedByForHeading_]]"> <div class="website-icon" id="icon"></div> <history-searched-label class="website-title"
diff --git a/chrome/browser/resources/history/history_item.ts b/chrome/browser/resources/history/history_item.ts index f618a26..c1c2c47 100644 --- a/chrome/browser/resources/history/history_item.ts +++ b/chrome/browser/resources/history/history_item.ts
@@ -10,6 +10,7 @@ import 'chrome://resources/js/icon.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; +import {HistoryResultType} from 'chrome://resources/cr_components/history/constants.js'; import type {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.js'; import type {CrIconButtonElement} from 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js'; import {FocusRowMixin} from 'chrome://resources/cr_elements/focus_row_mixin.js'; @@ -308,6 +309,11 @@ if (this.searchTerm) { browserService.recordAction('SearchResultClick'); } + + this.fire_('record-history-link-click', { + resultType: HistoryResultType.TRADITIONAL, + index: this.index, + }); } private onLinkRightClick_() {
diff --git a/chrome/browser/resources/side_panel/customize_chrome/categories.html b/chrome/browser/resources/side_panel/customize_chrome/categories.html index bcfa79f3..9a420c5 100644 --- a/chrome/browser/resources/side_panel/customize_chrome/categories.html +++ b/chrome/browser/resources/side_panel/customize_chrome/categories.html
@@ -232,7 +232,7 @@ <customize-chrome-check-mark-wrapper checked="[[isClassicChromeSelected_]]"> <div id="cornerNewTabPageTile" class="image-container"> - <img id="cornerNewTabPage" src="icons/gm3_corner_new_tab_page.svg"> + <img id="cornerNewTabPage" src="icons/corner_new_tab_page.svg"> </div> </customize-chrome-check-mark-wrapper> <div class="label">$i18n{classicChrome}</div>
diff --git a/chrome/browser/resources/side_panel/customize_chrome/icons/BUILD.gn b/chrome/browser/resources/side_panel/customize_chrome/icons/BUILD.gn index 260c2c6..5d22040 100644 --- a/chrome/browser/resources/side_panel/customize_chrome/icons/BUILD.gn +++ b/chrome/browser/resources/side_panel/customize_chrome/icons/BUILD.gn
@@ -10,20 +10,20 @@ grd_prefix = "side_panel_customize_chrome" out_grd = "$target_gen_dir/resources.grdp" input_files = [ - "collapse_carets.svg", "chrome_web_store.svg", + "collapse_carets.svg", + "corner_new_tab_page.svg", "coupons.svg", "delete.svg", "expand_carets.svg", "generated_image.svg", - "gm3_corner_new_tab_page.svg", - "gm3_mini_new_tab_page.svg", "image.svg", + "mini_new_tab_page.svg", "productivity.svg", "reset.svg", "sparkle.svg", - "upload.svg", "uploaded_image.svg", + "upload.svg", "writing.svg", ] input_files_base_dir = rebase_path(".", "//")
diff --git a/chrome/browser/resources/side_panel/customize_chrome/icons/gm3_corner_new_tab_page.svg b/chrome/browser/resources/side_panel/customize_chrome/icons/corner_new_tab_page.svg similarity index 100% rename from chrome/browser/resources/side_panel/customize_chrome/icons/gm3_corner_new_tab_page.svg rename to chrome/browser/resources/side_panel/customize_chrome/icons/corner_new_tab_page.svg
diff --git a/chrome/browser/resources/side_panel/customize_chrome/icons/gm3_mini_new_tab_page.svg b/chrome/browser/resources/side_panel/customize_chrome/icons/mini_new_tab_page.svg similarity index 100% rename from chrome/browser/resources/side_panel/customize_chrome/icons/gm3_mini_new_tab_page.svg rename to chrome/browser/resources/side_panel/customize_chrome/icons/mini_new_tab_page.svg
diff --git a/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.html b/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.html index c767e6b2..7a415e04 100644 --- a/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.html +++ b/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.html
@@ -30,7 +30,7 @@ justify-content: center; } - #gm3MiniNewTabPage { + #miniNewTabPage { height: auto; width: 100%; } @@ -107,9 +107,9 @@ <div class="image-background image" id="classicChromeBackground" on-click="onThemeSnapshotClick_"> - <svg id="gm3MiniNewTabPage" aria-labelledby="classicChromeThemeTitle" + <svg id="miniNewTabPage" aria-labelledby="classicChromeThemeTitle" viewBox="0 0 240 126" preserveAspectRatio="xMidYMid meet"> - <use href="icons/gm3_mini_new_tab_page.svg#miniNewTabPage"></use> + <use href="icons/mini_new_tab_page.svg#miniNewTabPage"></use> </svg> <div class="overlay"></div> <cr-ripple></cr-ripple>
diff --git a/chrome/browser/resources/side_panel/read_anything/voice_selection_menu.html b/chrome/browser/resources/side_panel/read_anything/voice_selection_menu.html index 0d4299b..d727e06 100644 --- a/chrome/browser/resources/side_panel/read_anything/voice_selection_menu.html +++ b/chrome/browser/resources/side_panel/read_anything/voice_selection_menu.html
@@ -35,7 +35,7 @@ } .dropdown-voice-selection-button:hover { background-color: var(--cr-hover-background-color); - cursor:pointer; + cursor: pointer; } .dropdown-voice-selection-button:focus-visible { background-color: var(--cr-hover-background-color); @@ -92,14 +92,14 @@ icon="read-anything-20:check-mark"></cr-icon> [[item.title]] </span> - <!-- TODO(b/333958820): Ensure keyboard focus is handled correctly - when the play button is pressed. --> - <cr-icon-button id="play-icon" on-click="onVoicePreviewClick_" - title="$i18n{playLabel}" - disabled$="[[item.previewPlaying]]" - aria-label="$i18n{playLabel} [[item.title]]" - iron-icon="read-anything-20:play-circle"></cr-icon-button> + <cr-icon-button id="preview-icon" on-click="onVoicePreviewClick_" + title$="[[previewLabel_(item.previewPlaying,'')]]" + aria-label$="[[previewLabel_(item.previewPlaying,item.title)]]" + iron-icon="[[previewIcon_(item.previewPlaying)]]"> + </cr-icon-button> </button> + <!-- TODO(crbug.com/1474951) Pause the preview when pause button is + pressed --> </template> </div> </template>
diff --git a/chrome/browser/resources/side_panel/read_anything/voice_selection_menu.ts b/chrome/browser/resources/side_panel/read_anything/voice_selection_menu.ts index af5b13e..442066e6 100644 --- a/chrome/browser/resources/side_panel/read_anything/voice_selection_menu.ts +++ b/chrome/browser/resources/side_panel/read_anything/voice_selection_menu.ts
@@ -14,6 +14,7 @@ import type {CrLazyRenderElement} from '//resources/cr_elements/cr_lazy_render/cr_lazy_render.js'; import {WebUiListenerMixin} from '//resources/cr_elements/web_ui_listener_mixin.js'; import {assert} from '//resources/js/assert.js'; +import {loadTimeData} from '//resources/js/load_time_data.js'; import type {DomRepeatEvent} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -152,14 +153,19 @@ // line is to make sure that the voice-selection callback is not triggered. event.stopImmediatePropagation(); - const previewVoice = event.model.item.voice; - this.dispatchEvent(new CustomEvent('preview-voice', { - bubbles: true, - composed: true, - detail: { - previewVoice, - }, - })); + const button = event.target as HTMLElement; + assert(button, 'no target for preview'); + + if (!event.model.item.previewPlaying) { + const previewVoice = event.model.item.voice; + this.dispatchEvent(new CustomEvent('preview-voice', { + bubbles: true, + composed: true, + detail: { + previewVoice, + }, + })); + } } private onClose_() { @@ -179,10 +185,9 @@ (currentElement.classList.contains('dropdown-voice-selection-button')) ? true : false; - const targetIsPreviewButton = (currentElement.id === 'play-icon' || - currentElement.id === 'pause-icon') ? - true : - false; + const targetIsPreviewButton = + (currentElement.id === 'preview-icon') ? true : false; + // For voice options, only handle the right arrow - everything else is // default if (targetIsVoiceOption && !['ArrowRight'].includes(e.key)) { @@ -193,6 +198,7 @@ !['ArrowLeft', 'ArrowUp', 'ArrowDown'].includes(e.key)) { return; } + // When the menu first opens, the target is the whole menu. // In that case, use default behavior. if (!targetIsVoiceOption && !targetIsPreviewButton) return; @@ -200,16 +206,36 @@ e.preventDefault(); if (targetIsVoiceOption) { - // From a voice option, go to whichever preview button is visible - // There are 'play-icon' and 'pause-icon' preview buttons, and - // only one is visible at a time. The one that's visible has style - // display-true, so use that to directly select the right button + // From a voice option, go to its preview button const visiblePreviewButton = - currentElement.querySelector<HTMLElement>('#play-icon'); + currentElement.querySelector<HTMLElement>('#preview-icon'); assert(visiblePreviewButton, 'can\'t find preview button'); visiblePreviewButton!.focus(); - } else { // Voice preview button - go to voice entry - currentElement.parentElement!.focus(); + } + // This action is also handled by the menu itself + // For left arrow, this takes us to the voice being previewed, + // For up and down arrows this is combined with the default up/down + // action, taking us to the next or previous voice. + currentElement.parentElement!.focus(); + } + + private previewLabel_(previewPlaying: boolean, voiceName: string): string { + let nameSuffix = ''; + if (voiceName.length > 0) { + nameSuffix = ' ' + voiceName; + } + if (previewPlaying) { + return loadTimeData.getString('pauseLabel') + nameSuffix; + } else { + return loadTimeData.getString('playLabel') + nameSuffix; + } + } + + private previewIcon_(previewPlaying: boolean): string { + if (previewPlaying) { + return 'read-anything-20:pause-circle'; + } else { + return 'read-anything-20:play-circle'; } } }
diff --git a/chrome/browser/resources/welcome/BUILD.gn b/chrome/browser/resources/welcome/BUILD.gn index 350a7df..d26bff9 100644 --- a/chrome/browser/resources/welcome/BUILD.gn +++ b/chrome/browser/resources/welcome/BUILD.gn
@@ -58,9 +58,6 @@ extra_grdp_files = [ "$target_gen_dir/icon_resources.grdp" ] } - # Files holding a Polymer element definition AND have an equivalent .html file. - web_component_files = [ "set_as_default/nux_set_as_default.ts" ] - non_web_component_files = [ "landing_view.html.ts", "landing_view_proxy.ts", @@ -82,7 +79,9 @@ "ntp_background/ntp_background_proxy.ts", "ntp_background/nux_ntp_background.html.ts", "ntp_background/nux_ntp_background.ts", + "set_as_default/nux_set_as_default.html.ts", "set_as_default/nux_set_as_default_proxy.ts", + "set_as_default/nux_set_as_default.ts", "shared/bookmark_proxy.ts", "shared/module_metrics_proxy.ts", "shared/nux_types.ts",
diff --git a/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html b/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html deleted file mode 100644 index 407c48c..0000000 --- a/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html +++ /dev/null
@@ -1,19 +0,0 @@ -<div class="container"> - <h1 tabindex="-1">${this.subtitle}</h1> - <h2>$i18n{setDefaultSubHeader}</h2> - <div class="illustration slide-in" aria-hidden="true"></div> - <div class="button-bar"> - <cr-button id="declineButton" @click="${this.onDeclineClick_}"> - $i18n{skip} - </cr-button> - <step-indicator .model="${this.indicatorModel}"></step-indicator> - <cr-button class="action-button" @click="${this.onSetDefaultClick_}"> - $i18n{setDefaultConfirm} -<if expr="is_win"> - <iron-icon icon="cr:open-in-new" slot="suffix-icon" - ?hidden="${!this.isWin10_}"> - </iron-icon> -</if> - </cr-button> - </div> -</div>
diff --git a/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html.ts b/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html.ts new file mode 100644 index 0000000..487aa83 --- /dev/null +++ b/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.html.ts
@@ -0,0 +1,30 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {html} from '//resources/lit/v3_0/lit.rollup.js'; +import type {NuxSetAsDefaultElement} from './nux_set_as_default.js'; + +export function getHtml(this: NuxSetAsDefaultElement) { + return html`<!--_html_template_start_--> +<div class="container"> + <h1 tabindex="-1">${this.subtitle}</h1> + <h2>$i18n{setDefaultSubHeader}</h2> + <div class="illustration slide-in" aria-hidden="true"></div> + <div class="button-bar"> + <cr-button id="declineButton" @click="${this.onDeclineClick_}"> + $i18n{skip} + </cr-button> + <step-indicator .model="${this.indicatorModel}"></step-indicator> + <cr-button class="action-button" @click="${this.onSetDefaultClick_}"> + $i18n{setDefaultConfirm} +<if expr="is_win"> + <iron-icon icon="cr:open-in-new" slot="suffix-icon" + ?hidden="${!this.isWin10_}"> + </iron-icon> +</if> + </cr-button> + </div> +</div> +<!--_html_template_end_-->`; +}
diff --git a/chrome/browser/search_engine_choice/search_engine_choice_dialog_browsertest.cc b/chrome/browser/search_engine_choice/search_engine_choice_dialog_browsertest.cc index 000189a..8e2f88a 100644 --- a/chrome/browser/search_engine_choice/search_engine_choice_dialog_browsertest.cc +++ b/chrome/browser/search_engine_choice/search_engine_choice_dialog_browsertest.cc
@@ -28,6 +28,7 @@ #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/ui/webui/ntp/new_tab_ui.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/common/chrome_constants.h" @@ -270,6 +271,7 @@ } private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; base::AutoReset<bool> scoped_chrome_build_override_ = SearchEngineChoiceDialogServiceFactory:: ScopedChromeBuildOverrideForTesting(
diff --git a/chrome/browser/segmentation_platform/segmentation_platform_config.cc b/chrome/browser/segmentation_platform/segmentation_platform_config.cc index fd89c4e..c8529e6 100644 --- a/chrome/browser/segmentation_platform/segmentation_platform_config.cc +++ b/chrome/browser/segmentation_platform/segmentation_platform_config.cc
@@ -165,6 +165,7 @@ configs.emplace_back(TabletProductivityUserModel::GetConfig()); configs.emplace_back(MostVisitedTilesUser::GetConfig()); configs.emplace_back(AndroidHomeModuleRanker::GetConfig()); + configs.emplace_back(GetConfigForWebAppInstallationPromo()); #endif configs.emplace_back(LowUserEngagementModel::GetConfig()); configs.emplace_back(SearchUserModel::GetConfig()); @@ -181,9 +182,7 @@ configs.emplace_back(OptimizationTargetSegmentationDummy::GetConfig()); if (base::FeatureList::IsEnabled( - webapps::features::kWebAppsEnableMLModelForPromotion) || - base::FeatureList::IsEnabled( - webapps::features::kInstallPromptSegmentation)) { + webapps::features::kWebAppsEnableMLModelForPromotion)) { configs.emplace_back(GetConfigForWebAppInstallationPromo()); } if (base::FeatureList::IsEnabled(ntp_features::kNtpDriveModuleSegmentation)) {
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index bf8b725..5b335c9 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -69,6 +69,7 @@ #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_tab_helper.h" @@ -3424,6 +3425,9 @@ web_app_info->tab_strip = std::move(tab_strip); return web_app::test::InstallWebApp(profile, std::move(web_app_info)); } + + private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; }; // This is disabled on mac pending http://crbug.com/1194201
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/scroll_capture/ScrollCaptureCallbackRenderTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/scroll_capture/ScrollCaptureCallbackRenderTest.java index 4fff254..e50021cd 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/scroll_capture/ScrollCaptureCallbackRenderTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/scroll_capture/ScrollCaptureCallbackRenderTest.java
@@ -39,8 +39,6 @@ import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.Features.DisableFeatures; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -116,8 +114,6 @@ @Test @LargeTest @Feature({"RenderTest"}) - // TODO(crbug.com/1453741): Fix test with CREATE_NEW_TAB_INITIALIZE_RENDERER. - @DisableFeatures(ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER) public void testCaptureTop() throws Exception { View view = mTab.getView(); Size size = new Size(view.getWidth(), view.getHeight()); @@ -131,8 +127,6 @@ @Test @LargeTest @Feature({"RenderTest"}) - // TODO(crbug.com/1453741): Fix test with CREATE_NEW_TAB_INITIALIZE_RENDERER. - @DisableFeatures(ChromeFeatureList.CREATE_NEW_TAB_INITIALIZE_RENDERER) public void testCaptureBottom() throws Exception { RenderCoordinates renderCoordinates = RenderCoordinates.fromWebContents(mTab.getWebContents());
diff --git a/chrome/browser/shortcuts/BUILD.gn b/chrome/browser/shortcuts/BUILD.gn index 805fad0..578a615 100644 --- a/chrome/browser/shortcuts/BUILD.gn +++ b/chrome/browser/shortcuts/BUILD.gn
@@ -9,13 +9,44 @@ source_set("shortcuts") { sources = [ "create_shortcut_for_current_web_contents_task.h", + "document_icon_fetcher.cc", + "document_icon_fetcher.h", + "fetch_icons_from_document_task.cc", + "fetch_icons_from_document_task.h", "platform_util_mac.h", "platform_util_mac.mm", ] deps = [ "//base", + "//components/webapps/common", + "//components/webapps/common:mojo_bindings", "//content/public/browser", + "//mojo/public/cpp/bindings", + "//skia", + "//third_party/blink/public/common", + "//ui/gfx", + "//url", + ] +} + +source_set("browser_tests") { + testonly = true + + sources = [ "document_icon_fetcher_browsertest.cc" ] + + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] + + deps = [ + ":shortcuts", + "//base", + "//chrome/browser/ui:ui", + "//chrome/test:test_support_ui", + "//content/public/browser", + "//skia", + "//testing/gtest:gtest", + "//ui/gfx:test_support", + "//url", ] }
diff --git a/chrome/browser/shortcuts/document_icon_fetcher.cc b/chrome/browser/shortcuts/document_icon_fetcher.cc new file mode 100644 index 0000000..9ae1be2 --- /dev/null +++ b/chrome/browser/shortcuts/document_icon_fetcher.cc
@@ -0,0 +1,81 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/shortcuts/document_icon_fetcher.h" + +#include <iterator> +#include <memory> + +#include "base/containers/flat_map.h" +#include "base/functional/bind.h" +#include "base/functional/callback.h" +#include "base/functional/callback_forward.h" +#include "base/location.h" +#include "base/memory/weak_ptr.h" +#include "base/task/sequenced_task_runner.h" +#include "base/types/expected.h" +#include "base/types/pass_key.h" +#include "chrome/browser/shortcuts/fetch_icons_from_document_task.h" +#include "content/public/browser/document_user_data.h" +#include "content/public/browser/web_contents.h" +#include "third_party/skia/include/core/SkBitmap.h" + +namespace shortcuts { + +// static +void DocumentIconFetcher::FetchIcons(content::WebContents& web_contents, + FetchIconsFromDocumentCallback callback) { + DocumentIconFetcher* fetch_manager = + DocumentIconFetcher::GetOrCreateForCurrentDocument( + web_contents.GetPrimaryMainFrame()); + fetch_manager->RunTask(std::move(callback)); +} + +DocumentIconFetcher::~DocumentIconFetcher() { + in_destruction_ = true; + // All of the tasks callbacks call `DocumentIconFetcher::OnTaskComplete` below + // directly. Save them & call them synchronously after the tasks are + // destroyed to prevent map modification during iteration. + std::vector<FetchIconsFromDocumentCallback> pending_callbacks; + for (const auto& [id, task] : fetch_tasks_) { + pending_callbacks.push_back(task->TakeCallback()); + } + fetch_tasks_.clear(); + for (FetchIconsFromDocumentCallback& callback : pending_callbacks) { + CHECK(callback); + // This calls `DocumentIconFetcher::OnTaskComplete` below. + std::move(callback).Run( + base::unexpected(FetchIconsForDocumentError::kDocumentDestroyed)); + } +} + +DOCUMENT_USER_DATA_KEY_IMPL(DocumentIconFetcher); + +DocumentIconFetcher::DocumentIconFetcher(content::RenderFrameHost* rfh) + : content::DocumentUserData<DocumentIconFetcher>(rfh) {} + +void DocumentIconFetcher::RunTask(FetchIconsFromDocumentCallback callback) { + std::unique_ptr<FetchIconsFromDocumentTask> task = + std::make_unique<FetchIconsFromDocumentTask>( + base::PassKey<DocumentIconFetcher>(), render_frame_host()); + int task_id = next_task_id_; + next_task_id_++; + const auto& [iter, _] = fetch_tasks_.emplace(task_id, std::move(task)); + // Note: the callback may be called synchronously. + iter->second->Start(base::BindOnce(&DocumentIconFetcher::OnTaskComplete, + weak_factory_.GetWeakPtr(), task_id, + std::move(callback))); +} + +void DocumentIconFetcher::OnTaskComplete( + int id, + FetchIconsFromDocumentCallback original_callback, + FetchIconsFromDocumentResult result) { + int num_erased = fetch_tasks_.erase(id); + CHECK(num_erased > 0 || in_destruction_); + base::SequencedTaskRunner::GetCurrentDefault()->PostTask( + FROM_HERE, base::BindOnce(std::move(original_callback), result)); +} + +} // namespace shortcuts
diff --git a/chrome/browser/shortcuts/document_icon_fetcher.h b/chrome/browser/shortcuts/document_icon_fetcher.h new file mode 100644 index 0000000..f057bbe --- /dev/null +++ b/chrome/browser/shortcuts/document_icon_fetcher.h
@@ -0,0 +1,56 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SHORTCUTS_DOCUMENT_ICON_FETCHER_H_ +#define CHROME_BROWSER_SHORTCUTS_DOCUMENT_ICON_FETCHER_H_ + +#include <memory> + +#include "base/containers/flat_map.h" +#include "base/functional/callback_forward.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/shortcuts/fetch_icons_from_document_task.h" +#include "content/public/browser/document_user_data.h" + +namespace content { +class WebContents; +} + +namespace shortcuts { + +// This object is responsible for fetching all available icons from a given +// document. +class DocumentIconFetcher + : public content::DocumentUserData<DocumentIconFetcher> { + public: + // Fetches all icons for the top level primary frame of the given web + // contents. `callback` will always be called (even on document destruction), + // and always called asynchronously. + static void FetchIcons(content::WebContents& web_contents, + FetchIconsFromDocumentCallback callback); + + ~DocumentIconFetcher() override; + + private: + friend DocumentUserData; + DOCUMENT_USER_DATA_KEY_DECL(); + + explicit DocumentIconFetcher(content::RenderFrameHost* rfh); + + void RunTask(FetchIconsFromDocumentCallback callback); + + void OnTaskComplete(int id, + FetchIconsFromDocumentCallback original_callback, + FetchIconsFromDocumentResult result); + + bool in_destruction_ = false; + int next_task_id_ = 0; + base::flat_map<int, std::unique_ptr<FetchIconsFromDocumentTask>> fetch_tasks_; + + base::WeakPtrFactory<DocumentIconFetcher> weak_factory_{this}; +}; + +} // namespace shortcuts + +#endif // CHROME_BROWSER_SHORTCUTS_DOCUMENT_ICON_FETCHER_H_
diff --git a/chrome/browser/shortcuts/document_icon_fetcher_browsertest.cc b/chrome/browser/shortcuts/document_icon_fetcher_browsertest.cc new file mode 100644 index 0000000..b93d0f8 --- /dev/null +++ b/chrome/browser/shortcuts/document_icon_fetcher_browsertest.cc
@@ -0,0 +1,162 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/shortcuts/document_icon_fetcher.h" + +#include <memory> + +#include "base/base_paths.h" +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "base/test/gmock_expected_support.h" +#include "base/test/test_future.h" +#include "base/types/expected.h" +#include "chrome/browser/shortcuts/fetch_icons_from_document_task.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_commands.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/test/browser_test.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/color_utils.h" +#include "ui/gfx/test/sk_gmock_support.h" + +namespace shortcuts { +namespace { +constexpr char kPageNoIcons[] = "/shortcuts/no_icons_page.html"; +constexpr char kPageWithIcons[] = "/shortcuts/page_icons.html"; + +class DocumentIconFetcherTest : public InProcessBrowserTest { + public: + void SetUpOnMainThread() override { + default_favicon_server_.AddDefaultHandlers(base::FilePath( + FILE_PATH_LITERAL("chrome/test/data/shortcuts/default_icon_has_two"))); + ASSERT_TRUE(embedded_https_test_server().Start()); + ASSERT_TRUE(default_favicon_server_.Start()); + } + + GURL GetPageWithDefaultFavicon() { + return default_favicon_server_.GetURL("/index.html"); + } + + base::expected<SkBitmap, std::string> LoadImageFromTestFile( + const base::FilePath& relative_path_from_chrome_data) { + base::ScopedAllowBlockingForTesting allow_blocking; + // Load image data from test directory. + base::FilePath chrome_src_dir; + if (!base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, + &chrome_src_dir)) { + return base::unexpected("Could not find src directory."); + } + + base::FilePath image_path = + chrome_src_dir.Append(FILE_PATH_LITERAL("chrome/test/data")) + .Append(relative_path_from_chrome_data); + if (!base::PathExists(image_path)) { + return base::unexpected( + base::StrCat({"Path does not exist: ", image_path.AsUTF8Unsafe()})); + } + std::string image_data; + if (!base::ReadFileToString(image_path, &image_data)) { + return base::unexpected("Could not read file."); + } + + SkBitmap image; + if (!gfx::PNGCodec::Decode( + reinterpret_cast<const uint8_t*>(image_data.data()), + image_data.size(), &image)) { + return base::unexpected("Could not decode file."); + } + return image; + } + + private: + net::EmbeddedTestServer default_favicon_server_{ + net::EmbeddedTestServer::TYPE_HTTPS}; +}; + +IN_PROC_BROWSER_TEST_F(DocumentIconFetcherTest, PageNoIcons) { + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), embedded_https_test_server().GetURL(kPageNoIcons))); + + base::test::TestFuture<FetchIconsFromDocumentResult> future; + DocumentIconFetcher::FetchIcons( + *browser()->tab_strip_model()->GetActiveWebContents(), + future.GetCallback()); + ASSERT_TRUE(future.Wait()); + EXPECT_TRUE(future.Get().has_value()); + EXPECT_THAT(future.Get().value(), testing::IsEmpty()); +} + +IN_PROC_BROWSER_TEST_F(DocumentIconFetcherTest, IconMetadata) { + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), embedded_https_test_server().GetURL(kPageWithIcons))); + + base::test::TestFuture<FetchIconsFromDocumentResult> future; + + DocumentIconFetcher::FetchIcons( + *browser()->tab_strip_model()->GetActiveWebContents(), + future.GetCallback()); + ASSERT_TRUE(future.Wait()); + ASSERT_TRUE(future.Get().has_value()); + std::vector<SkBitmap> images = future.Get().value(); + + SkBitmap expected_green; + ASSERT_OK_AND_ASSIGN(expected_green, + LoadImageFromTestFile(base::FilePath( + FILE_PATH_LITERAL("shortcuts/green.png")))); + SkBitmap expected_noise; + ASSERT_OK_AND_ASSIGN(expected_noise, + LoadImageFromTestFile(base::FilePath( + FILE_PATH_LITERAL("shortcuts/noise.png")))); + EXPECT_THAT(images, testing::UnorderedElementsAre( + gfx::test::EqualsBitmap(expected_green), + gfx::test::EqualsBitmap(expected_noise))); +} + +IN_PROC_BROWSER_TEST_F(DocumentIconFetcherTest, DefaultFavicon) { + ASSERT_TRUE( + ui_test_utils::NavigateToURL(browser(), GetPageWithDefaultFavicon())); + + base::test::TestFuture<FetchIconsFromDocumentResult> future; + DocumentIconFetcher::FetchIcons( + *browser()->tab_strip_model()->GetActiveWebContents(), + future.GetCallback()); + ASSERT_TRUE(future.Wait()); + EXPECT_TRUE(future.Get().has_value()); + std::vector<SkBitmap> images = future.Get().value(); + SkBitmap expected_16; + ASSERT_OK_AND_ASSIGN( + expected_16, LoadImageFromTestFile(base::FilePath(FILE_PATH_LITERAL( + "shortcuts/default_icon_has_two/16_favicon_part.png")))); + SkBitmap expected_32; + ASSERT_OK_AND_ASSIGN( + expected_32, LoadImageFromTestFile(base::FilePath(FILE_PATH_LITERAL( + "shortcuts/default_icon_has_two/32_favicon_part.png")))); + EXPECT_THAT(images, testing::UnorderedElementsAre( + gfx::test::EqualsBitmap(expected_16), + gfx::test::EqualsBitmap(expected_32))); +} + +IN_PROC_BROWSER_TEST_F(DocumentIconFetcherTest, WebContentsClosed) { + base::test::TestFuture<FetchIconsFromDocumentResult> future; + chrome::NewTab(browser()); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), embedded_https_test_server().GetURL(kPageWithIcons))); + DocumentIconFetcher::FetchIcons( + *browser()->tab_strip_model()->GetActiveWebContents(), + future.GetCallback()); + chrome::CloseTab(browser()); + ASSERT_TRUE(future.Wait()); + EXPECT_THAT( + future.Get(), + base::test::ErrorIs(FetchIconsForDocumentError::kDocumentDestroyed)); +} + +} // namespace +} // namespace shortcuts
diff --git a/chrome/browser/shortcuts/fetch_icons_from_document_task.cc b/chrome/browser/shortcuts/fetch_icons_from_document_task.cc new file mode 100644 index 0000000..653a96e --- /dev/null +++ b/chrome/browser/shortcuts/fetch_icons_from_document_task.cc
@@ -0,0 +1,124 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/shortcuts/fetch_icons_from_document_task.h" + +#include "base/functional/bind.h" +#include "base/functional/callback.h" +#include "base/location.h" +#include "base/memory/raw_ref.h" +#include "base/types/expected.h" +#include "components/webapps/common/web_page_metadata.mojom.h" +#include "components/webapps/common/web_page_metadata_agent.mojom.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" +#include "mojo/public/cpp/bindings/associated_remote.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/geometry/size.h" + +namespace shortcuts { + +FetchIconsFromDocumentTask::FetchIconsFromDocumentTask( + base::PassKey<DocumentIconFetcher>, + content::RenderFrameHost& rfh) + : frame_host_(rfh) { + CHECK(frame_host_->IsInPrimaryMainFrame()); +} + +FetchIconsFromDocumentTask::~FetchIconsFromDocumentTask() = default; + +void FetchIconsFromDocumentTask::Start( + FetchIconsFromDocumentCallback callback) { + callback_ = std::move(callback); + mojo::AssociatedRemote<webapps::mojom::WebPageMetadataAgent> metadata_agent; + frame_host_->GetRemoteAssociatedInterfaces()->GetInterface(&metadata_agent); + + // Set the error handler so that we can run abort this task if the WebContents + // or the RenderFrameHost are destroyed and the connection to + // ChromeRenderFrame is lost. + metadata_agent.set_disconnect_handler( + base::BindOnce(&FetchIconsFromDocumentTask::OnMetadataFetchError, + weak_factory_.GetWeakPtr())); + + // Bind the InterfacePtr into the callback so that it's kept alive + // until there's either a connection error or a response. + auto* web_page_metadata_proxy = metadata_agent.get(); + web_page_metadata_proxy->GetWebPageMetadata( + base::BindOnce(&FetchIconsFromDocumentTask::OnWebPageMetadataObtained, + weak_factory_.GetWeakPtr(), std::move(metadata_agent))); +} + +FetchIconsFromDocumentCallback FetchIconsFromDocumentTask::TakeCallback() { + return std::move(callback_); +} + +void FetchIconsFromDocumentTask::OnWebPageMetadataObtained( + mojo::AssociatedRemote<webapps::mojom::WebPageMetadataAgent> metadata_agent, + webapps::mojom::WebPageMetadataPtr web_page_metadata) { + metadata_fetch_complete_ = true; + std::vector<GURL> icons; + for (const auto& icon_info : web_page_metadata->icons) { + icons.push_back(icon_info->url); + } + for (const auto& favicon_url : frame_host_->FaviconURLs()) { + icons.push_back(favicon_url->icon_url); + } + + // Eliminate duplicates. + base::flat_set<GURL> icon_set(std::move(icons)); + num_pending_image_requests_ = icon_set.size(); + + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(&frame_host_.get()); + for (const GURL& url : icon_set) { + web_contents->DownloadImageInFrame( + frame_host_->GetGlobalId(), url, /*is_favicon=*/true, + /*preferred_size=*/gfx::Size(), + /*max_bitmap_size=*/0, /*bypass_cache=*/false, + base::BindOnce(&FetchIconsFromDocumentTask::DidDownloadFavicon, + weak_factory_.GetWeakPtr())); + } + MaybeCompleteImageDownloadAndSelfDestruct(); +} + +void FetchIconsFromDocumentTask::DidDownloadFavicon( + int id, + int http_status_code, + const GURL& image_url, + const std::vector<SkBitmap>& bitmaps, + const std::vector<gfx::Size>& sizes) { + icons_.reserve(icons_.size() + bitmaps.size()); + for (const SkBitmap& bitmap : bitmaps) { + if (bitmap.drawsNothing()) { + continue; + } + icons_.push_back(bitmap); + } + --num_pending_image_requests_; + MaybeCompleteImageDownloadAndSelfDestruct(); +} + +void FetchIconsFromDocumentTask::MaybeCompleteImageDownloadAndSelfDestruct() { + if (!metadata_fetch_complete_ || num_pending_image_requests_ > 0) { + return; + } + OnCompleteSelfDestruct(base::ok(std::move(icons_))); +} + +void FetchIconsFromDocumentTask::OnCompleteSelfDestruct(Result result, + base::Location here) { + if (!callback_) { + return; + } + std::move(callback_).Run(std::move(result)); +} + +void FetchIconsFromDocumentTask::OnMetadataFetchError() { + OnCompleteSelfDestruct( + base::unexpected(FetchIconsForDocumentError::kMetadataFetchFailed)); +} + +} // namespace shortcuts
diff --git a/chrome/browser/shortcuts/fetch_icons_from_document_task.h b/chrome/browser/shortcuts/fetch_icons_from_document_task.h new file mode 100644 index 0000000..7ef5b9a --- /dev/null +++ b/chrome/browser/shortcuts/fetch_icons_from_document_task.h
@@ -0,0 +1,101 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SHORTCUTS_FETCH_ICONS_FROM_DOCUMENT_TASK_H_ +#define CHROME_BROWSER_SHORTCUTS_FETCH_ICONS_FROM_DOCUMENT_TASK_H_ + +#include <vector> + +#include "base/functional/callback_forward.h" +#include "base/memory/raw_ref.h" +#include "base/memory/weak_ptr.h" +#include "base/types/expected.h" +#include "base/types/pass_key.h" +#include "base/values.h" +#include "components/webapps/common/web_page_metadata.mojom-forward.h" +#include "components/webapps/common/web_page_metadata_agent.mojom-forward.h" +#include "mojo/public/cpp/bindings/associated_remote.h" + +class SkBitmap; +class GURL; + +namespace base { +class Location; +} + +namespace content { +class RenderFrameHost; +} + +namespace gfx { +class Size; +} + +namespace shortcuts { +class DocumentIconFetcher; + +enum class FetchIconsForDocumentError { + kDocumentDestroyed, + kMetadataFetchFailed +}; +using FetchIconsFromDocumentResult = + base::expected<std::vector<SkBitmap>, FetchIconsForDocumentError>; +using FetchIconsFromDocumentCallback = + base::OnceCallback<void(FetchIconsFromDocumentResult)>; + +// Fetch all icons for the current RenderFrameHost document. +// Invariants: +// - The `frame_host_` provided to this class must be alive for the lifetime of +// this class. +// - The `callback` may be called synchronously. +// - The `callback` will be NOT be called on destruction. To handle that, the +// user +// of this class must use the `TakeCallback()` method to extract the callback. +class FetchIconsFromDocumentTask { + public: + using Result = FetchIconsFromDocumentResult; + + // `rfh` must be the primary main frame. + FetchIconsFromDocumentTask(base::PassKey<DocumentIconFetcher>, + content::RenderFrameHost& rfh); + ~FetchIconsFromDocumentTask(); + + // The `callback` may be called synchronously. + void Start(FetchIconsFromDocumentCallback callback); + + FetchIconsFromDocumentCallback TakeCallback(); + + private: + void OnWebPageMetadataObtained( + mojo::AssociatedRemote<webapps::mojom::WebPageMetadataAgent> + metadata_agent, + webapps::mojom::WebPageMetadataPtr web_page_metadata); + + void DownloadIcon(const GURL& url); + + void DidDownloadFavicon(int id, + int http_status_code, + const GURL& image_url, + const std::vector<SkBitmap>& bitmaps, + const std::vector<gfx::Size>& sizes); + + void MaybeCompleteImageDownloadAndSelfDestruct(); + + void OnCompleteSelfDestruct(Result result, base::Location here = FROM_HERE); + + void OnMetadataFetchError(); + + base::raw_ref<content::RenderFrameHost> frame_host_; + FetchIconsFromDocumentCallback callback_; + + bool metadata_fetch_complete_ = false; + int num_pending_image_requests_ = 0; + std::vector<SkBitmap> icons_; + + base::WeakPtrFactory<FetchIconsFromDocumentTask> weak_factory_{this}; +}; + +} // namespace shortcuts + +#endif // CHROME_BROWSER_SHORTCUTS_FETCH_ICONS_FROM_DOCUMENT_TASK_H_
diff --git a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc index 5946190..3627767 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc
@@ -40,6 +40,7 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/signin/dice_web_signin_interceptor_delegate.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" @@ -301,6 +302,8 @@ Profile::FromBrowserContext(context), std::move(fake_delegate)); } + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; + std::map<content::BrowserContext*, FakeDiceWebSigninInterceptorDelegate*> interceptor_delegates_; };
diff --git a/chrome/browser/site_isolation/DEPS b/chrome/browser/site_isolation/DEPS deleted file mode 100644 index 7d6f2785..0000000 --- a/chrome/browser/site_isolation/DEPS +++ /dev/null
@@ -1,8 +0,0 @@ -specific_include_rules = { - "chrome_site_per_process_browsertest.cc": [ - "+pdf/pdf_features.h", - ], - "site_per_process_interactive_browsertest.cc": [ - "+pdf/pdf_features.h", - ], -} \ No newline at end of file
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index f28fceb1..334648c 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -68,6 +68,7 @@ #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/common/chrome_features.h" @@ -715,22 +716,6 @@ browser(), https_server_.GetURL(replacement_path))); } - Browser* InstallAndOpenTestWebApp(const GURL& start_url) { - auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>(); - web_app_info->start_url = start_url; - web_app_info->scope = start_url.GetWithoutFilename(); - web_app_info->title = u"Test app"; - web_app_info->description = u"Test description"; - - Profile* profile = browser()->profile(); - - webapps::AppId app_id = - web_app::test::InstallWebApp(profile, std::move(web_app_info)); - - Browser* app_browser = web_app::LaunchWebAppBrowserAndWait(profile, app_id); - return app_browser; - } - void UpdateChromePolicy(const policy::PolicyMap& policies) { policy_provider_.UpdateChromePolicy(policies); ASSERT_TRUE(base::CurrentThread::Get()); @@ -1300,9 +1285,31 @@ browser()->tab_strip_model()->delegate()->ShouldDisplayFavicon(tab)); } +class SSLUITestWithWebApps : public SSLUITest { + public: + Browser* InstallAndOpenTestWebApp(const GURL& start_url) { + auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>(); + web_app_info->start_url = start_url; + web_app_info->scope = start_url.GetWithoutFilename(); + web_app_info->title = u"Test app"; + web_app_info->description = u"Test description"; + + Profile* profile = browser()->profile(); + + webapps::AppId app_id = + web_app::test::InstallWebApp(profile, std::move(web_app_info)); + + Browser* app_browser = web_app::LaunchWebAppBrowserAndWait(profile, app_id); + return app_browser; + } + + private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; +}; + // Visits a page in an app window with https error and proceed: // Disabled due to flaky failures; see https://crbug.com/1156046. -IN_PROC_BROWSER_TEST_F(SSLUITest, +IN_PROC_BROWSER_TEST_F(SSLUITestWithWebApps, DISABLED_InAppTestHTTPSExpiredCertAndProceed) { ASSERT_TRUE(https_server_expired_.Start()); @@ -1318,7 +1325,7 @@ } // Visits a page with https error and proceed. Then open the app and proceed. -IN_PROC_BROWSER_TEST_F(SSLUITest, +IN_PROC_BROWSER_TEST_F(SSLUITestWithWebApps, InAppTestHTTPSExpiredCertAndPreviouslyProceeded) { ASSERT_TRUE(https_server_expired_.Start());
diff --git a/chrome/browser/ssl/ssl_fenced_frame_browsertest.cc b/chrome/browser/ssl/ssl_fenced_frame_browsertest.cc index dedc290..695baab 100644 --- a/chrome/browser/ssl/ssl_fenced_frame_browsertest.cc +++ b/chrome/browser/ssl/ssl_fenced_frame_browsertest.cc
@@ -6,6 +6,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/test/base/in_process_browser_test.h" @@ -68,7 +69,7 @@ Browser* app_browser = web_app::LaunchWebAppBrowserAndWait(profile, app_id); return app_browser; } - + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; content::test::FencedFrameTestHelper fenced_frame_helper_; };
diff --git a/chrome/browser/tab_group/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilter.java b/chrome/browser/tab_group/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilter.java index d2209c3..a17ec44 100644 --- a/chrome/browser/tab_group/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilter.java +++ b/chrome/browser/tab_group/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilter.java
@@ -382,22 +382,6 @@ if (didCreateNewGroup && isTabInTabGroup(tab)) { didCreateNewGroup = false; } - } - - // This specific observer emission must happen before the below code which moves the - // tabs on grouping. The reason this must happen before is because moving a tab will - // update the tab group's favicon color in TabListMediator and cause it to generate a - // tab group color. This may indicate an improper state where tab groups that already - // have a color are not considered new groups, and the color should be set during the - // TabGroupCreationManager#showDialog flow anyways. - for (TabGroupModelFilterObserver observer : mGroupFilterObserver) { - if (didCreateNewGroup) { - observer.didCreateNewGroup(destinationTab, this); - } - } - - for (int i = 0; i < tabs.size(); i++) { - Tab tab = tabs.get(i); // When merging tabs are in the same group, only make one willMergeTabToGroup call. if (!isSameGroup || i == tabs.size() - 1) { @@ -444,6 +428,10 @@ } for (TabGroupModelFilterObserver observer : mGroupFilterObserver) { + if (didCreateNewGroup) { + observer.didCreateNewGroup(destinationTab, this); + } + // If this is a new tab group creation, do not trigger a snackbar. boolean skipSnackbarForCreation = didCreateNewGroup && ChromeFeatureList.sTabGroupParityAndroid.isEnabled();
diff --git a/chrome/browser/ui/DEPS b/chrome/browser/ui/DEPS index 774c66c..51a2d29 100644 --- a/chrome/browser/ui/DEPS +++ b/chrome/browser/ui/DEPS
@@ -29,7 +29,6 @@ "+components/user_education/webui", "+components/user_notes", "+components/web_package", - "+pdf/pdf_features.h", "+services/content/public", "+services/device/public/mojom", "+services/screen_ai",
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc index 4f49d40f..bd63ea69 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc +++ b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" @@ -677,12 +678,23 @@ } #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) +class PopupBlockerBrowserTestWithWebApps : public PopupBlockerBrowserTest { + private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; +}; + // Reentrancy regression test for PopunderPreventer attempting to activate a // fullscreen web app window that is being closed; see crbug.com/331095620. -IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, - CloseFullscreenStandaloneWebApp) { +// TODO(crbug.com/335493696): Mac shims don't work with faked fullscreen. +#if BUILDFLAG(IS_MAC) +#define MAYBE_CloseFullscreenStandaloneWebApp \ + DISABLED_CloseFullscreenStandaloneWebApp +#else +#define MAYBE_CloseFullscreenStandaloneWebApp CloseFullscreenStandaloneWebApp +#endif +IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTestWithWebApps, + MAYBE_CloseFullscreenStandaloneWebApp) { GURL url = embedded_test_server()->GetURL("/web_apps/basic.html"); - web_app::OsIntegrationManager::ScopedSuppressForTesting suppress; webapps::AppId id = web_app::InstallWebAppFromPage(browser(), url); Browser* app = web_app::LaunchWebAppBrowserAndWait(browser()->profile(), id); WebContents* tab = app->tab_strip_model()->GetActiveWebContents();
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 03620f99..800e7d4 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -2117,15 +2117,14 @@ } bool Browser::CanEnterFullscreenModeForTab( - content::RenderFrameHost* requesting_frame, - const blink::mojom::FullscreenOptions& options) { + content::RenderFrameHost* requesting_frame) { // If the tab strip isn't editable then a drag session is in progress, and it // is not safe to enter fullscreen. https://crbug.com/1315080 if (!tab_strip_model_delegate_->IsTabStripEditable()) return false; return exclusive_access_manager_->fullscreen_controller() - ->CanEnterFullscreenModeForTab(requesting_frame, options.display_id); + ->CanEnterFullscreenModeForTab(requesting_frame); } void Browser::EnterFullscreenModeForTab(
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 6a3a4af..1c848af 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -1011,8 +1011,7 @@ void RestoreFromWebAPI() override; ui::WindowShowState GetWindowShowState() const override; bool CanEnterFullscreenModeForTab( - content::RenderFrameHost* requesting_frame, - const blink::mojom::FullscreenOptions& options) override; + content::RenderFrameHost* requesting_frame) override; void EnterFullscreenModeForTab( content::RenderFrameHost* requesting_frame, const blink::mojom::FullscreenOptions& options) override;
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index 5023e56c..3c6fb66c 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc
@@ -78,6 +78,7 @@ #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/policy/web_app_policy_constants.h" #include "chrome/browser/web_applications/policy/web_app_policy_manager.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/browser/web_applications/web_app_provider.h" @@ -394,6 +395,9 @@ OnBrowserCloseCancelled, (Browser * browser, BrowserClosingStatus reason), (override)); + + private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; }; // Launch the app on a page with no title, check that the app title was set
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index a9ebb52c..f6f1957 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -1122,8 +1122,8 @@ } DefaultBrowserPromptManager::UpdatePrefsForDismissedPrompt( browser_->profile()); - DefaultBrowserPromptManager::GetInstance()->CloseAllPrompts(); - + DefaultBrowserPromptManager::GetInstance()->CloseAllPrompts( + DefaultBrowserPromptManager::CloseReason::kAccept); break; #endif default: @@ -1325,6 +1325,7 @@ command_updater_.UpdateCommandEnabled(IDC_SHOW_BETA_FORUM, true); command_updater_.UpdateCommandEnabled( IDC_BOOKMARKS_MENU, (!guest_session && !profile()->IsSystemProfile())); + command_updater_.UpdateCommandEnabled(IDC_SAVED_TAB_GROUPS_MENU, true); command_updater_.UpdateCommandEnabled( IDC_RECENT_TABS_MENU, (!guest_session && !profile()->IsSystemProfile() && !profile()->IsIncognitoProfile()));
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc index 81a0f64..06a703e 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
@@ -221,8 +221,7 @@ } bool FullscreenController::CanEnterFullscreenModeForTab( - content::RenderFrameHost* requesting_frame, - const int64_t display_id) { + content::RenderFrameHost* requesting_frame) { DCHECK(requesting_frame); auto* web_contents = WebContents::FromRenderFrameHost(requesting_frame); DCHECK(web_contents); @@ -244,7 +243,7 @@ // could cause requestFullscreen promises to hang. If we are in this function, // the renderer expects a visual property update to call // |blink::FullscreenController::DidEnterFullscreen| to resolve promises. - DCHECK(CanEnterFullscreenModeForTab(requesting_frame, display_id)); + DCHECK(CanEnterFullscreenModeForTab(requesting_frame)); auto* web_contents = WebContents::FromRenderFrameHost(requesting_frame); DCHECK(web_contents);
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller.h b/chrome/browser/ui/exclusive_access/fullscreen_controller.h index 4b30e9a..643d434 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller.h +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller.h
@@ -114,9 +114,7 @@ // Returns whether entering fullscreen with |EnterFullscreenModeForTab()| is // allowed. - bool CanEnterFullscreenModeForTab( - content::RenderFrameHost* requesting_frame, - const int64_t display_id = display::kInvalidDisplayId); + bool CanEnterFullscreenModeForTab(content::RenderFrameHost* requesting_frame); // Enter tab-initiated fullscreen mode. FullscreenController decides whether // to also fullscreen the browser window. See 'FullscreenWithinTab Note'.
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc index 8c5c9b50..52ac544 100644 --- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc +++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -45,6 +45,7 @@ #include "chrome/browser/web_applications/external_install_options.h" #include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h" #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_helpers.h" @@ -353,7 +354,7 @@ // used by the NetworkService. content::ContentMockCertVerifier cert_verifier_; - web_app::OsIntegrationManager::ScopedSuppressForTesting os_hooks_suppress_; + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; }; // Tests that "Open link in new tab" opens a link in a foreground tab. @@ -1356,7 +1357,13 @@ // This test was flaky on Win7 because it was bumping up against a 45 second // timeout. If it starts flaking on Windows 10+, it should be broken up into // smaller tests. See https://crbug.com/807471. -IN_PROC_BROWSER_TEST_P(HostedAppProcessModelTest, FromOutsideHostedApp) { +// TODO(crbug.com/335469702): Flaky on Linux ChromiumOS MSAN. +#if BUILDFLAG(IS_CHROMEOS) && defined(MEMORY_SANITIZER) +#define MAYBE_FromOutsideHostedApp DISABLED_FromOutsideHostedApp +#else +#define MAYBE_FromOutsideHostedApp FromOutsideHostedApp +#endif +IN_PROC_BROWSER_TEST_P(HostedAppProcessModelTest, MAYBE_FromOutsideHostedApp) { // Set up and launch the hosted app. GURL app_url = embedded_test_server()->GetURL("app.site.test", "/frame_tree/simple.htm");
diff --git a/chrome/browser/ui/lens/lens_overlay_controller_browsertest.cc b/chrome/browser/ui/lens/lens_overlay_controller_browsertest.cc index 64b8ccb..c458ae0 100644 --- a/chrome/browser/ui/lens/lens_overlay_controller_browsertest.cc +++ b/chrome/browser/ui/lens/lens_overlay_controller_browsertest.cc
@@ -333,8 +333,14 @@ SidePanelEntry::Id::kLensOverlayResults); } +#if BUILDFLAG(IS_CHROMEOS_LACROS) && !BUILDFLAG(IS_CHROMEOS_DEVICE) && \ + defined(MEMORY_SANTIZER) +#define MAYBE_DelayPermissionsPrompt DISABLED_DelayPermissionsPrompt +#else +#define MAYBE_DelayPermissionsPrompt DelayPermissionsPrompt +#endif IN_PROC_BROWSER_TEST_F(LensOverlayControllerBrowserTest, - DelayPermissionsPrompt) { + MAYBE_DelayPermissionsPrompt) { // Navigate to a page so we can request permissions WaitForPaint();
diff --git a/chrome/browser/ui/safety_hub/menu_notification_service.cc b/chrome/browser/ui/safety_hub/menu_notification_service.cc index ec1baf4..5ce71e5 100644 --- a/chrome/browser/ui/safety_hub/menu_notification_service.cc +++ b/chrome/browser/ui/safety_hub/menu_notification_service.cc
@@ -50,6 +50,21 @@ const base::Value::Dict& stored_notifications = pref_service_->GetDict(safety_hub_prefs::kMenuNotificationsPrefsKey); + pref_dict_key_map_ = { + {safety_hub::SafetyHubModuleType::UNUSED_SITE_PERMISSIONS, + "unused-site-permissions"}, + {safety_hub::SafetyHubModuleType::NOTIFICATION_PERMISSIONS, + "notification-permissions"}, + {safety_hub::SafetyHubModuleType::SAFE_BROWSING, "safe-browsing"}, + {safety_hub::SafetyHubModuleType::EXTENSIONS, "extensions"}, + }; + // PasswordStatusCheckService might be null for some profiles and testing. Add + // to the dictionary only if the service is available. + if (password_check_service) { + pref_dict_key_map_.emplace(safety_hub::SafetyHubModuleType::PASSWORDS, + "passwords"); + } + // TODO(crbug.com/1443466): Make the interval for each service finch // configurable. // The Safety Hub services will be available whenever the |GetCachedResult| @@ -77,12 +92,16 @@ base::Unretained(extension_info_service), profile, true), stored_notifications); - SetInfoElement( - safety_hub::SafetyHubModuleType::PASSWORDS, - MenuNotificationPriority::HIGH, base::Days(0), - base::BindRepeating(&PasswordStatusCheckService::GetCachedResult, - base::Unretained(password_check_service)), - stored_notifications); + // PasswordStatusCheckService might be null for some profiles and testing. Add + // the info item only if the service is available. + if (password_check_service) { + SetInfoElement( + safety_hub::SafetyHubModuleType::PASSWORDS, + MenuNotificationPriority::HIGH, base::Days(0), + base::BindRepeating(&PasswordStatusCheckService::GetCachedResult, + base::Unretained(password_check_service)), + stored_notifications); + } // Listen for changes to the Safe Browsing pref to accommodate the trigger // logic.
diff --git a/chrome/browser/ui/safety_hub/menu_notification_service.h b/chrome/browser/ui/safety_hub/menu_notification_service.h index aca05b6..d297bbdf 100644 --- a/chrome/browser/ui/safety_hub/menu_notification_service.h +++ b/chrome/browser/ui/safety_hub/menu_notification_service.h
@@ -132,16 +132,8 @@ // Called when the pref for Safe Browsing has been updated. void OnSafeBrowsingPrefUpdate(); - const std::map<safety_hub::SafetyHubModuleType, const char*> - pref_dict_key_map_ = { - {safety_hub::SafetyHubModuleType::UNUSED_SITE_PERMISSIONS, - "unused-site-permissions"}, - {safety_hub::SafetyHubModuleType::NOTIFICATION_PERMISSIONS, - "notification-permissions"}, - {safety_hub::SafetyHubModuleType::SAFE_BROWSING, "safe-browsing"}, - {safety_hub::SafetyHubModuleType::EXTENSIONS, "extensions"}, - {safety_hub::SafetyHubModuleType::PASSWORDS, "passwords"}, - }; + // Holds the mapping from module type to pref name. + std::map<safety_hub::SafetyHubModuleType, const char*> pref_dict_key_map_; // Preference service that persists the notifications. raw_ptr<PrefService> pref_service_;
diff --git a/chrome/browser/ui/safety_hub/menu_notification_service_factory.cc b/chrome/browser/ui/safety_hub/menu_notification_service_factory.cc index f274a905..f04b25b 100644 --- a/chrome/browser/ui/safety_hub/menu_notification_service_factory.cc +++ b/chrome/browser/ui/safety_hub/menu_notification_service_factory.cc
@@ -40,6 +40,8 @@ .WithRegular(ProfileSelection::kOriginalOnly) .Build()) { DependsOn(UnusedSitePermissionsServiceFactory::GetInstance()); + DependsOn(NotificationPermissionsReviewServiceFactory::GetInstance()); + DependsOn(PasswordStatusCheckServiceFactory::GetInstance()); DependsOn(extensions::ExtensionPrefsFactory::GetInstance()); }
diff --git a/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.cc b/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.cc index 34e8c3a..e71e0c6 100644 --- a/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.cc +++ b/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.cc
@@ -50,7 +50,3 @@ engagement_service); } -bool NotificationPermissionsReviewServiceFactory:: - ServiceIsCreatedWithBrowserContext() const { - return base::FeatureList::IsEnabled(features::kSafetyHub); -}
diff --git a/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.h b/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.h index 7e75491..9c38adc 100644 --- a/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.h +++ b/chrome/browser/ui/safety_hub/notification_permission_review_service_factory.h
@@ -41,8 +41,6 @@ // BrowserContextKeyedServiceFactory: std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; - - bool ServiceIsCreatedWithBrowserContext() const override; }; #endif // CHROME_BROWSER_UI_SAFETY_HUB_NOTIFICATION_PERMISSION_REVIEW_SERVICE_FACTORY_H_
diff --git a/chrome/browser/ui/safety_hub/notification_permission_review_service_unittest.cc b/chrome/browser/ui/safety_hub/notification_permission_review_service_unittest.cc index 99655ac4..e2a7efe7 100644 --- a/chrome/browser/ui/safety_hub/notification_permission_review_service_unittest.cc +++ b/chrome/browser/ui/safety_hub/notification_permission_review_service_unittest.cc
@@ -249,6 +249,8 @@ NotificationsEngagementServiceFactory::GetForProfile(profile()); notification_engagement_service->RecordNotificationDisplayed( GURL("https://google.com:443"), 10 * 7); + // Letting service update the cached result. + safety_hub_test_util::UpdateSafetyHubServiceAsync(service); const auto& updated_notification_permissions = service->PopulateNotificationPermissionReviewData(); EXPECT_EQ(2UL, updated_notification_permissions.size());
diff --git a/chrome/browser/ui/safety_hub/password_status_check_service.cc b/chrome/browser/ui/safety_hub/password_status_check_service.cc index 4cd0b7d..00a65b9 100644 --- a/chrome/browser/ui/safety_hub/password_status_check_service.cc +++ b/chrome/browser/ui/safety_hub/password_status_check_service.cc
@@ -285,14 +285,9 @@ profile_, ServiceAccessType::IMPLICIT_ACCESS); // ProfilePasswordStore may not exist for some cases like non-user profiles on - // Ash. If ProfilePasswordStore does not exist, then no other password - // operations can be done. Hence, here is an early return to prevent - // initializing checks. - // TODO(crbug.com/1443466): Add CHECK for profile_store after making this - // service null if the store does not exist. - if (!profile_store) { - return; - } + // Ash. If ProfilePasswordStore does not exist, the service should not be + // created by the factory. + DCHECK(profile_store); profile_password_store_observation_.Observe(profile_store.get()); if (account_store) {
diff --git a/chrome/browser/ui/safety_hub/password_status_check_service_factory.cc b/chrome/browser/ui/safety_hub/password_status_check_service_factory.cc index 10fc12fd..d3a3233 100644 --- a/chrome/browser/ui/safety_hub/password_status_check_service_factory.cc +++ b/chrome/browser/ui/safety_hub/password_status_check_service_factory.cc
@@ -52,11 +52,19 @@ if (!base::FeatureList::IsEnabled(features::kSafetyHub)) { return nullptr; } + + Profile* profile = Profile::FromBrowserContext(context); + password_manager::PasswordStoreInterface* store = + ProfilePasswordStoreFactory::GetForProfile( + profile, ServiceAccessType::EXPLICIT_ACCESS) + .get(); + // Incognito, guest, or system profiles doesn't have PasswordStore so + // SafetyHub shouldn't be created as well. + if (!store) { + return nullptr; + } + return std::make_unique<PasswordStatusCheckService>( Profile::FromBrowserContext(context)); } -bool PasswordStatusCheckServiceFactory::ServiceIsCreatedWithBrowserContext() - const { - return base::FeatureList::IsEnabled(features::kSafetyHub); -}
diff --git a/chrome/browser/ui/safety_hub/password_status_check_service_factory.h b/chrome/browser/ui/safety_hub/password_status_check_service_factory.h index 491ffc1d..082ba2d 100644 --- a/chrome/browser/ui/safety_hub/password_status_check_service_factory.h +++ b/chrome/browser/ui/safety_hub/password_status_check_service_factory.h
@@ -34,8 +34,6 @@ ~PasswordStatusCheckServiceFactory() override; // BrowserContextKeyedServiceFactory: - bool ServiceIsCreatedWithBrowserContext() const override; - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/ui/safety_hub/password_status_check_service_unittest.cc b/chrome/browser/ui/safety_hub/password_status_check_service_unittest.cc index aabe4c9..935069ba6 100644 --- a/chrome/browser/ui/safety_hub/password_status_check_service_unittest.cc +++ b/chrome/browser/ui/safety_hub/password_status_check_service_unittest.cc
@@ -252,25 +252,6 @@ } }; -class PasswordStatusCheckServiceWithoutPasswordStoreTest - : public testing::Test { - public: - PasswordStatusCheckService* service() { return service_.get(); } - - content::BrowserTaskEnvironment* task_environment() { return &task_env_; } - - private: - void SetUp() override { - service_ = std::make_unique<PasswordStatusCheckService>(&profile_); - task_env_.RunUntilIdle(); - } - - content::BrowserTaskEnvironment task_env_{ - base::test::TaskEnvironment::TimeSource::MOCK_TIME}; - TestingProfile profile_; - std::unique_ptr<PasswordStatusCheckService> service_; -}; - class PasswordStatusCheckServiceParameterizedSchedulingTest : public PasswordStatusCheckServiceBaseTest, public testing::WithParamInterface<int> { @@ -868,20 +849,6 @@ testing::ElementsAre(kOrigin1)); } -TEST_F(PasswordStatusCheckServiceWithoutPasswordStoreTest, NoPasswordStored) { - // Let the time pass until a check should have happened. - task_environment()->AdvanceClock(base::Days(30)); - task_environment()->RunUntilIdle(); - - // Expect that nothing is initialized. - EXPECT_FALSE(service()->GetSavedPasswordsPresenterForTesting()); - EXPECT_FALSE(service()->GetPasswordCheckDelegateForTesting()); - EXPECT_FALSE(service()->IsObservingSavedPasswordsPresenterForTesting()); - EXPECT_FALSE(service()->IsObservingBulkLeakCheckForTesting()); - EXPECT_FALSE(service()->is_password_check_running()); - EXPECT_FALSE(service()->is_update_credential_count_pending()); -} - TEST_P(PasswordStatusCheckServiceParameterizedSchedulingTest, CheckWeightedRandomScheduling) { base::test::ScopedFeatureList feature_list;
diff --git a/chrome/browser/ui/safety_hub/safety_hub_test_util.cc b/chrome/browser/ui/safety_hub/safety_hub_test_util.cc index 31cdf51c..3da17ad 100644 --- a/chrome/browser/ui/safety_hub/safety_hub_test_util.cc +++ b/chrome/browser/ui/safety_hub/safety_hub_test_util.cc
@@ -8,6 +8,7 @@ #include "base/run_loop.h" #include "base/test/run_until.h" +#include "chrome/browser/ui/safety_hub/password_status_check_service_factory.h" #include "chrome/test/base/testing_profile.h" #include "components/crx_file/id_util.h" #include "extensions/browser/extension_prefs.h" @@ -112,6 +113,14 @@ })); } +void RunUntilPasswordCheckCompleted(Profile* profile) { + PasswordStatusCheckService* service = + PasswordStatusCheckServiceFactory::GetForProfile(profile); + ASSERT_TRUE(base::test::RunUntil([&]() { + return !service->IsUpdateRunning() && !service->IsInfrastructureReady(); + })); +} + std::unique_ptr<testing::NiceMock<MockCWSInfoService>> GetMockCWSInfoService( Profile* profile, bool with_calls) {
diff --git a/chrome/browser/ui/safety_hub/safety_hub_test_util.h b/chrome/browser/ui/safety_hub/safety_hub_test_util.h index 7f3180c..ffee56b 100644 --- a/chrome/browser/ui/safety_hub/safety_hub_test_util.h +++ b/chrome/browser/ui/safety_hub/safety_hub_test_util.h
@@ -37,6 +37,10 @@ void UpdatePasswordCheckServiceAsync( PasswordStatusCheckService* password_service); +// This will run until ongoing checks in PasswordStatusCheckService to be +// completed. +void RunUntilPasswordCheckCompleted(Profile* profile); + // Creates a mock service that returns mock results for the CWS info service. If // |with_calls| is true, total six extensions with different properties are // mocked: malware, policy violation, unpublished, combination of malware and
diff --git a/chrome/browser/ui/startup/default_browser_prompt_manager.cc b/chrome/browser/ui/startup/default_browser_prompt_manager.cc index 592b62e..7594907c 100644 --- a/chrome/browser/ui/startup/default_browser_prompt_manager.cc +++ b/chrome/browser/ui/startup/default_browser_prompt_manager.cc
@@ -100,12 +100,14 @@ } } -void DefaultBrowserPromptManager::CloseAllPrompts() { +void DefaultBrowserPromptManager::CloseAllPrompts(CloseReason close_reason) { CloseAllInfoBars(); SetShowAppMenuPromptVisibility(false); - SetAppMenuItemVisibility(false); + if (close_reason == CloseReason::kAccept) { + SetAppMenuItemVisibility(false); + } } bool DefaultBrowserPromptManager::ShouldTrackBrowser(Browser* browser) { @@ -141,9 +143,9 @@ static_cast<ConfirmInfoBarDelegate*>(infobar->delegate()) ->RemoveObserver(this); - if (user_initiated_info_bar_close_pending_) { - CloseAllPrompts(); - user_initiated_info_bar_close_pending_ = false; + if (user_initiated_info_bar_close_pending_.has_value()) { + CloseAllPrompts(user_initiated_info_bar_close_pending_.value()); + user_initiated_info_bar_close_pending_.reset(); } } @@ -152,11 +154,11 @@ g_browser_process->local_state()->GetInteger( prefs::kDefaultBrowserDeclinedCount) + 1); - user_initiated_info_bar_close_pending_ = true; + user_initiated_info_bar_close_pending_ = CloseReason::kAccept; } void DefaultBrowserPromptManager::OnDismiss() { - user_initiated_info_bar_close_pending_ = true; + user_initiated_info_bar_close_pending_ = CloseReason::kDismiss; } DefaultBrowserPromptManager::DefaultBrowserPromptManager() = default; @@ -264,7 +266,8 @@ FROM_HERE, app_menu_remaining_duration, base::BindOnce([]() { UpdatePrefsForDismissedPrompt( BrowserList::GetInstance()->GetLastActive()->profile()); - DefaultBrowserPromptManager::GetInstance()->CloseAllPrompts(); + DefaultBrowserPromptManager::GetInstance()->CloseAllPrompts( + CloseReason::kDismiss); })); } else { app_menu_prompt_dismiss_timer_.Stop();
diff --git a/chrome/browser/ui/startup/default_browser_prompt_manager.h b/chrome/browser/ui/startup/default_browser_prompt_manager.h index a4ba8e1..95f0fc9 100644 --- a/chrome/browser/ui/startup/default_browser_prompt_manager.h +++ b/chrome/browser/ui/startup/default_browser_prompt_manager.h
@@ -35,6 +35,11 @@ virtual void OnShowAppMenuPromptChanged() = 0; }; + enum class CloseReason { + kAccept, + kDismiss, + }; + static DefaultBrowserPromptManager* GetInstance(); // Resets the tracking preferences for the default browser prompts so that @@ -59,7 +64,8 @@ void RemoveObserver(Observer* observer); void MaybeShowPrompt(); - void CloseAllPrompts(); + + void CloseAllPrompts(CloseReason close_reason); // BrowserTabStripTrackerDelegate bool ShouldTrackBrowser(Browser* browser) override; @@ -100,7 +106,8 @@ std::unique_ptr<BrowserTabStripTracker> browser_tab_strip_tracker_; std::map<content::WebContents*, infobars::InfoBar*> infobars_; - bool user_initiated_info_bar_close_pending_ = false; + + std::optional<CloseReason> user_initiated_info_bar_close_pending_; bool show_app_menu_prompt_ = false; bool show_app_menu_item_ = false;
diff --git a/chrome/browser/ui/startup/default_browser_prompt_manager_unittest.cc b/chrome/browser/ui/startup/default_browser_prompt_manager_unittest.cc index 90193c2..a95b497e0 100644 --- a/chrome/browser/ui/startup/default_browser_prompt_manager_unittest.cc +++ b/chrome/browser/ui/startup/default_browser_prompt_manager_unittest.cc
@@ -44,7 +44,8 @@ BrowserWithTestWindowTest::SetUp(); manager_ = DefaultBrowserPromptManager::GetInstance(); - manager_->CloseAllPrompts(); + manager_->CloseAllPrompts( + DefaultBrowserPromptManager::CloseReason::kAccept); // Set up a single tab in the foreground. std::unique_ptr<content::WebContents> contents = @@ -82,7 +83,8 @@ local_state()->ClearPref(prefs::kDefaultBrowserDeclinedCount); } - manager()->CloseAllPrompts(); + manager()->CloseAllPrompts( + DefaultBrowserPromptManager::CloseReason::kAccept); infobars::ContentInfoBarManager* infobar_manager = infobars::ContentInfoBarManager::FromWebContents( @@ -157,6 +159,30 @@ ASSERT_FALSE(manager->get_show_app_menu_item()); } +TEST_F(DefaultBrowserPromptManagerTest, AppMenuItemHiddenOnPromptAccept) { + EnableDefaultBrowserPromptRefreshFeatureWithParams( + {{features::kShowDefaultBrowserAppMenuItem.name, "true"}}); + + auto* manager = DefaultBrowserPromptManager::GetInstance(); + manager->MaybeShowPrompt(); + ASSERT_TRUE(manager->get_show_app_menu_item()); + + manager->CloseAllPrompts(DefaultBrowserPromptManager::CloseReason::kAccept); + ASSERT_FALSE(manager->get_show_app_menu_item()); +} + +TEST_F(DefaultBrowserPromptManagerTest, AppMenuItemPersistsOnPromptDismissed) { + EnableDefaultBrowserPromptRefreshFeatureWithParams( + {{features::kShowDefaultBrowserAppMenuItem.name, "true"}}); + + auto* manager = DefaultBrowserPromptManager::GetInstance(); + manager->MaybeShowPrompt(); + ASSERT_TRUE(manager->get_show_app_menu_item()); + + manager->CloseAllPrompts(DefaultBrowserPromptManager::CloseReason::kDismiss); + ASSERT_TRUE(manager->get_show_app_menu_item()); +} + TEST_F(DefaultBrowserPromptManagerTest, InfoBarMaxPromptCount) { // If max prompt count is negative, do not limit the number of times the // prompt is shown.
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index bfaf6abd..443c59e2 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/ui/startup/startup_browser_creator.h" + #include <stddef.h> #include <algorithm> @@ -69,7 +71,6 @@ #include "chrome/browser/ui/profiles/profile_ui_test_utils.h" #include "chrome/browser/ui/search/ntp_test_utils.h" #include "chrome/browser/ui/startup/launch_mode_recorder.h" -#include "chrome/browser/ui/startup/startup_browser_creator.h" #include "chrome/browser/ui/startup/startup_browser_creator_impl.h" #include "chrome/browser/ui/startup/startup_tab_provider.h" #include "chrome/browser/ui/startup/startup_types.h" @@ -79,6 +80,7 @@ #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h" #include "chrome/browser/web_applications/test/fake_web_app_provider.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_test_observers.h" #include "chrome/browser/web_applications/web_app_command_scheduler.h" #include "chrome/browser/web_applications/web_app_constants.h" @@ -1800,6 +1802,7 @@ } private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; base::test::ScopedFeatureList scoped_feature_list_; }; @@ -2060,6 +2063,7 @@ bool browser_added_check_passed_ = false; private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; std::unique_ptr< base::MockCallback<upgrade_util::RelaunchChromeBrowserCallback>> mock_relaunch_callback_; @@ -2188,7 +2192,7 @@ WebAppProvider& provider() { return *WebAppProvider::GetForTest(profile()); } base::test::ScopedFeatureList scoped_feature_list_; - web_app::OsIntegrationManager::ScopedSuppressForTesting os_hooks_supress_; + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; }; IN_PROC_BROWSER_TEST_F(StartupBrowserWithWebAppTest, @@ -2260,25 +2264,27 @@ IN_PROC_BROWSER_TEST_F(StartupBrowserWithWebAppTest, PRE_LastUsedProfilesWithWebApp) { - BrowserAddedObserver added_observer; + { + BrowserAddedObserver added_observer; #if BUILDFLAG(IS_MAC) - // Simulate an app shim connecting and launching an app. - apps::AppShimManager::Get()->LoadAndLaunchAppForTesting(kAppId); + // Simulate an app shim connecting and launching an app. + apps::AppShimManager::Get()->LoadAndLaunchAppForTesting(kAppId); #endif - content::RunAllTasksUntilIdle(); - // Launching with an app opens the app window via a task, so the test - // might start before SelectFirstBrowser is called. - if (!browser()) { - added_observer.Wait(); - SelectFirstBrowser(); + content::RunAllTasksUntilIdle(); + // Launching with an app opens the app window via a task, so the test + // might start before SelectFirstBrowser is called. + if (!browser()) { + added_observer.Wait(); + SelectFirstBrowser(); + } } ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); // An app window should have been launched. EXPECT_TRUE(browser()->is_type_app()); - CloseBrowserAsynchronously(browser()); + CloseBrowserSynchronously(browser()); } // TODO(crbug.com/327256043): Flaky on win @@ -2445,6 +2451,9 @@ void SetUpCommandLine(base::CommandLine* command_line) override {} WebAppProvider& provider() { return *WebAppProvider::GetForTest(profile()); } + + private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; }; IN_PROC_BROWSER_TEST_F(StartupBrowserWithRealWebAppTest, @@ -2658,6 +2667,8 @@ last_opened_profiles); } + private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; base::test::ScopedFeatureList scoped_feature_list_; #if BUILDFLAG(IS_WIN) // This is needed to stop StartupBrowserWebAppProtocolHandlingTests creating a @@ -3525,7 +3536,7 @@ policy_provider_.UpdateChromePolicy(policies); } } - + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_provider_; };
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc index 75158e5ea..7b546ec 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc +++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc
@@ -114,7 +114,8 @@ std::unique_ptr<ui::DialogModel> SavedTabGroupUtils::CreateSavedTabGroupContextMenuModel( Browser* browser, - const base::Uuid& saved_guid) { + const base::Uuid& saved_guid, + bool show_pin_unpin_option) { const auto* const service = SavedTabGroupServiceFactory::GetForProfile(browser->profile()); const auto* const saved_group = service->model()->Get(saved_guid); @@ -152,7 +153,7 @@ .SetId(kMoveGroupToNewWindowMenuItem) .SetIsEnabled(should_enable_move_menu_item)); - if (tab_groups::IsTabGroupsSaveUIUpdateEnabled()) { + if (tab_groups::IsTabGroupsSaveUIUpdateEnabled() && show_pin_unpin_option) { dialog_model.AddMenuItem( ui::ImageModel::FromVectorIcon(saved_group->is_pinned() ? kKeepPinFilledChromeRefreshIcon
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h index 0692abd..decf5409 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h +++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h
@@ -58,9 +58,12 @@ // Create the the context menu model for a saved tab group button or a saved // tab group menu item in the Everything menu. `browser` is the one from // which this method is invoked. `saved_guid` is the saved tab group's Uuid. + // Show a "Pin / Unpin group from bookmarks bar" option if + // `show_pin_unpin_option` is true. static std::unique_ptr<ui::DialogModel> CreateSavedTabGroupContextMenuModel( Browser* browser, - const base::Uuid& saved_guid); + const base::Uuid& saved_guid, + bool show_pin_unpin_option); // Converts a webcontents into a SavedTabGroupTab. static SavedTabGroupTab CreateSavedTabGroupTabFromWebContents(
diff --git a/chrome/browser/ui/tabs/tab_strip_model_browsertest.cc b/chrome/browser/ui/tabs/tab_strip_model_browsertest.cc index 658e00f7..a35db1e 100644 --- a/chrome/browser/ui/tabs/tab_strip_model_browsertest.cc +++ b/chrome/browser/ui/tabs/tab_strip_model_browsertest.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/prevent_close_test_base.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_id_constants.h" @@ -93,6 +94,7 @@ (override)); protected: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; base::ScopedObservation<TabStripModel, TabStripModelPreventCloseTest> observer_{this}; };
diff --git a/chrome/browser/ui/test/test_browser_ui.cc b/chrome/browser/ui/test/test_browser_ui.cc index 40456e2..88dad994 100644 --- a/chrome/browser/ui/test/test_browser_ui.cc +++ b/chrome/browser/ui/test/test_browser_ui.cc
@@ -32,6 +32,10 @@ #include "ui/views/widget/widget.h" #endif +#if BUILDFLAG(IS_WIN) +#include "ui/events/platform/platform_event_source.h" +#endif + // TODO(crbug.com/40625383) support Mac for pixel tests. // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete. @@ -64,10 +68,24 @@ view->GetWidget()->GetNativeWindow()->GetRootWindow()); generator.MoveMouseTo({0, 0}); cursor_client_->DisableMouseEvents(); +#if BUILDFLAG(IS_WIN) + // On Windows, cursor client disable isn't consistently respected, and it's + // also used to handle touch -> mouse event translation, so use this + // instead. See crbug.com/333846475 for an example of the problem this + // solves. + ui::PlatformEventSource::SetIgnoreNativePlatformEvents(true); +#endif } + ScopedMouseDisabler(const ScopedMouseDisabler&) = delete; const ScopedMouseDisabler operator=(const ScopedMouseDisabler&) = delete; - ~ScopedMouseDisabler() { cursor_client_->EnableMouseEvents(); } + + ~ScopedMouseDisabler() { +#if BUILDFLAG(IS_WIN) + ui::PlatformEventSource::SetIgnoreNativePlatformEvents(false); +#endif + cursor_client_->EnableMouseEvents(); + } private: raw_ptr<aura::client::CursorClient> cursor_client_; @@ -112,7 +130,7 @@ return ui::test::ActionResult::kNotAttempted; } - // Disable and hide cursor to prvent any interference with the + // Disable and hide cursor to prevent any interference with the // screenshots. ScopedMouseDisabler disable(view);
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index 9109cad..ba46618 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -95,6 +95,7 @@ #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" #include "components/profile_metrics/browser_profile_type.h" +#include "components/saved_tab_groups/features.h" #include "components/signin/public/base/signin_metrics.h" #include "components/signin/public/base/signin_pref_names.h" #include "components/signin/public/identity_manager/identity_manager.h" @@ -145,6 +146,7 @@ using content::WebContents; DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(AppMenuModel, kBookmarksMenuItem); +DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(AppMenuModel, kTabGroupsMenuItem); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(AppMenuModel, kDownloadsMenuItem); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(AppMenuModel, kHistoryMenuItem); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(AppMenuModel, kExtensionsMenuItem); @@ -1732,6 +1734,18 @@ SetElementIdentifierAt(GetIndexOfCommandId(IDC_BOOKMARKS_MENU).value(), kBookmarksMenuItem); } + + if (tab_groups::IsTabGroupsSaveUIUpdateEnabled() && + browser_->profile()->IsRegularProfile()) { + auto saved_tab_groups_model = std::make_unique<ui::SimpleMenuModel>(this); + sub_menus_.push_back(std::move(saved_tab_groups_model)); + AddSubMenuWithStringId(IDC_SAVED_TAB_GROUPS_MENU, IDS_SAVED_TAB_GROUPS_MENU, + sub_menus_.back().get()); + SetElementIdentifierAt( + GetIndexOfCommandId(IDC_SAVED_TAB_GROUPS_MENU).value(), + kTabGroupsMenuItem); + } + WebContents* web_contents = browser_->tab_strip_model()->GetActiveWebContents(); if (!browser_->profile()->IsOffTheRecord() && web_contents && @@ -1932,6 +1946,8 @@ SetCommandIcon(this, IDC_RECENT_TABS_MENU, kHistoryIcon); SetCommandIcon(this, IDC_SHOW_DOWNLOADS, kDownloadMenuIcon); SetCommandIcon(this, IDC_BOOKMARKS_MENU, kBookmarksListsMenuIcon); + SetCommandIcon(this, IDC_SAVED_TAB_GROUPS_MENU, + kSavedTabGroupBarEverythingIcon); SetCommandIcon(this, IDC_VIEW_PASSWORDS, vector_icons::kPasswordManagerIcon); SetCommandIcon(this, IDC_ZOOM_MENU, kZoomInIcon);
diff --git a/chrome/browser/ui/toolbar/app_menu_model.h b/chrome/browser/ui/toolbar/app_menu_model.h index c477fba..307c007 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.h +++ b/chrome/browser/ui/toolbar/app_menu_model.h
@@ -164,6 +164,7 @@ public ui::ButtonMenuItemModel::Delegate { public: DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kBookmarksMenuItem); + DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kTabGroupsMenuItem); DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kDownloadsMenuItem); DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kHistoryMenuItem); DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kExtensionsMenuItem); @@ -182,14 +183,15 @@ // varies depending upon the underlying model. The command IDs for items in // these menus will be staggered and each increment by this value, so they // don't have conflicts. Currently, this accounts for the bookmarks, recent - // tabs menus, and the profile submenu. - static constexpr int kNumUnboundedMenuTypes = 3; + // tabs menus, the profile submenu and tab groups submenu. + static constexpr int kNumUnboundedMenuTypes = 4; // First command ID to use for each unbounded menu. These should be staggered, // and there should be kNumUnboundedMenuTypes of them. static constexpr int kMinBookmarksCommandId = IDC_FIRST_UNBOUNDED_MENU; static constexpr int kMinRecentTabsCommandId = kMinBookmarksCommandId + 1; static constexpr int kMinOtherProfileCommandId = kMinRecentTabsCommandId + 1; + static constexpr int kMinTabGroupsCommandId = kMinOtherProfileCommandId + 1; // Creates an app menu model for the given browser. Init() must be called // before passing this to an AppMenu. |app_menu_icon_controller|, if provided,
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc index b31e533..38fc067 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc
@@ -256,7 +256,7 @@ } everything_menu_ = std::make_unique<STGEverythingMenu>( - overflow_button_->button_controller(), GetWidget(), browser_); + overflow_button_->button_controller(), browser_); everything_menu_->RunMenu(); }
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc index 55f2520..391ae15 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc
@@ -168,8 +168,7 @@ public: void SetUp() override { SavedTabGroupBarUnitTest::SetUp(); - everything_menu_ = - std::make_unique<STGEverythingMenu>(nullptr, nullptr, browser()); + everything_menu_ = std::make_unique<STGEverythingMenu>(nullptr, browser()); } void TearDown() override {
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc index 4e1e5ec..93c0bf9 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_button.cc
@@ -97,7 +97,8 @@ base::BindRepeating( &SavedTabGroupUtils::CreateSavedTabGroupContextMenuModel, browser, - group.saved_guid()), + group.saved_guid(), + /*show_pin_unpin_option=*/true), views::MenuRunner::CONTEXT_MENU | views::MenuRunner::IS_NESTED) { SetAccessibilityProperties( ax::mojom::Role::kButton, /*name=*/GetAccessibleNameForButton(),
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.cc index ab03707..654537c 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.cc
@@ -25,9 +25,25 @@ DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(STGEverythingMenu, kTabGroup); STGEverythingMenu::STGEverythingMenu(views::MenuButtonController* controller, - views::Widget* widget, Browser* browser) - : menu_button_controller_(controller), browser_(browser), widget_(widget) {} + : menu_button_controller_(controller), + browser_(browser), + widget_(views::Widget::GetWidgetForNativeWindow( + browser->window()->GetNativeWindow())) {} + +int STGEverythingMenu::GetAndIncrementNextTabGroupItemID() { + const int current_id = next_tab_group_item_command_id_; + next_tab_group_item_command_id_ += AppMenuModel::kNumUnboundedMenuTypes; + return current_id; +} + +const SavedTabGroup* STGEverythingMenu::GetTabGroupForCommandId( + int command_id) { + const int idx_in_sorted_tab_group = + (command_id - AppMenuModel::kMinTabGroupsCommandId) / + AppMenuModel::kNumUnboundedMenuTypes; + return sorted_tab_groups_[idx_in_sorted_tab_group]; +} const SavedTabGroupModel* STGEverythingMenu::GetSavedTabGroupModelFromBrowser() { @@ -81,8 +97,9 @@ const auto title = tab_group->title(); // For saved tab group items, use the indice in `sorted_tab_groups_` as the // command ids. + const int command_id = GetAndIncrementNextTabGroupItemID(); menu_model->AddItemWithIcon( - i /*command_id*/, + command_id, title.empty() ? l10n_util::GetPluralStringFUTF16( IDS_SAVED_TAB_GROUP_TABS_COUNT, static_cast<int>(tab_group->saved_tabs().size())) @@ -91,18 +108,22 @@ // Set the first tab group item with element id `kTabGroup`. if (i == 0) { menu_model->SetElementIdentifierAt( - menu_model->GetIndexOfCommandId(0).value(), kTabGroup); + menu_model->GetIndexOfCommandId(command_id).value(), kTabGroup); } } return menu_model; } void STGEverythingMenu::PopulateMenu(views::MenuItemView* parent) { + if (parent->HasSubmenu()) { + parent->GetSubmenu()->RemoveAllChildViews(); + } model_ = CreateMenuModel(); for (size_t i = 0, max = model_->GetItemCount(); i < max; ++i) { views::MenuModelAdapter::AppendMenuItemFromModel(model_.get(), i, parent, model_->GetCommandIdAt(i)); } + parent->GetSubmenu()->InvalidateLayout(); } void STGEverythingMenu::RunMenu() { @@ -120,7 +141,7 @@ if (command_id == IDC_CREATE_NEW_TAB_GROUP) { browser_->command_controller()->ExecuteCommand(command_id); } else { - const auto* const group = sorted_tab_groups_[command_id]; + const auto* const group = GetTabGroupForCommandId(command_id); if (group->saved_tabs().empty()) { return; } @@ -138,13 +159,13 @@ return false; } - const auto* const group = sorted_tab_groups_[command_id]; + const auto* const group = GetTabGroupForCommandId(command_id); context_menu_controller_ = std::make_unique<views::DialogModelContextMenuController>( widget_->GetRootView(), base::BindRepeating( &SavedTabGroupUtils::CreateSavedTabGroupContextMenuModel, - browser_, group->saved_guid()), + browser_, group->saved_guid(), show_pin_unpin_option_), views::MenuRunner::CONTEXT_MENU | views::MenuRunner::IS_NESTED); context_menu_controller_->ShowContextMenuForViewImpl(widget_->GetRootView(), p, source_type);
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.h b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.h index 5cae5ff..78a22fd 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.h +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.h
@@ -6,11 +6,14 @@ #define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_EVERYTHING_MENU_H_ #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/toolbar/app_menu_model.h" +#include "components/saved_tab_groups/features.h" #include "components/saved_tab_groups/saved_tab_group_model.h" #include "ui/base/models/simple_menu_model.h" #include "ui/views/controls/button/menu_button_controller.h" #include "ui/views/controls/menu/menu_delegate.h" #include "ui/views/controls/menu/menu_item_view.h" +#include "ui/views/controls/menu/submenu_view.h" #include "ui/views/dialog_model_context_menu_controller.h" namespace tab_groups { @@ -25,7 +28,6 @@ DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kTabGroup); STGEverythingMenu(views::MenuButtonController* menu_button_controller, - views::Widget* widget, Browser* browser); STGEverythingMenu(const STGEverythingMenu&) = delete; @@ -43,9 +45,22 @@ bool IsShowing() { return menu_runner_ && menu_runner_->IsRunning(); } + void SetShowPinOption(bool show_pin_unpin_option) { + show_pin_unpin_option_ = show_pin_unpin_option; + } + + // override views::MenuDelegate: + void ExecuteCommand(int command_id, int event_flags) override; + bool ShowContextMenu(views::MenuItemView* source, + int command_id, + const gfx::Point& p, + ui::MenuSourceType source_type) override; + private: friend class STGEverythingMenuUnitTest; + int GetAndIncrementNextTabGroupItemID(); + const SavedTabGroup* GetTabGroupForCommandId(int command_id); std::unique_ptr<ui::SimpleMenuModel> CreateMenuModel(); // Returns sorted saved tab groups with the most recently created as the @@ -55,24 +70,26 @@ const SavedTabGroupModel* GetSavedTabGroupModelFromBrowser(); - // override views::MenuDelegate: - void ExecuteCommand(int command_id, int event_flags) override; - bool ShowContextMenu(views::MenuItemView* source, - int command_id, - const gfx::Point& p, - ui::MenuSourceType source_type) override; - // Saved tab groups with the most recently created as the first. std::vector<const SavedTabGroup*> sorted_tab_groups_; // Owned by the Everything button. raw_ptr<views::MenuButtonController> menu_button_controller_; + // Whether or not the submenu of a tab group item should have "Pin/Unpin group + // from bookmarks bar" option. True by default. False if the submenu if + // visually far away from the bookmark bar e.g. in 3-dot menu. + bool show_pin_unpin_option_ = true; + // The convenient controller that runs a context menu for saved tab group menu // items. std::unique_ptr<views::DialogModelContextMenuController> context_menu_controller_; + // TODO(pengchaocai): Explore a generic command id solution if there are more + // use cases than app menu. + int next_tab_group_item_command_id_ = AppMenuModel::kMinTabGroupsCommandId; + std::unique_ptr<views::MenuRunner> menu_runner_; std::unique_ptr<ui::SimpleMenuModel> model_; raw_ptr<Browser> browser_;
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_interactive_uitest.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_interactive_uitest.cc index d4f76f5..98c295bc 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_interactive_uitest.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_interactive_uitest.cc
@@ -362,7 +362,40 @@ WaitForShow(SavedTabGroupUtils::kMoveGroupToNewWindowMenuItem)); } -// TODO(crbug.com/40934084): Deflake this test before enabling +// TODO(crbug.com/333956456): Resolve before enabling. +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#define MAYBE_ContextMenuShowForAppMenuSubmenu \ + DISABLED_ContextMenuShowForAppMenuSubmenu +#else +#define MAYBE_ContextMenuShowForAppMenuSubmenu ContextMenuShowForAppMenuSubmenu +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) +IN_PROC_BROWSER_TEST_P(SavedTabGroupInteractiveTest, + MAYBE_ContextMenuShowForAppMenuSubmenu) { + if (!IsV2UIEnabled()) { + GTEST_SKIP() << "N/A for V1"; + } + + ASSERT_TRUE( + AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_TYPED)); + ASSERT_EQ(2, browser()->tab_strip_model()->count()); + + const tab_groups::TabGroupId local_group_id = + browser()->tab_strip_model()->AddToNewGroup({0}); + + RunTestSequence( + FinishTabstripAnimations(), ShowBookmarksBar(), + SaveGroupAndCloseEditorBubble(local_group_id), + WaitForHide(kTabGroupEditorBubbleId), + PressButton(kToolbarAppMenuButtonElementId), + WaitForShow(AppMenuModel::kTabGroupsMenuItem), + SelectMenuItem(AppMenuModel::kTabGroupsMenuItem), + WaitForShow(STGEverythingMenu::kTabGroup), + MoveMouseTo(STGEverythingMenu::kTabGroup), ClickMouse(ui_controls::RIGHT), + WaitForShow(SavedTabGroupUtils::kDeleteGroupMenuItem), + WaitForShow(SavedTabGroupUtils::kMoveGroupToNewWindowMenuItem)); +} + +// TODO(crbug.com/1487362): Deflake this test before enabling #if BUILDFLAG(IS_MAC) #define MAYBE_MoveGroupToNewWindowFromButtonMenu \ DISABLED_MoveGroupToNewWindowFromButtonMenu @@ -638,6 +671,90 @@ } IN_PROC_BROWSER_TEST_P(SavedTabGroupInteractiveTest, + CreateNewTabGroupFromAppMenuSubmenu) { + if (!IsV2UIEnabled()) { + GTEST_SKIP() << "N/A for V1"; + } + const bool is_v2_ui_enabled = IsV2UIEnabled(); + + RunTestSequence( + FinishTabstripAnimations(), ShowBookmarksBar(), + CheckEverythingButtonVisibility(is_v2_ui_enabled), + CheckResult([&]() { return browser()->tab_strip_model()->count(); }, 1), + EnsureNotPresent(kTabGroupEditorBubbleId), + PressButton(kToolbarAppMenuButtonElementId), + WaitForShow(AppMenuModel::kTabGroupsMenuItem), + SelectMenuItem(AppMenuModel::kTabGroupsMenuItem), + WaitForShow(STGEverythingMenu::kCreateNewTabGroup), + SelectMenuItem(STGEverythingMenu::kCreateNewTabGroup), + FinishTabstripAnimations(), FlushEvents(), + WaitForShow(kTabGroupEditorBubbleId), + CheckResult([&]() { return browser()->tab_strip_model()->count(); }, 2), + // This menu item opens a new tab and the editor bubble. + CheckResult( + [&]() { return browser()->tab_strip_model()->active_index(); }, 1), + CheckResult( + [&]() { + return browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetVisibleURL() + .host_piece(); + }, + chrome::kChromeUINewTabHost)); +} + +IN_PROC_BROWSER_TEST_P(SavedTabGroupInteractiveTest, + OpenSavedGroupFromAppMenuSubmenu) { + if (!IsV2UIEnabled()) { + GTEST_SKIP() << "N/A for V1"; + } + + ASSERT_TRUE( + AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_TYPED)); + ASSERT_TRUE( + AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_TYPED)); + ASSERT_EQ(3, browser()->tab_strip_model()->count()); + + // Add 2 tabs to the group. + const tab_groups::TabGroupId local_group_id = + browser()->tab_strip_model()->AddToNewGroup({0, 1}); + const SavedTabGroupKeyedService* const service = + SavedTabGroupServiceFactory::GetForProfile(browser()->profile()); + + base::Uuid saved_guid; + + RunTestSequence( + FinishTabstripAnimations(), ShowBookmarksBar(), + // Save the group and ensure it is linked in the model. + SaveGroupLeaveEditorBubbleOpen(local_group_id), + // The group we just saved should be the only group in the model. + CheckResult([&]() { return service->model()->Count(); }, 1), + // Find the saved guid that is linked to the group we just saved. + Do([&]() { + const SavedTabGroup& saved_group = + service->model()->saved_tab_groups()[0]; + ASSERT_TRUE(saved_group.local_group_id().has_value()); + saved_guid = saved_group.saved_guid(); + }), + // Make sure the editor bubble is still open and flush events before we + // close it. + EnsurePresent(kTabGroupEditorBubbleId), FlushEvents(), + // Close the tab group and expect the saved group is no longer linked. + PressButton(kTabGroupEditorBubbleCloseGroupButtonId), + FinishTabstripAnimations(), CheckIfSavedGroupIsClosed(&saved_guid), + WaitForHide(kTabGroupHeaderElementId), + // Open the saved tab group from the submenu of "Tab groups" item in app + // menu. + PressButton(kToolbarAppMenuButtonElementId), + WaitForShow(AppMenuModel::kTabGroupsMenuItem), + SelectMenuItem(AppMenuModel::kTabGroupsMenuItem), + WaitForShow(STGEverythingMenu::kTabGroup), + SelectMenuItem(STGEverythingMenu::kTabGroup), FinishTabstripAnimations(), + WaitForShow(kTabGroupHeaderElementId)); +} + +IN_PROC_BROWSER_TEST_P(SavedTabGroupInteractiveTest, EverythingButtonAlwaysShowsForV2) { const tab_groups::TabGroupId group_id = browser()->tab_strip_model()->AddToNewGroup({0});
diff --git a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_browsertest.cc index 165eb11..e0782b3 100644 --- a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_browsertest.cc
@@ -6,6 +6,7 @@ #include "base/functional/callback_helpers.h" #include "base/run_loop.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/extensions/browsertest_util.h" #include "chrome/browser/extensions/extension_service.h" @@ -20,6 +21,7 @@ #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/test/base/in_process_browser_test.h" @@ -211,6 +213,13 @@ ->extension_service() ->AddExtension(extension.get()); + std::unique_ptr<web_app::OsIntegrationTestOverrideBlockingRegistration> + faked_os_integration; + { + base::ScopedAllowBlockingForTesting blocking; + faked_os_integration = std::make_unique< + web_app::OsIntegrationTestOverrideBlockingRegistration>(); + } const GURL start_url = GURL("https://test.com/"); auto web_app_info = std::make_unique<web_app::WebAppInstallInfo>(); web_app_info->start_url = start_url; @@ -239,6 +248,11 @@ extensions::UNINSTALL_SOURCE_FOR_TESTING); run_loop.RunUntilIdle(); } + + { + base::ScopedAllowBlockingForTesting blocking; + faked_os_integration.reset(); + } } class ParameterizedExtensionUninstallDialogViewBrowserTest
diff --git a/chrome/browser/ui/views/frame/browser_frame_browsertest.cc b/chrome/browser/ui/views/frame/browser_frame_browsertest.cc index 6cf6cfd..180bc95 100644 --- a/chrome/browser/ui/views/frame/browser_frame_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_frame_browsertest.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/ui/views/chrome_views_delegate.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/common/pref_names.h" @@ -71,6 +72,9 @@ public: BrowserFrameTest() : InProcessBrowserTest(std::make_unique<BrowserFrameBoundsChecker>()) {} + + private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; }; // Verifies that the tools are loaded with initial bounds.
diff --git a/chrome/browser/ui/views/frame/browser_frame_view_browsertest_win.cc b/chrome/browser/ui/views/frame/browser_frame_view_browsertest_win.cc index 99cdc8a..3e21809f 100644 --- a/chrome/browser/ui/views/frame/browser_frame_view_browsertest_win.cc +++ b/chrome/browser/ui/views/frame/browser_frame_view_browsertest_win.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/frame/browser_frame_view_win.h" - #include <tuple> #include "base/files/file_util.h" @@ -17,6 +15,7 @@ #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/app_menu_button.h" #include "chrome/browser/ui/views/frame/browser_caption_button_container_win.h" +#include "chrome/browser/ui/views/frame/browser_frame_view_win.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/windows_caption_button.h" #include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_test_helper.h" @@ -25,6 +24,7 @@ #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/browser/win/titlebar_config.h" @@ -188,6 +188,9 @@ nullptr; raw_ptr<WebAppFrameToolbarView, AcrossTasksDanglingUntriaged> web_app_frame_toolbar_ = nullptr; + + private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; }; IN_PROC_BROWSER_TEST_F(WebAppBrowserFrameViewWinTest, ThemeColor) { @@ -336,6 +339,7 @@ WebAppFrameToolbarTestHelper web_app_frame_toolbar_helper_; private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; base::ScopedTempDir temp_dir_; };
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc index dfcaebe6..a97f12c 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/ui/views/location_bar/custom_tab_bar_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/browser/web_applications/web_app_install_utils.h" @@ -124,6 +125,8 @@ private: GURL GetAppURL() { return embedded_test_server()->GetURL("/empty.html"); } + + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; }; // Tests the frame color for a normal browser window.
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc index ffe4f16..d245286 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
@@ -24,6 +24,7 @@ #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/test/base/in_process_browser_test.h" @@ -139,6 +140,7 @@ theme_mode == ThemeMode::kDefault); } + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; raw_ptr<BrowserView, AcrossTasksDanglingUntriaged> browser_view_ = nullptr; raw_ptr<OpaqueBrowserFrameView, AcrossTasksDanglingUntriaged> opaque_browser_frame_view_ = nullptr; @@ -338,6 +340,7 @@ WebAppFrameToolbarTestHelper web_app_frame_toolbar_helper_; private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; base::ScopedTempDir temp_dir_; };
diff --git a/chrome/browser/ui/views/infobars/default_browser_infobar_interactive_uitest.cc b/chrome/browser/ui/views/infobars/default_browser_infobar_interactive_uitest.cc index 4fc336c..0228345 100644 --- a/chrome/browser/ui/views/infobars/default_browser_infobar_interactive_uitest.cc +++ b/chrome/browser/ui/views/infobars/default_browser_infobar_interactive_uitest.cc
@@ -142,8 +142,15 @@ InSameContext(EnsureNotPresent(ConfirmInfoBar::kInfoBarElementId))); } +// TODO(crbug.com/335474941): Flaky on Windows. +#if BUILDFLAG(IS_WIN) +#define MAYBE_RemovesAllBrowserPromptsOnAccept \ + DISABLED_RemovesAllBrowserPromptsOnAccept +#else +#define MAYBE_RemovesAllBrowserPromptsOnAccept RemovesAllBrowserPromptsOnAccept +#endif IN_PROC_BROWSER_TEST_F(DefaultBrowserInfobarWithRefreshInteractiveTest, - RemovesAllBrowserPromptsOnAccept) { + MAYBE_RemovesAllBrowserPromptsOnAccept) { DefaultBrowserPromptManager::GetInstance()->MaybeShowPrompt(); RunTestSequence( WaitForShow(ConfirmInfoBar::kInfoBarElementId), FlushEvents(), @@ -172,8 +179,16 @@ } #endif +// TODO(crbug.com/335474941): Flaky on Windows. +#if BUILDFLAG(IS_WIN) +#define MAYBE_HandlesAcceptWithDisabledAnimation \ + DISABLED_HandlesAcceptWithDisabledAnimation +#else +#define MAYBE_HandlesAcceptWithDisabledAnimation \ + HandlesAcceptWithDisabledAnimation +#endif IN_PROC_BROWSER_TEST_F(DefaultBrowserInfobarWithRefreshInteractiveTest, - HandlesAcceptWithDisabledAnimation) { + MAYBE_HandlesAcceptWithDisabledAnimation) { // When animations are disabled, the info bar is destroyed sooner which can // cause UAF if not handled properly. This test ensures it is handled // properly. @@ -200,8 +215,14 @@ WaitForHide(ConfirmInfoBar::kInfoBarElementId)); } +// TODO(crbug.com/335474941): Flaky on Windows. +#if BUILDFLAG(IS_WIN) +#define MAYBE_LogsMetrics DISABLED_LogsMetrics +#else +#define MAYBE_LogsMetrics LogsMetrics +#endif IN_PROC_BROWSER_TEST_F(DefaultBrowserInfobarWithRefreshInteractiveTest, - LogsMetrics) { + MAYBE_LogsMetrics) { base::HistogramTester histogram_tester; DefaultBrowserPromptManager::GetInstance()->MaybeShowPrompt(); RunTestSequence(WaitForShow(ConfirmInfoBar::kInfoBarElementId),
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc index cd4caf0..fea2b16 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc
@@ -951,7 +951,7 @@ webapps::AppId app_id_; // Stop test from installing OS hooks. - web_app::OsIntegrationManager::ScopedSuppressForTesting os_hooks_suppress_; + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; }; // Test renamed, as currently Skia Gold doesn't support resetting test
diff --git a/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_interactive_uitest.cc b/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_interactive_uitest.cc index fc05c48..ea43fc7 100644 --- a/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_interactive_uitest.cc +++ b/chrome/browser/ui/views/site_data/page_specific_site_data_dialog_interactive_uitest.cc
@@ -402,26 +402,6 @@ ~PageSpecificSiteDataDialogIsolatedWebAppInteractiveUiTest() override = default; - void SetUpOnMainThread() override { -#if !BUILDFLAG(IS_MAC) - // TODO(crbug.com/40272260): OsIntegrationTestOverrideImpl seems - // to interfere with Kombucha on the Mac. - base::ScopedAllowBlockingForTesting allow_blocking; - override_registration_ = - web_app::OsIntegrationTestOverrideImpl::OverrideForTesting(); -#endif // BUILDFLAG(IS_MAC) - PageSpecificSiteDataDialogInteractiveUiTest::SetUpOnMainThread(); - } - void TearDownOnMainThread() override { - web_app::test::UninstallWebApp(browser()->profile(), app_id_); - -#if !BUILDFLAG(IS_MAC) - base::ScopedAllowBlockingForTesting allow_blocking; - override_registration_.reset(); -#endif // BUILDFLAG(IS_MAC) - PageSpecificSiteDataDialogInteractiveUiTest::TearDownOnMainThread(); - } - protected: void SetUpFeatureList() override { feature_list_.InitWithFeatures( @@ -474,16 +454,22 @@ private: webapps::AppId app_id_; -#if !BUILDFLAG(IS_MAC) - std::unique_ptr< - ::web_app::OsIntegrationTestOverrideImpl::BlockingRegistration> + web_app::OsIntegrationTestOverrideImpl::BlockingRegistration override_registration_; -#endif // !BUILDFLAG(IS_MAC) }; +// TODO(crbug.com/40776475): This test fails to pass on Mac with real app shims +// working. +#if BUILDFLAG(IS_MAC) +#define MAYBE_AppNameIsDisplayedInsteadOfHostname \ + DISABLED_AppNameIsDisplayedInsteadOfHostname +#else +#define MAYBE_AppNameIsDisplayedInsteadOfHostname \ + AppNameIsDisplayedInsteadOfHostname +#endif // BUILDFLAG(IS_MAC) IN_PROC_BROWSER_TEST_F( PageSpecificSiteDataDialogIsolatedWebAppInteractiveUiTest, - AppNameIsDisplayedInsteadOfHostname) { + MAYBE_AppNameIsDisplayedInsteadOfHostname) { Browser* iwa_browser = InstallAndLaunchIsolatedWebApp(); RunTestSequenceInContext( iwa_browser->window()->GetElementContext(),
diff --git a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc index 19bc0461..8dcc8f73 100644 --- a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc +++ b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc
@@ -61,10 +61,6 @@ return nullptr; } -bool FakeTabSlotController::ShowDomainInHoverCards() const { - return true; -} - bool FakeTabSlotController::HoverCardIsShowingForTab(Tab* tab) { return false; }
diff --git a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h index a309ac7..980f955 100644 --- a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h +++ b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h
@@ -68,7 +68,6 @@ void OnMouseEventInTab(views::View* source, const ui::MouseEvent& event) override {} void UpdateHoverCard(Tab* tab, HoverCardUpdateType update_type) override {} - bool ShowDomainInHoverCards() const override; bool HoverCardIsShowingForTab(Tab* tab) override; int GetBackgroundOffset() const override; int GetStrokeThickness() const override;
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index 0bd51294..146c8621 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -49,6 +49,7 @@ #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/tabs/window_finder.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" @@ -3182,6 +3183,7 @@ } private: + web_app::OsIntegrationTestOverrideBlockingRegistration faked_os_integration_; base::test::ScopedFeatureList scoped_feature_list_; };
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index b3b8bba..2531327a 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -28,11 +28,8 @@ #include "chrome/browser/ui/views/tabs/fade_label_view.h" #include "chrome/browser/ui/views/tabs/filename_elider.h" #include "chrome/browser/ui/views/tabs/tab.h" -#include "chrome/browser/ui/views/tabs/tab_hover_card_controller.h" #include "chrome/browser/ui/views/tabs/tab_style_views.h" -#include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" -#include "components/prefs/pref_service.h" #include "components/url_formatter/url_formatter.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" @@ -138,6 +135,10 @@ SetLayoutManager(std::make_unique<views::FillLayout>()); } + void SetAnimationEnabled(bool animation_enabled) { + animation_enabled_ = animation_enabled; + } + // Sets the appropriate rounded corners for the preview image, for platforms // where layers must be explicitly clipped (because they are not clipped by // the widget). @@ -283,7 +284,9 @@ return; } - if (!GetPreviewImageCrossfadeStart().has_value()) { + // For consistency, always bail out with a "don't crossfade" response if + // animations are disabled. + if (!animation_enabled_ || !GetPreviewImageCrossfadeStart().has_value()) { return; } @@ -320,6 +323,8 @@ const raw_ptr<TabHoverCardBubbleView> bubble_view_; + bool animation_enabled_ = true; + // Displays the image that we are trying to display for the target/current // tab. Placed under `image_fading_out_` so that it is revealed as the // previous image fades out. @@ -351,12 +356,16 @@ DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(TabHoverCardBubbleView, kHoverCardBubbleElementId); +DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(TabHoverCardBubbleView, + kHoverCardDomainLabelElementId); -TabHoverCardBubbleView::TabHoverCardBubbleView(Tab* tab) +TabHoverCardBubbleView::TabHoverCardBubbleView(Tab* tab, + const InitParams& params) : BubbleDialogDelegateView(tab, views::BubbleBorder::TOP_LEFT, views::BubbleBorder::STANDARD_SHADOW), - tab_style_(TabStyle::Get()) { + tab_style_(TabStyle::Get()), + bubble_params_(params) { SetButtons(ui::DIALOG_BUTTON_NONE); // Remove the accessible role so that hover cards are not read when they @@ -393,8 +402,9 @@ 1, views::style::CONTEXT_DIALOG_BODY_TEXT)); } - if (TabHoverCardController::AreHoverCardImagesEnabled()) { + if (bubble_params_.show_image_preview) { thumbnail_view_ = AddChildView(std::make_unique<ThumbnailView>(this)); + thumbnail_view_->SetAnimationEnabled(bubble_params_.use_animation); thumbnail_view_->SetRoundedCorners(true, corner_radius_); } @@ -405,14 +415,6 @@ footer_view_->flex_layout()->GetDefaultFlexRule()) .WithWeight(0)); - OnMemoryUsageInHovercardsPrefChanged(); - pref_change_registrar_.Init(g_browser_process->local_state()); - pref_change_registrar_.Add( - prefs::kHoverCardMemoryUsageEnabled, - base::BindRepeating( - &TabHoverCardBubbleView::OnMemoryUsageInHovercardsPrefChanged, - base::Unretained(this))); - // Set up layout. views::FlexLayout* const layout = @@ -426,12 +428,13 @@ // label. In those cases, we need to adjust the bottom margin of the title // element because it is no longer above another text element and needs a // bottom margin. - const bool show_domain = tab->controller()->ShowDomainInHoverCards(); gfx::Insets title_margins = features::IsChromeRefresh2023() ? kTextAreaRefreshMargins : kTitleMargins; - domain_label_->SetVisible(show_domain); - if (show_domain) { + domain_label_->SetVisible(bubble_params_.show_domain); + domain_label_->SetProperty(views::kElementIdentifierKey, + kHoverCardDomainLabelElementId); + if (bubble_params_.show_domain) { gfx::Insets domain_margins = title_margins; domain_margins.set_top(features::IsChromeRefresh2023() ? kTitleDomainSpacing : 0); @@ -561,7 +564,7 @@ // High memory usage notification is considered a tab alert. Show it even // if the memory usage in hovercards pref is disabled. const bool show_memory_usage = - (memory_usage_in_hovercards_setting_ && tab_memory_usage_in_bytes > 0) || + (bubble_params_.show_memory_usage && tab_memory_usage_in_bytes > 0) || is_high_memory_usage; bool show_footer = alert_state_.has_value() || show_discard_status || show_memory_usage; @@ -616,12 +619,6 @@ // static std::optional<double> TabHoverCardBubbleView::GetPreviewImageCrossfadeStart() { - // For consistency, always bail out with a "don't crossfade" response if - // animations are disabled. - if (!TabHoverCardController::UseAnimations()) { - return std::nullopt; - } - static const double start_percent = base::GetFieldTrialParamByFeatureAsDouble( features::kTabHoverCardImages, features::kTabHoverCardImagesCrossfadePreviewAtParameterName, 0.25); @@ -630,12 +627,6 @@ : std::nullopt; } -void TabHoverCardBubbleView::OnMemoryUsageInHovercardsPrefChanged() { - PrefService* const pref_service = g_browser_process->local_state(); - memory_usage_in_hovercards_setting_ = - pref_service->GetBoolean(prefs::kHoverCardMemoryUsageEnabled); -} - gfx::Size TabHoverCardBubbleView::CalculatePreferredSize() const { const int width = tab_style_->GetPreviewImageSize().width(); const int height =
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h index c50e5742..5d8a6b32 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h
@@ -19,7 +19,6 @@ #include "chrome/browser/ui/tabs/tab_utils.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/tabs/fade_footer_view.h" -#include "components/prefs/pref_change_registrar.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/gfx/animation/linear_animation.h" #include "ui/views/animation/animation_delegate_views.h" @@ -46,7 +45,20 @@ base::Milliseconds(200); DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kHoverCardBubbleElementId); - explicit TabHoverCardBubbleView(Tab* tab); + DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kHoverCardDomainLabelElementId); + + struct InitParams { + // Becomes false with certain accessibility options and in tests + bool use_animation = true; + // Becomes false for ChromeOS tabbed system apps (e.g. Terminal) + bool show_domain = true; + // Becomes false when image preview setting is disabled + bool show_image_preview = true; + // Becomes false for ChromeOS system apps or when disabled in settings + bool show_memory_usage = true; + }; + + explicit TabHoverCardBubbleView(Tab* tab, const InitParams& params); TabHoverCardBubbleView(const TabHoverCardBubbleView&) = delete; TabHoverCardBubbleView& operator=(const TabHoverCardBubbleView&) = delete; ~TabHoverCardBubbleView() override; @@ -80,8 +92,6 @@ BackgroundTabHoverCardContentsHaveCorrectDimensions); class ThumbnailView; - void OnMemoryUsageInHovercardsPrefChanged(); - // views::BubbleDialogDelegateView: gfx::Size CalculatePreferredSize() const override; @@ -91,9 +101,8 @@ raw_ptr<FooterView> footer_view_ = nullptr; std::optional<TabAlertState> alert_state_; const raw_ptr<const TabStyle> tab_style_; - PrefChangeRegistrar pref_change_registrar_; - bool memory_usage_in_hovercards_setting_ = false; + const InitParams bubble_params_; int corner_radius_ = ChromeLayoutProvider::Get()->GetCornerRadiusMetric( views::Emphasis::kHigh); };
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc index de0f55e..b0b2cdd 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/ui/views/tabs/tab_hover_card_thumbnail_observer.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" +#include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/common/pref_names.h" #include "components/omnibox/browser/omnibox_edit_model.h" #include "components/omnibox/browser/omnibox_popup_view.h" @@ -145,6 +146,16 @@ return delay; } +bool IsBrowserForSystemWebApp(const Browser* browser) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + const auto* const app_controller = browser->app_controller(); + if (app_controller && app_controller->system_app()) { + return true; + } +#endif + return false; +} + } // anonymous namespace //------------------------------------------------------------------- @@ -210,14 +221,26 @@ base::Value(base::FeatureList::IsEnabled( features::kTabHoverCardImages))); + pref_change_registrar_.Init(pref_service); + // Register for previews enabled pref change events. hover_card_image_previews_enabled_ = AreHoverCardImagesEnabled(); - pref_change_registrar_.Init(pref_service); pref_change_registrar_.Add( prefs::kHoverCardImagesEnabled, base::BindRepeating( &TabHoverCardController::OnHovercardImagesEnabledChanged, base::Unretained(this))); + + // Register for memory usage enabled pref change events. Exclude + // tracking them for system web apps (e.g. ChromeOS terminal app). + if (!IsBrowserForSystemWebApp(tab_strip_->GetBrowser())) { + OnHovercardMemoryUsageEnabledChanged(); + pref_change_registrar_.Add( + prefs::kHoverCardMemoryUsageEnabled, + base::BindRepeating( + &TabHoverCardController::OnHovercardMemoryUsageEnabledChanged, + base::Unretained(this))); + } } // Possibly apply memory pressure override for testing. @@ -500,7 +523,14 @@ } void TabHoverCardController::CreateHoverCard(Tab* tab) { - hover_card_ = new TabHoverCardBubbleView(tab); + TabHoverCardBubbleView::InitParams params; + params.use_animation = UseAnimations(); + // In some browser types (e.g. ChromeOS terminal app) hide the domain label. + params.show_domain = !IsBrowserForSystemWebApp(tab_strip_->GetBrowser()); + params.show_memory_usage = hover_card_memory_usage_enabled_; + params.show_image_preview = hover_card_image_previews_enabled_; + + hover_card_ = new TabHoverCardBubbleView(tab, params); hover_card_observation_.Observe(hover_card_.get()); event_sniffer_ = std::make_unique<EventSniffer>(this); slide_animator_ = std::make_unique<views::BubbleSlideAnimator>(hover_card_); @@ -574,7 +604,8 @@ // The crossfade parameter determines when a placeholder image is displayed. const auto crossfade_at = TabHoverCardBubbleView::GetPreviewImageCrossfadeStart(); - if (crossfade_at.has_value() && crossfade_at.value() == 0.0) { + if (UseAnimations() && crossfade_at.has_value() && + crossfade_at.value() == 0.0) { hover_card_->SetPlaceholderImage(); thumbnail_wait_state_ = ThumbnailWaitState::kWaitingWithPlaceholder; } else { @@ -806,3 +837,9 @@ thumbnail_observer_.reset(); } } + +void TabHoverCardController::OnHovercardMemoryUsageEnabledChanged() { + hover_card_memory_usage_enabled_ = + g_browser_process->local_state()->GetBoolean( + prefs::kHoverCardMemoryUsageEnabled); +}
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller.h b/chrome/browser/ui/views/tabs/tab_hover_card_controller.h index 7292f3e..88ab91d 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_controller.h +++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller.h
@@ -40,13 +40,6 @@ explicit TabHoverCardController(TabStrip* tab_strip); ~TabHoverCardController() override; - // Returns whether the hover card preview images feature is enabled. - static bool AreHoverCardImagesEnabled(); - - // Returns whether hover card animations should be shown on the current - // device. - static bool UseAnimations(); - bool IsHoverCardVisible() const; bool IsHoverCardShowingForTab(Tab* tab) const; void UpdateHoverCard(Tab* tab, @@ -77,7 +70,10 @@ FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest, HidePreviewsForDiscardedTab); FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest, + DisableMemoryUsageForTab); + FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest, ShowPreviewsForDiscardedTabWithThumbnail); + FRIEND_TEST_ALL_PREFIXES(TabHoverCardPreviewsEnabledPrefTest, DefaultState); class EventSniffer; enum ThumbnailWaitState { @@ -86,6 +82,13 @@ kWaitingWithoutPlaceholder }; + // Returns whether the hover card preview images feature is enabled. + static bool AreHoverCardImagesEnabled(); + + // Returns whether hover card animations should be shown on the current + // device. + static bool UseAnimations(); + // views::ViewObserver: void OnViewIsDeleting(views::View* observed_view) override; void OnViewVisibilityChanged(views::View* observed_view, @@ -134,6 +137,7 @@ base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); void OnHovercardImagesEnabledChanged(); + void OnHovercardMemoryUsageEnabledChanged(); bool waiting_for_preview() const { return thumbnail_wait_state_ != ThumbnailWaitState::kNotWaiting; @@ -184,9 +188,10 @@ // resources are up to date when we eventually show the hover card. raw_ptr<TabResourceUsageCollector> tab_resource_usage_collector_; - // Tracks changes to the hover card image previews preferences + // Tracks changes to the hover card preferences PrefChangeRegistrar pref_change_registrar_; bool hover_card_image_previews_enabled_ = false; + bool hover_card_memory_usage_enabled_ = false; // Ensure that this timer is destroyed before anything else is cleaned up. base::OneShotTimer delayed_show_timer_;
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc index 28c224f..a055389 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/tabs/tab_hover_card_controller.h" - #include <memory> #include "base/strings/utf_string_conversions.h" @@ -28,8 +26,12 @@ #include "chrome/browser/ui/views/tabs/tab.h" #include "chrome/browser/ui/views/tabs/tab_close_button.h" #include "chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h" +#include "chrome/browser/ui/views/tabs/tab_hover_card_controller.h" #include "chrome/browser/ui/views/tabs/tab_hover_card_test_util.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" +#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/browser/web_applications/test/web_app_install_test_utils.h" +#include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/pref_names.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/generated_resources.h" @@ -59,6 +61,10 @@ #include "ui/views/test/widget_test.h" #include "url/gurl.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ash/system_web_apps/test_support/test_system_web_app_installation.h" +#endif + namespace { constexpr char16_t kTabTitle[] = u"Test Tab 2"; constexpr char16_t kTabDomain[] = u"example.com"; @@ -799,3 +805,40 @@ All, TabHoverCardFadeFooterInteractiveUiTest, testing::ValuesIn(GetTabHoverCardFooterTestFeatureConfig())); + +#if BUILDFLAG(IS_CHROMEOS_ASH) +class TabHoverCardSystemWebAppTest : public InteractiveBrowserTest { + public: + TabHoverCardSystemWebAppTest() + : test_system_web_app_installation_( + ash::TestSystemWebAppInstallation::SetUpTabbedMultiWindowApp()) {} + + void SetUpOnMainThread() override { + InteractiveBrowserTest::SetUpOnMainThread(); + Tab::SetShowHoverCardOnMouseHoverForTesting(true); + } + + protected: + std::unique_ptr<ash::TestSystemWebAppInstallation> + test_system_web_app_installation_; +}; + +IN_PROC_BROWSER_TEST_F(TabHoverCardSystemWebAppTest, + HideDomainNameFromHoverCard) { + test_system_web_app_installation_->WaitForAppInstall(); + const auto* const app_browser = web_app::LaunchWebAppBrowser( + browser()->profile(), test_system_web_app_installation_->GetAppId()); + const char kTabToHover[] = "Tab to hover"; + + RunTestSequenceInContext( + app_browser->window()->GetElementContext(), + WithView(kTabStripElementId, + [](TabStrip* tab_strip) { tab_strip->StopAnimating(true); }), + NameDescendantViewByType<Tab>(kBrowserViewElementId, kTabToHover, 0), + MoveMouseTo(kTabToHover), + WaitForShow(TabHoverCardBubbleView::kHoverCardBubbleElementId), + EnsureNotPresent(TabHoverCardBubbleView::kHoverCardDomainLabelElementId), + MoveMouseTo(kNewTabButtonElementId), + WaitForHide(TabHoverCardBubbleView::kHoverCardBubbleElementId)); +} +#endif
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller_unittest.cc b/chrome/browser/ui/views/tabs/tab_hover_card_controller_unittest.cc index 964ce02..81ef0537 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_controller_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller_unittest.cc
@@ -110,6 +110,29 @@ TabHoverCardController::kNotWaiting); } +TEST_F(TabHoverCardControllerTest, DisableMemoryUsageForTab) { + g_browser_process->local_state()->SetBoolean( + prefs::kHoverCardMemoryUsageEnabled, false); + + AddTab(browser_view()->browser(), GURL("http://foo1.com")); + AddTab(browser_view()->browser(), GURL("http://foo2.com")); + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + + auto controller = + std::make_unique<TabHoverCardController>(browser_view()->tabstrip()); + + Tab* const target_tab = browser_view()->tabstrip()->tab_at(1); + TabRendererData data; + auto tab_resource_usage = base::MakeRefCounted<TabResourceUsage>(); + tab_resource_usage->SetMemoryUsageInBytes(100); + data.tab_resource_usage = std::move(tab_resource_usage); + target_tab->SetData(std::move(data)); + controller->target_tab_ = target_tab; + + controller->CreateHoverCard(target_tab); + EXPECT_FALSE(controller->hover_card_memory_usage_enabled_); +} + class TestThumbnailImageDelegate : public ThumbnailImage::Delegate { public: TestThumbnailImageDelegate() = default;
diff --git a/chrome/browser/ui/views/tabs/tab_slot_controller.h b/chrome/browser/ui/views/tabs/tab_slot_controller.h index d1c5c89..e928216 100644 --- a/chrome/browser/ui/views/tabs/tab_slot_controller.h +++ b/chrome/browser/ui/views/tabs/tab_slot_controller.h
@@ -156,9 +156,6 @@ // how the show, hide, or update will be processed. virtual void UpdateHoverCard(Tab* tab, HoverCardUpdateType update_type) = 0; - // Returns whether domain/origin should be shown in tab hover cards. - virtual bool ShowDomainInHoverCards() const = 0; - // Returns true if the hover card is showing for the given tab. virtual bool HoverCardIsShowingForTab(Tab* tab) = 0;
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 4308001b..fe75f65 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -1767,16 +1767,6 @@ tab_container_->UpdateHoverCard(tab, update_type); } -bool TabStrip::ShowDomainInHoverCards() const { -#if BUILDFLAG(IS_CHROMEOS_ASH) - const auto* app_controller = GetBrowser()->app_controller(); - if (app_controller && app_controller->system_app()) { - return false; - } -#endif - return true; -} - bool TabStrip::HoverCardIsShowingForTab(Tab* tab) { return hover_card_controller_ && hover_card_controller_->IsHoverCardShowingForTab(tab);
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index 4551481..d3919c76 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -288,7 +288,6 @@ void OnMouseEventInTab(views::View* source, const ui::MouseEvent& event) override; void UpdateHoverCard(Tab* tab, HoverCardUpdateType update_type) override; - bool ShowDomainInHoverCards() const override; bool HoverCardIsShowingForTab(Tab* tab) override; int GetBackgroundOffset() const override; int GetStrokeThickness() const override;
diff --git a/chrome/browser/ui/views/toolbar/app_menu.cc b/chrome/browser/ui/views/toolbar/app_menu.cc index d5d4395..eee57e09 100644 --- a/chrome/browser/ui/views/toolbar/app_menu.cc +++ b/chrome/browser/ui/views/toolbar/app_menu.cc
@@ -41,6 +41,7 @@ #include "chrome/browser/ui/global_error/global_error_service_factory.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/profiles/profile_view_utils.h" +#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/toolbar/app_menu_model.h" #include "chrome/browser/ui/ui_features.h" @@ -52,6 +53,7 @@ #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" #include "components/bookmarks/browser/bookmark_model.h" +#include "components/saved_tab_groups/features.h" #include "components/signin/public/base/signin_pref_names.h" #include "components/signin/public/identity_manager/account_info.h" #include "components/zoom/page_zoom.h" @@ -123,6 +125,13 @@ // Horizontal padding on the edges of the in-menu buttons. const int kHorizontalPadding = 15; +constexpr int kBookmarksCommandIdOffset = + AppMenuModel::kMinBookmarksCommandId - IDC_FIRST_UNBOUNDED_MENU; +constexpr int kRecentTabsCommandIdOffset = + AppMenuModel::kMinRecentTabsCommandId - IDC_FIRST_UNBOUNDED_MENU; +constexpr int kTabGroupsCommandIdOffset = + AppMenuModel::kMinTabGroupsCommandId - IDC_FIRST_UNBOUNDED_MENU; + #if BUILDFLAG(IS_CHROMEOS) // Extra horizontal space to reserve for the fullscreen button. const int kFullscreenPadding = 74; @@ -138,7 +147,7 @@ return command_id >= IDC_FIRST_UNBOUNDED_MENU && ((command_id - IDC_FIRST_UNBOUNDED_MENU) % AppMenuModel::kNumUnboundedMenuTypes == - 0); + kBookmarksCommandIdOffset); } // Returns true if |command_id| identifies a recent tabs menu item. @@ -146,7 +155,15 @@ return command_id >= IDC_FIRST_UNBOUNDED_MENU && ((command_id - IDC_FIRST_UNBOUNDED_MENU) % AppMenuModel::kNumUnboundedMenuTypes == - 1); + kRecentTabsCommandIdOffset); +} + +// Returns true if |command_id| identifies a tab group menu item. +bool IsTabGroupsCommand(int command_id) { + return command_id >= IDC_FIRST_UNBOUNDED_MENU && + ((command_id - IDC_FIRST_UNBOUNDED_MENU) % + AppMenuModel::kNumUnboundedMenuTypes == + kTabGroupsCommandIdOffset); } // Combination border/background for the buttons contained in the menu. The @@ -1106,6 +1123,11 @@ int command_id, const gfx::Point& p, ui::MenuSourceType source_type) { + if (IsTabGroupsCommand(command_id)) { + stg_everything_menu_->SetShowPinOption(false); + return stg_everything_menu_->ShowContextMenu(source, command_id, p, + source_type); + } return IsBookmarkCommand(command_id) ? bookmark_menu_delegate_->ShowContextMenu(source, command_id, p, source_type) @@ -1150,6 +1172,11 @@ return false; // The root item, a separator, or a title. } + if (command_id == IDC_CREATE_NEW_TAB_GROUP || + IsTabGroupsCommand(command_id)) { + return true; + } + if (IsBookmarkCommand(command_id) || command_id == IDC_SHOW_BOOKMARK_SIDE_PANEL) { return true; @@ -1183,6 +1210,12 @@ } void AppMenu::ExecuteCommand(int command_id, int mouse_event_flags) { + if (command_id == IDC_CREATE_NEW_TAB_GROUP || + IsTabGroupsCommand(command_id)) { + stg_everything_menu_->ExecuteCommand(command_id, mouse_event_flags); + return; + } + if (IsBookmarkCommand(command_id)) { UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.OpenBookmark", menu_opened_timer_.Elapsed()); @@ -1210,6 +1243,11 @@ return false; } + if (command_id == IDC_CREATE_NEW_TAB_GROUP || + IsTabGroupsCommand(command_id)) { + return false; + } + if (IsBookmarkCommand(command_id) || command_id == IDC_SHOW_BOOKMARK_SIDE_PANEL) { return false; @@ -1232,10 +1270,17 @@ } void AppMenu::WillShowMenu(MenuItemView* menu) { - if (menu == bookmark_menu_) + if (menu == saved_tab_groups_menu_) { + if (!stg_everything_menu_) { + stg_everything_menu_ = + std::make_unique<tab_groups::STGEverythingMenu>(nullptr, browser_); + } + stg_everything_menu_->PopulateMenu(menu); + } else if (menu == bookmark_menu_) { CreateBookmarkMenu(); - else if (bookmark_menu_delegate_) + } else if (bookmark_menu_delegate_) { bookmark_menu_delegate_->WillShowMenu(menu); + } } void AppMenu::WillHideMenu(MenuItemView* menu) { @@ -1390,6 +1435,11 @@ bookmark_menu_ = item; break; + case IDC_SAVED_TAB_GROUPS_MENU: + DCHECK(!saved_tab_groups_menu_); + saved_tab_groups_menu_ = item; + break; + #if BUILDFLAG(GOOGLE_CHROME_BRANDING) case IDC_FEEDBACK: DCHECK(!feedback_menu_item_);
diff --git a/chrome/browser/ui/views/toolbar/app_menu.h b/chrome/browser/ui/views/toolbar/app_menu.h index c5dd0878..0d8614f 100644 --- a/chrome/browser/ui/views/toolbar/app_menu.h +++ b/chrome/browser/ui/views/toolbar/app_menu.h
@@ -15,7 +15,9 @@ #include "base/timer/elapsed_timer.h" #include "chrome/browser/ui/global_error/global_error_observer.h" #include "chrome/browser/ui/global_error/global_error_service.h" +#include "chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.h" #include "components/bookmarks/browser/base_bookmark_model_observer.h" +#include "components/saved_tab_groups/saved_tab_group.h" #include "ui/base/models/menu_model.h" #include "ui/views/controls/menu/menu_delegate.h" @@ -171,6 +173,12 @@ // Menu corresponding to IDC_BOOKMARKS_MENU. raw_ptr<views::MenuItemView, DanglingUntriaged> bookmark_menu_ = nullptr; + // Used for managing the tab group menu items. + std::unique_ptr<tab_groups::STGEverythingMenu> stg_everything_menu_; + + // Menu corresponding to IDC_SAVED_TAB_GROUPS_MENU. + raw_ptr<views::MenuItemView> saved_tab_groups_menu_ = nullptr; + // Menu corresponding to IDC_FEEDBACK. raw_ptr<views::MenuItemView, DanglingUntriaged> feedback_menu_item_ = nullptr;
diff --git a/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller_unittest.cc b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller_unittest.cc index cec4b9d..35846d7 100644 --- a/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller_unittest.cc +++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller_unittest.cc
@@ -232,6 +232,9 @@ std::make_unique<LoopbackCrosapiAppServiceProxy>(profile_.get()); #endif // BUILDFLAG(IS_CHROMEOS_LACROS) + // Launching requires real os integration. + fake_provider()->UseRealOsIntegrationManager(); + test::AwaitStartWebAppProviderAndSubsystems(profile()); }
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc index cc83c1cf..d7e5d56 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -1778,10 +1778,11 @@ << "No app installed for site: " << static_cast<int>(site); WebAppRegistrar& app_registrar = provider()->registrar_unsafe(); -#if BUILDFLAG(IS_CHROMEOS) - DisplayMode display_mode = app_registrar.GetAppEffectiveDisplayMode(app_id); - bool is_open_in_app_browser = + const DisplayMode display_mode = + app_registrar.GetAppEffectiveDisplayMode(app_id); + const bool is_open_in_app_browser = (display_mode != blink::mojom::DisplayMode::kBrowser); +#if BUILDFLAG(IS_CHROMEOS) if (is_open_in_app_browser) { app_browser_ = LaunchWebAppBrowserAndWait(profile(), app_id); active_app_id_ = app_id; @@ -1808,15 +1809,19 @@ event_ptr->meta_key = false; event_ptr->shift_key = false; + BrowserAddedWaiter browser_added_waiter; ui_test_utils::UrlLoadObserver url_observer( app_registrar.GetAppLaunchUrl(app_id), content::NotificationService::AllSources()); app_home_page_handler.LaunchApp(app_id, std::move(event_ptr)); url_observer.Wait(); - // The app_browser_ is needed only for apps that open in a new window, and is - // nullptr for apps that launch in a tab. - app_browser_ = GetAppBrowserForAppId(profile(), app_id); + // The app_browser_ is needed only for apps that open in a new window. + if (is_open_in_app_browser) { + browser_added_waiter.Wait(); + app_browser_ = browser_added_waiter.browser_added(); + EXPECT_TRUE(AppBrowserController::IsForWebApp(app_browser(), app_id)); + } active_app_id_ = app_id; #endif AfterStateChangeAction();
diff --git a/chrome/browser/ui/views/webauthn/authenticator_gpm_arbitrary_pin_sheet_view.cc b/chrome/browser/ui/views/webauthn/authenticator_gpm_arbitrary_pin_sheet_view.cc index 0470998..cdabfe1 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_gpm_arbitrary_pin_sheet_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_gpm_arbitrary_pin_sheet_view.cc
@@ -21,10 +21,11 @@ std::pair<std::unique_ptr<views::View>, AuthenticatorGPMArbitraryPinSheetView::AutoFocus> AuthenticatorGPMArbitraryPinSheetView::BuildStepSpecificContent() { - return std::make_pair(std::make_unique<AuthenticatorGPMArbitraryPinView>( - gpm_arbitrary_pin_sheet_model()->ui_disabled(), - gpm_arbitrary_pin_sheet_model()->pin(), this), - AutoFocus::kYes); + bool ui_disabled = gpm_arbitrary_pin_sheet_model()->ui_disabled(); + return std::make_pair( + std::make_unique<AuthenticatorGPMArbitraryPinView>( + ui_disabled, gpm_arbitrary_pin_sheet_model()->pin(), this), + ui_disabled ? AutoFocus::kNo : AutoFocus::kYes); } void AuthenticatorGPMArbitraryPinSheetView::OnPinChanged(std::u16string pin) {
diff --git a/chrome/browser/ui/views/webauthn/authenticator_gpm_arbitrary_pin_view.cc b/chrome/browser/ui/views/webauthn/authenticator_gpm_arbitrary_pin_view.cc index c5f9ddc..99a18e8 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_gpm_arbitrary_pin_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_gpm_arbitrary_pin_view.cc
@@ -26,6 +26,7 @@ pin_textfield->SetDefaultWidthInChars(20); pin_textfield->SetReadOnly(ui_disabled); pin_textfield->SetText(pin); + pin_textfield->SetEnabled(!ui_disabled); pin_textfield_ = AddChildView(std::move(pin_textfield)); reveal_button_ = AddChildView(CreateRevealButton(base::BindRepeating(
diff --git a/chrome/browser/ui/views/webauthn/authenticator_gpm_pin_sheet_view.cc b/chrome/browser/ui/views/webauthn/authenticator_gpm_pin_sheet_view.cc index 0daa5099..27906ff 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_gpm_pin_sheet_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_gpm_pin_sheet_view.cc
@@ -19,11 +19,11 @@ std::pair<std::unique_ptr<views::View>, AuthenticatorGpmPinSheetView::AutoFocus> AuthenticatorGpmPinSheetView::BuildStepSpecificContent() { + bool ui_disabled = gpm_pin_sheet_model()->ui_disabled(); return std::make_pair(std::make_unique<AuthenticatorGPMPinView>( gpm_pin_sheet_model()->pin_digits_count(), - gpm_pin_sheet_model()->ui_disabled(), - gpm_pin_sheet_model()->pin(), this), - AutoFocus::kYes); + ui_disabled, gpm_pin_sheet_model()->pin(), this), + ui_disabled ? AutoFocus::kNo : AutoFocus::kYes); } void AuthenticatorGpmPinSheetView::OnPinChanged(std::u16string pin) {
diff --git a/chrome/browser/ui/views/webauthn/authenticator_gpm_pin_view.cc b/chrome/browser/ui/views/webauthn/authenticator_gpm_pin_view.cc index 0f943b27..36aca8e 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_gpm_pin_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_gpm_pin_view.cc
@@ -26,6 +26,7 @@ pin_textfield->SetObscured(true); pin_textfield->SetDisabled(ui_disabled); pin_textfield->SetPin(pin); + pin_textfield->SetEnabled(!ui_disabled); pin_textfield_ = AddChildView(std::move(pin_textfield)); reveal_button_ = AddChildView(CreateRevealButton(
diff --git a/chrome/browser/ui/webui/ash/settings/pages/apps/apps_section.cc b/chrome/browser/ui/webui/ash/settings/pages/apps/apps_section.cc index d92c000..b45feadb 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/apps/apps_section.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/apps/apps_section.cc
@@ -406,6 +406,18 @@ html_source->AddLocalizedStrings(kLocalizedStrings); } +void AddAppParentalControlsStrings(content::WebUIDataSource* html_source) { + static constexpr webui::LocalizedString kLocalizedStrings[] = { + {"appParentalControlsTitle", IDS_OS_SETTINGS_APP_PARENTAL_CONTROLS_LABEL}, + {"appParentalControlsSubtitle", + IDS_OS_SETTINGS_APP_PARENTAL_CONTROLS_SUBLABEL}, + {"appParentalControlsSetUpButton", + IDS_OS_SETTINGS_APP_PARENTAL_CONTROLS_SET_UP_BUTTON}, + }; + + html_source->AddLocalizedStrings(kLocalizedStrings); +} + bool ShowPluginVm(const Profile* profile, const PrefService& pref_service) { // Even if not allowed, we still want to show Plugin VM if the VM image is on // disk, so that users are still able to delete the image at will. @@ -514,9 +526,6 @@ {"enableIsolatedWebAppsToggleLabel", IDS_SETTINGS_ENABLE_ISOLATED_WEB_APPS_LABEL}, {"appManagementAppLanguageLabel", IDS_APP_MANAGEMENT_APP_LANGUAGE_LABEL}, - {"appParentalControlsTitle", IDS_OS_SETTINGS_APP_PARENTAL_CONTROLS_LABEL}, - {"appParentalControlsSubtitle", - IDS_OS_SETTINGS_APP_PARENTAL_CONTROLS_SUBLABEL}, }; html_source->AddLocalizedStrings(kLocalizedStrings); @@ -564,6 +573,7 @@ AddAndroidAppStrings(html_source); AddPluginVmLoadTimeData(html_source); AddBorealisStrings(html_source); + AddAppParentalControlsStrings(html_source); // Startup subsection exists only when OsSettingsRevampWayfinding is disabled. if (startup_subsection_) {
diff --git a/chrome/browser/ui/webui/ash/settings/pages/multitasking/multitasking_section.cc b/chrome/browser/ui/webui/ash/settings/pages/multitasking/multitasking_section.cc index 59b0a40..580083f 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/multitasking/multitasking_section.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/multitasking/multitasking_section.cc
@@ -88,8 +88,9 @@ // Note: This is a subsection that exists under System Preferences. This is // not a top-level section and does not have a respective declaration in // chromeos::settings::mojom::Section. - return ShouldShowMultitasking() ? mojom::Section::kSystemPreferences - : mojom::Section::kPersonalization; + return ash::features::IsOsSettingsRevampWayfindingEnabled() + ? mojom::Section::kSystemPreferences + : mojom::Section::kPersonalization; } mojom::SearchResultIcon MultitaskingSection::GetSectionIcon() const { @@ -97,8 +98,9 @@ } const char* MultitaskingSection::GetSectionPath() const { - return ShouldShowMultitasking() ? mojom::kSystemPreferencesSectionPath - : mojom::kPersonalizationSectionPath; + return ash::features::IsOsSettingsRevampWayfindingEnabled() + ? mojom::kSystemPreferencesSectionPath + : mojom::kPersonalizationSectionPath; } bool MultitaskingSection::LogMetric(mojom::Setting setting,
diff --git a/chrome/browser/ui/webui/ash/settings/pages/personalization/personalization_section.cc b/chrome/browser/ui/webui/ash/settings/pages/personalization/personalization_section.cc index a9c8bf46..b78bbf67 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/personalization/personalization_section.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/personalization/personalization_section.cc
@@ -49,7 +49,7 @@ : OsSettingsSection(profile, search_tag_registry), isRevampEnabled_(ash::features::IsOsSettingsRevampWayfindingEnabled()), multitasking_subsection_( - ShouldShowMultitaskingInPersonalization() + !isRevampEnabled_ ? std::make_optional<MultitaskingSection>(profile, search_tag_registry) : std::nullopt) { @@ -83,14 +83,14 @@ }; html_source->AddLocalizedStrings(kWallpaperLocalizedStrings); - if (ShouldShowMultitaskingInPersonalization()) { + if (multitasking_subsection_) { multitasking_subsection_->AddLoadTimeData(html_source); } } void PersonalizationSection::AddHandlers(content::WebUI* web_ui) { web_ui->AddMessageHandler(std::make_unique<PersonalizationHubHandler>()); - if (ShouldShowMultitaskingInPersonalization()) { + if (multitasking_subsection_) { multitasking_subsection_->AddHandlers(web_ui); } } @@ -121,7 +121,7 @@ void PersonalizationSection::RegisterHierarchy( HierarchyGenerator* generator) const { generator->RegisterTopLevelSetting(mojom::Setting::kOpenWallpaper); - if (ShouldShowMultitaskingInPersonalization()) { + if (multitasking_subsection_) { multitasking_subsection_->RegisterHierarchy(generator); } }
diff --git a/chrome/browser/ui/webui/ash/settings/pages/privacy/metrics_consent_handler.cc b/chrome/browser/ui/webui/ash/settings/pages/privacy/metrics_consent_handler.cc index ab96eb5..41d81125 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/privacy/metrics_consent_handler.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/privacy/metrics_consent_handler.cc
@@ -98,6 +98,13 @@ } bool MetricsConsentHandler::IsMetricsConsentConfigurable() const { + // TODO(b/333911538): In the interim, completely disable child users + // from being able to toggle consent in the settings. Once the parent sets + // the consent for the child during OOBE, it cannot be updated afterwards. + if (user_manager_->IsLoggedInAsChildUser()) { + return false; + } + return ShouldUseUserConsent() || user_manager_->IsCurrentUserOwner(); }
diff --git a/chrome/browser/ui/webui/ash/settings/pages/privacy/metrics_consent_handler_unittest.cc b/chrome/browser/ui/webui/ash/settings/pages/privacy/metrics_consent_handler_unittest.cc index f05fa8c..a369b66 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/privacy/metrics_consent_handler_unittest.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/privacy/metrics_consent_handler_unittest.cc
@@ -394,4 +394,39 @@ StatsReportingController::Shutdown(); } +TEST_F(MetricsConsentHandlerTest, ChildUserCannotToggleAsNonOwner) { + auto owner_id = AccountId::FromUserEmailGaiaId(kOwner, "2"); + std::unique_ptr<TestingProfile> owner = RegisterOwner(owner_id); + + auto child_id = AccountId::FromUserEmailGaiaId("child@user.com", "3"); + std::unique_ptr<TestingProfile> child = + CreateUser("child@user.com", non_owner_keys); + test_user_manager_->set_current_user_child(true); + test_user_manager_->AddUserWithAffiliationAndTypeAndProfile( + child_id, false, user_manager::UserType::kChild, child.get()); + + // User cannot use user consent. This happens if the device is managed. + test_metrics_service_client_->SetShouldUseUserConsent(true); + + LoginUser(child_id); + EXPECT_FALSE(test_user_manager_->IsCurrentUserOwner()); + + // Set the javascript message object for metrics consent state. + InitializeTestHandler(child.get()); + handler_->GetMetricsConsentState(); + + // Check values of javascript callback response message. + std::string pref_name; + bool is_configurable; + EXPECT_TRUE(GetMetricsConsentStateMessage(&pref_name, &is_configurable)); + + // Unmanaged child user should use user consent and should not be toggle-able. + EXPECT_THAT(pref_name, Eq(::metrics::prefs::kMetricsUserConsent)); + EXPECT_FALSE(is_configurable); + + // Explicitly shutdown controller here because OwnerSettingsService is + // destructed before TearDown() is called. + StatsReportingController::Shutdown(); +} + } // namespace ash::settings
diff --git a/chrome/browser/ui/webui/commerce/product_specifications_ui.cc b/chrome/browser/ui/webui/commerce/product_specifications_ui.cc index e7ac354..03c19124b 100644 --- a/chrome/browser/ui/webui/commerce/product_specifications_ui.cc +++ b/chrome/browser/ui/webui/commerce/product_specifications_ui.cc
@@ -17,6 +17,7 @@ #include "components/commerce/core/commerce_feature_list.h" #include "components/commerce/core/shopping_service.h" #include "components/commerce/core/webui/shopping_service_handler.h" +#include "components/strings/grit/components_strings.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" @@ -50,6 +51,12 @@ source->AddString("message", "Some example content..."); source->AddString("pageTitle", "Product Specifications"); source->AddString("summaryTitle", "Summary"); + + static constexpr webui::LocalizedString kStrings[] = { + {"openTabsSectionTitle", IDS_PRODUCT_SPECIFICATIONS_OPEN_TABS_SECTION}, + }; + + source->AddLocalizedStrings(kStrings); } void ProductSpecificationsUI::BindInterface(
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc index 6bca368..89f04e9 100644 --- a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc +++ b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc
@@ -235,6 +235,10 @@ InstallGoodExtension(); SafetyHubMenuNotificationService* notification_service = SafetyHubMenuNotificationServiceFactory::GetForProfile(profile); + // Safety Hub services will be initialized when + // SafetyHubMenuNotificationService is created. Let Safety Hub services to + // initialize properly. + safety_hub_test_util::RunUntilPasswordCheckCompleted(profile); // No unpublished extensions yet, so there shouldn't be a menu notifications. std::optional<MenuNotificationEntry> notification = notification_service->GetNotificationToShow();
diff --git a/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc index 8c2ab02..fd60a3b 100644 --- a/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc +++ b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
@@ -86,7 +86,8 @@ // them when this changes and close all open prompts. DefaultBrowserPromptManager::UpdatePrefsForDismissedPrompt( Profile::FromWebUI(web_ui())); - DefaultBrowserPromptManager::GetInstance()->CloseAllPrompts(); + DefaultBrowserPromptManager::GetInstance()->CloseAllPrompts( + DefaultBrowserPromptManager::CloseReason::kDismiss); } void DefaultBrowserHandler::OnDefaultBrowserSettingChange() {
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index 0c2fbf18..ef596c7 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -712,6 +712,7 @@ "//content/test:test_support", "//services/data_decoder/public/cpp:test_support", "//testing/gtest", + "//ui/gfx:test_support", "//ui/webui", ] if (is_chromeos_ash) {
diff --git a/chrome/browser/web_applications/commands/fetch_manifest_and_install_command_unittest.cc b/chrome/browser/web_applications/commands/fetch_manifest_and_install_command_unittest.cc index 449bf07c..4c021cd 100644 --- a/chrome/browser/web_applications/commands/fetch_manifest_and_install_command_unittest.cc +++ b/chrome/browser/web_applications/commands/fetch_manifest_and_install_command_unittest.cc
@@ -56,6 +56,7 @@ #include "ui/color/color_provider_utils.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/geometry/size.h" +#include "ui/gfx/test/sk_gmock_support.h" #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/components/arc/mojom/intent_helper.mojom.h" @@ -71,54 +72,6 @@ namespace web_app { namespace { -MATCHER_P(EqualsBitmap, expected_bmp, "") { - // Number of pixels with an error - int error_pixels_count = 0; - - gfx::Rect error_bounding_rect = gfx::Rect(); - - // Check that bitmaps have identical dimensions. - if (arg.width() != expected_bmp.width()) { - *result_listener << "where widths do not match, actual: " << arg.width() - << ", expected: " << expected_bmp.width(); - return false; - } - if (arg.height() != expected_bmp.height()) { - *result_listener << "where heights do not match, actual: " << arg.height() - << ", expected: " << expected_bmp.height(); - return false; - } - - for (int x = 0; x < arg.width(); ++x) { - for (int y = 0; y < arg.height(); ++y) { - SkColor actual_color = arg.getColor(x, y); - SkColor expected_color = expected_bmp.getColor(x, y); - if (actual_color != expected_color) { - ++error_pixels_count; - error_bounding_rect.Union(gfx::Rect(x, y, 1, 1)); - } - } - } - - if (error_pixels_count != 0) { - *result_listener << "Number of pixel with an error: " << error_pixels_count - << "\nError Bounding Box : " - << error_bounding_rect.ToString() << "\n"; - int sample_x = expected_bmp.width() / 2; - int sample_y = expected_bmp.height() / 2; - std::string expected_color = color_utils::SkColorToRgbaString( - expected_bmp.getColor(sample_x, sample_y)); - std::string actual_color = - color_utils::SkColorToRgbaString(arg.getColor(sample_x, sample_y)); - *result_listener << "Sample pixel comparison at " << sample_x << "x" - << sample_y << ": Expected " << expected_color - << ", actual " << actual_color; - return false; - } - - return true; -} - class FetchManifestAndInstallCommandTest : public WebAppTest { public: const GURL kWebAppUrl = GURL("https://example.com/path/index.html"); @@ -1044,7 +997,7 @@ ASSERT_TRUE(icons_future.Wait()); std::map<SquareSizePx, SkBitmap> bitmaps = icons_future.Get(); EXPECT_THAT(bitmaps[icon_size::k256], - EqualsBitmap(GenerateExpected256Icon())); + gfx::test::EqualsBitmap(GenerateExpected256Icon())); EXPECT_EQ(IsDiyApp(), provider()->registrar_unsafe().IsDiyApp(app_id));
diff --git a/chrome/browser/web_applications/commands/install_from_info_command_browsertest.cc b/chrome/browser/web_applications/commands/install_from_info_command_browsertest.cc index 0ef5881..fcc99c0 100644 --- a/chrome/browser/web_applications/commands/install_from_info_command_browsertest.cc +++ b/chrome/browser/web_applications/commands/install_from_info_command_browsertest.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 "install_from_info_command.h" +#include "chrome/browser/web_applications/commands/install_from_info_command.h" #include <map> #include <memory> @@ -11,6 +11,7 @@ #include "base/run_loop.h" #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/test_future.h" #include "chrome/browser/ui/web_applications/web_app_browsertest_base.h" #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" #include "chrome/browser/web_applications/test/fake_os_integration_manager.h" @@ -18,6 +19,7 @@ #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_command_scheduler.h" +#include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_icon_manager.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/browser/web_applications/web_app_provider.h" @@ -31,14 +33,7 @@ class InstallFromInfoCommandTest : public WebAppBrowserTestBase { public: - InstallFromInfoCommandTest() { - WebAppProvider::SetOsIntegrationManagerFactoryForTesting( - [](Profile* profile) -> std::unique_ptr<OsIntegrationManager> { - return std::make_unique<FakeOsIntegrationManager>(profile, nullptr, - nullptr, nullptr); - }); - } - + InstallFromInfoCommandTest() = default; std::map<SquareSizePx, SkBitmap> ReadIcons(const webapps::AppId& app_id, IconPurpose purpose, const SortedSizesPx& sizes_px) { @@ -54,10 +49,6 @@ run_loop.Run(); return result; } - - FakeOsIntegrationManager* os_integration_manager() { - return provider().os_integration_manager().AsTestOsIntegrationManager(); - } }; IN_PROC_BROWSER_TEST_F(InstallFromInfoCommandTest, SuccessInstall) {
diff --git a/chrome/browser/web_applications/commands/launch_web_app_command.cc b/chrome/browser/web_applications/commands/launch_web_app_command.cc index 4c16c45..d439f87 100644 --- a/chrome/browser/web_applications/commands/launch_web_app_command.cc +++ b/chrome/browser/web_applications/commands/launch_web_app_command.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/commands/web_app_command.h" #include "chrome/browser/web_applications/locks/app_lock.h" +#include "chrome/browser/web_applications/os_integration/os_integration_test_override.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_ui_manager.h" #include "components/services/app_service/public/cpp/app_launch_util.h" @@ -59,6 +60,20 @@ return; } + bool is_standalone_launch = + params_.container == apps::LaunchContainer::kLaunchContainerWindow || + (launch_setting_ == + LaunchWebAppWindowSetting::kOverrideWithWebAppConfig && + lock_->registrar().GetAppUserDisplayMode(params_.app_id) != + mojom::UserDisplayMode::kBrowser); + + if (is_standalone_launch) { + // Launching an app in a standalone windows requires OS integration, and the + // only way this is supported in tests is to use the + // OsIntegrationTestOverride functionality. + CHECK_OS_INTEGRATION_ALLOWED(); + } + provider_->ui_manager().LaunchWebApp( std::move(params_), launch_setting_, *profile_, base::BindOnce(&LaunchWebAppCommand::OnAppLaunched,
diff --git a/chrome/browser/web_applications/extensions/web_app_uninstall_and_replace_job.cc b/chrome/browser/web_applications/extensions/web_app_uninstall_and_replace_job.cc index 132f4ec..6075866 100644 --- a/chrome/browser/web_applications/extensions/web_app_uninstall_and_replace_job.cc +++ b/chrome/browser/web_applications/extensions/web_app_uninstall_and_replace_job.cc
@@ -80,7 +80,7 @@ WebAppUninstallAndReplaceJob::~WebAppUninstallAndReplaceJob() = default; void WebAppUninstallAndReplaceJob::Start() { - DCHECK(to_app_lock_->registrar().IsInstalled(to_app_)); + CHECK(to_app_lock_->registrar().GetAppById(to_app_)); std::vector<webapps::AppId> apps_to_replace; for (const webapps::AppId& from_app : from_apps_or_extensions_) { @@ -184,20 +184,29 @@ void WebAppUninstallAndReplaceJob::OnShortcutLocationGathered( const webapps::AppId& from_app, base::OnceClosure on_complete, - ShortcutLocations locations) { + ShortcutLocations from_app_locations) { auto* proxy = apps::AppServiceProxyFactory::GetForProfile(&profile_.get()); const bool is_extension = proxy->AppRegistryCache().GetAppType(from_app) == apps::AppType::kChromeApp; + bool run_on_os_login = from_app_locations.in_startup; if (is_extension) { // Need to be called before `proxy->UninstallSilently` because // UninstallSilently might synchronously finish, so the wait won't get // finished if called after. WaitForExtensionShortcutsDeleted( - from_app, base::BindOnce(&WebAppUninstallAndReplaceJob:: - SynchronizeOSIntegrationForReplacementApp, - weak_ptr_factory_.GetWeakPtr(), - std::move(on_complete), locations)); + from_app, + base::BindOnce(&WebAppUninstallAndReplaceJob:: + SynchronizeOSIntegrationForReplacementApp, + weak_ptr_factory_.GetWeakPtr(), std::move(on_complete), + run_on_os_login, from_app_locations)); + } else { + // Platforms like Mac don't fetch the 'run on os login' property from the + // GetAppExistingShortCutLocation API. + run_on_os_login = + run_on_os_login || + to_app_lock_->registrar().GetAppRunOnOsLoginMode(from_app).value == + RunOnOsLoginMode::kWindowed; } // When the `from_app` is a web app, we can't wait for it to finish because it @@ -207,18 +216,19 @@ proxy->UninstallSilently(from_app, apps::UninstallSource::kMigration); if (!is_extension) { - SynchronizeOSIntegrationForReplacementApp(std::move(on_complete), - locations); + SynchronizeOSIntegrationForReplacementApp( + std::move(on_complete), run_on_os_login, from_app_locations); } } void WebAppUninstallAndReplaceJob::SynchronizeOSIntegrationForReplacementApp( base::OnceClosure on_complete, - ShortcutLocations locations) { + bool from_app_run_on_os_login, + ShortcutLocations from_app_locations) { ValueWithPolicy<RunOnOsLoginMode> run_on_os_login = to_app_lock_->registrar().GetAppRunOnOsLoginMode(to_app_); if (run_on_os_login.user_controllable) { - RunOnOsLoginMode new_mode = locations.in_startup + RunOnOsLoginMode new_mode = from_app_run_on_os_login ? RunOnOsLoginMode::kWindowed : RunOnOsLoginMode::kNotRun; if (new_mode != run_on_os_login.value) { @@ -230,8 +240,9 @@ } SynchronizeOsOptions synchronize_options; - synchronize_options.add_shortcut_to_desktop = locations.on_desktop; - synchronize_options.add_to_quick_launch_bar = locations.in_quick_launch_bar; + synchronize_options.add_shortcut_to_desktop = from_app_locations.on_desktop; + synchronize_options.add_to_quick_launch_bar = + from_app_locations.in_quick_launch_bar; synchronize_options.reason = SHORTCUT_CREATION_AUTOMATED; to_app_lock_->os_integration_manager().Synchronize(to_app_, std::move(on_complete));
diff --git a/chrome/browser/web_applications/jobs/uninstall/web_app_uninstall_and_replace_job.h b/chrome/browser/web_applications/jobs/uninstall/web_app_uninstall_and_replace_job.h index dcbb0c1..7e2e41b 100644 --- a/chrome/browser/web_applications/jobs/uninstall/web_app_uninstall_and_replace_job.h +++ b/chrome/browser/web_applications/jobs/uninstall/web_app_uninstall_and_replace_job.h
@@ -54,10 +54,12 @@ void OnShortcutLocationGathered(const webapps::AppId& from_app, base::OnceClosure on_complete, - ShortcutLocations locations); + ShortcutLocations from_app_locations); - void SynchronizeOSIntegrationForReplacementApp(base::OnceClosure on_complete, - ShortcutLocations locations); + void SynchronizeOSIntegrationForReplacementApp( + base::OnceClosure on_complete, + bool from_app_run_on_os_login, + ShortcutLocations from_app_locations); const raw_ref<Profile> profile_; const raw_ref<base::Value::Dict> debug_value_;
diff --git a/chrome/browser/web_applications/os_integration/os_integration_manager.cc b/chrome/browser/web_applications/os_integration/os_integration_manager.cc index af4f2ce5..71e0d080 100644 --- a/chrome/browser/web_applications/os_integration/os_integration_manager.cc +++ b/chrome/browser/web_applications/os_integration/os_integration_manager.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/os_integration/file_handling_sub_manager.h" #include "chrome/browser/web_applications/os_integration/os_integration_sub_manager.h" +#include "chrome/browser/web_applications/os_integration/os_integration_test_override.h" #include "chrome/browser/web_applications/os_integration/protocol_handling_sub_manager.h" #include "chrome/browser/web_applications/os_integration/run_on_os_login_sub_manager.h" #include "chrome/browser/web_applications/os_integration/shortcut_menu_handling_sub_manager.h" @@ -144,6 +145,7 @@ // This is usually called to clean up OS integration states on the OS, // regardless of whether there are apps existing in the app registry or not. if (options.has_value() && options.value().force_unregister_os_integration) { + CHECK_OS_INTEGRATION_ALLOWED(); ForceUnregisterOsIntegrationOnSubManager( app_id, /*index=*/0, std::move(callback).Then( @@ -308,6 +310,8 @@ return; } + CHECK_OS_INTEGRATION_ALLOWED(); + ExecuteNextSubmanager(app_id, options, desired_states_ptr, web_app->current_os_integration_states(), /*index=*/0, std::move(write_state_to_db));
diff --git a/chrome/browser/web_applications/os_integration/os_integration_test_override.cc b/chrome/browser/web_applications/os_integration/os_integration_test_override.cc index ab5bb83..befd9553 100644 --- a/chrome/browser/web_applications/os_integration/os_integration_test_override.cc +++ b/chrome/browser/web_applications/os_integration/os_integration_test_override.cc
@@ -14,6 +14,7 @@ #include "base/memory/scoped_refptr.h" #include "base/no_destructor.h" #include "build/build_config.h" +#include "chrome/browser/web_applications/os_integration/os_integration_manager.h" #include "components/webapps/common/web_app_id.h" namespace web_app { @@ -35,6 +36,27 @@ } // namespace // static +void OsIntegrationTestOverride::CheckOsIntegrationAllowed() { +#if !BUILDFLAG(IS_CHROMEOS) + // Note: Using OsIntegrationManager::SuppressForTesting disables os + // integration, even if OsIntegrationTestOverride is specified. In this case, + // os integration is still not allowed, and anything needing it (like + // launching) should call this function & check-fail here. + bool os_integration_can_occur_in_tests = + !OsIntegrationManager::AreOsHooksSuppressedForTesting() && + ::web_app::OsIntegrationTestOverride::Get(); + if (!os_integration_can_occur_in_tests) { + CHECK_IS_NOT_TEST() + << "Please initialize an " + "`OsIntegrationTestOverrideBlockingRegistration`" + "to allow fully installed web apps with OS integration in tests. In " + "unit tests it may be required to call " + "`FakeWebAppProvider::UseRealOsIntegrationManager()` during set up."; + } +#endif +} + +// static scoped_refptr<OsIntegrationTestOverride> OsIntegrationTestOverride::Get() { auto& state = GetMutableOsIntegrationTestOverrideStateForTesting(); base::AutoLock state_lock(state.lock);
diff --git a/chrome/browser/web_applications/os_integration/os_integration_test_override.h b/chrome/browser/web_applications/os_integration/os_integration_test_override.h index c4563a4..a13dd701 100644 --- a/chrome/browser/web_applications/os_integration/os_integration_test_override.h +++ b/chrome/browser/web_applications/os_integration/os_integration_test_override.h
@@ -66,6 +66,8 @@ class OsIntegrationTestOverride : public base::RefCountedThreadSafe<OsIntegrationTestOverride> { public: + static void CheckOsIntegrationAllowed(); + // This will return a nullptr in production code or tests that have not // created a `OsIntegrationTestOverrideImpl::BlockingRegistration` through // `OsIntegrationTestOverrideImpl::OverrideForTesting`. @@ -130,4 +132,7 @@ } // namespace web_app +#define CHECK_OS_INTEGRATION_ALLOWED() \ + OsIntegrationTestOverride::CheckOsIntegrationAllowed() + #endif // CHROME_BROWSER_WEB_APPLICATIONS_OS_INTEGRATION_OS_INTEGRATION_TEST_OVERRIDE_H_
diff --git a/chrome/browser/web_applications/preinstalled_web_apps_browsertest.cc b/chrome/browser/web_applications/preinstalled_web_apps_browsertest.cc index 9bd0d60..745482dd 100644 --- a/chrome/browser/web_applications/preinstalled_web_apps_browsertest.cc +++ b/chrome/browser/web_applications/preinstalled_web_apps_browsertest.cc
@@ -39,11 +39,6 @@ PreinstalledWebAppManager::SkipStartupForTesting()) { // Ignore any default app configs on disk. SetPreinstalledWebAppConfigDirForTesting(&empty_path_); - WebAppProvider::SetOsIntegrationManagerFactoryForTesting( - [](Profile* profile) -> std::unique_ptr<OsIntegrationManager> { - return std::make_unique<FakeOsIntegrationManager>(profile, nullptr, - nullptr, nullptr); - }); } ~PreinstalledWebAppsBrowserTest() override {
diff --git a/chrome/browser/web_applications/test/fake_web_app_provider.cc b/chrome/browser/web_applications/test/fake_web_app_provider.cc index cad06b8..040e25e 100644 --- a/chrome/browser/web_applications/test/fake_web_app_provider.cc +++ b/chrome/browser/web_applications/test/fake_web_app_provider.cc
@@ -98,6 +98,20 @@ synchronize_preinstalled_app_on_startup_ = synchronize_on_startup; } +void FakeWebAppProvider::UseRealOsIntegrationManager() { + CheckNotStartedAndDisconnect(); + auto file_handler_manager = + std::make_unique<WebAppFileHandlerManager>(profile_); + auto protocol_handler_manager = + std::make_unique<WebAppProtocolHandlerManager>(profile_); + auto shortcut_manager = std::make_unique<WebAppShortcutManager>( + profile_, file_handler_manager.get(), protocol_handler_manager.get()); + + SetOsIntegrationManager(std::make_unique<OsIntegrationManager>( + profile_, std::move(shortcut_manager), std::move(file_handler_manager), + std::move(protocol_handler_manager))); +} + void FakeWebAppProvider::SetEnableAutomaticIwaUpdates( AutomaticIwaUpdateStrategy automatic_iwa_update_strategy) { CheckNotStartedAndDisconnect();
diff --git a/chrome/browser/web_applications/test/fake_web_app_provider.h b/chrome/browser/web_applications/test/fake_web_app_provider.h index 3739fdf..2d28bf29 100644 --- a/chrome/browser/web_applications/test/fake_web_app_provider.h +++ b/chrome/browser/web_applications/test/fake_web_app_provider.h
@@ -108,6 +108,11 @@ // by default for unit tests, and can be enabled by setting this flag to true. void SetSynchronizePreinstalledAppsOnStartup(bool synchronize_on_startup); + // Call when the unit tets wants to trigger OS integration, removing the + // ScopedSuppressOsHooks in FakeOsIntegrationManager (allowing the + // OsIntegrationTestOverrideBlockingRegistration to work correctly). + void UseRealOsIntegrationManager(); + enum class AutomaticIwaUpdateStrategy { kDefault, kForceDisabled,
diff --git a/chrome/browser/web_applications/test/os_integration_test_override_impl.h b/chrome/browser/web_applications/test/os_integration_test_override_impl.h index 97ed1e35..215b1c7 100644 --- a/chrome/browser/web_applications/test/os_integration_test_override_impl.h +++ b/chrome/browser/web_applications/test/os_integration_test_override_impl.h
@@ -57,6 +57,12 @@ // integration (disk folders, windows registry changes, etc) have been removed. // // `test_override()` can be used to view or modify the OS state. +// +// Note: This override does not apply if there is a +// OsIntegrationManager::ScopedSuppressForTesting is created. This often happens +// in unit tests, which use a FakeWebAppProvider by default. To reset that +// object held by the FakeOsIntegrationManager, call +// FakeWebAppProvider::UseRealOsIntegrationManager() on test setup. class OsIntegrationTestOverrideBlockingRegistration { public: OsIntegrationTestOverrideBlockingRegistration();
diff --git a/chrome/browser/web_applications/web_app_command_scheduler.cc b/chrome/browser/web_applications/web_app_command_scheduler.cc index 13f2633..981bfa1 100644 --- a/chrome/browser/web_applications/web_app_command_scheduler.cc +++ b/chrome/browser/web_applications/web_app_command_scheduler.cc
@@ -402,6 +402,19 @@ location); } +void WebAppCommandScheduler::RemoveAllManagementTypesAndUninstall( + base::PassKey<WebAppSyncBridge>, + const webapps::AppId& app_id, + webapps::WebappUninstallSource uninstall_source, + UninstallJob::Callback callback, + const base::Location& location) { + provider_->command_manager().ScheduleCommand( + WebAppUninstallCommand::CreateForRemoveInstallManagements( + uninstall_source, *profile_, app_id, WebAppManagementTypes::All(), + std::move(callback)), + location); +} + void WebAppCommandScheduler::UninstallAllUserInstalledWebApps( webapps::WebappUninstallSource uninstall_source, UninstallAllUserInstalledWebAppsCommand::Callback callback,
diff --git a/chrome/browser/web_applications/web_app_command_scheduler.h b/chrome/browser/web_applications/web_app_command_scheduler.h index aeb4abdb..d6c8e64f 100644 --- a/chrome/browser/web_applications/web_app_command_scheduler.h +++ b/chrome/browser/web_applications/web_app_command_scheduler.h
@@ -301,6 +301,21 @@ UninstallAllUserInstalledWebAppsCommand::Callback callback, const base::Location& location = FROM_HERE); + // Completely removes the web_app from the database by removing all management + // types. Since this is a very destructive operation, prefer invoking + // RemoveInstallUrlMaybeUninstall(), RemoveInstallManagementMaybeUninstall(), + // RemoveUserUninstallableManagements() or UninstallAllUserInstalledWebApps() + // instead. + // Currently, only the WebAppSyncBridge is allowed to invoke this for + // uninstalling web apps, since it is safe to assume that apps marked with + // `is_uninstalling` set to true can be fully removed from the registry. + void RemoveAllManagementTypesAndUninstall( + base::PassKey<WebAppSyncBridge>, + const webapps::AppId& app_id, + webapps::WebappUninstallSource uninstall_source, + UninstallJob::Callback callback, + const base::Location& location = FROM_HERE); + // Schedules a command that updates run on os login to provided `login_mode` // for a web app. void SetRunOnOsLoginMode(const webapps::AppId& app_id,
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 1091966d..4b1c17a 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -73,13 +73,6 @@ namespace web_app { -namespace { - -WebAppProvider::OsIntegrationManagerFactory - g_os_integration_manager_factory_for_testing = nullptr; - -} // namespace - // static WebAppProvider* WebAppProvider::GetDeprecated(Profile* profile) { return WebAppProviderFactory::GetForProfile(profile); @@ -136,12 +129,6 @@ return WebAppProvider::GetForLocalAppsUnchecked(profile); } -// static -void WebAppProvider::SetOsIntegrationManagerFactoryForTesting( - OsIntegrationManagerFactory factory) { - g_os_integration_manager_factory_for_testing = factory; -} - WebAppProvider::WebAppProvider(Profile* profile) : profile_(profile) { DCHECK(AreWebAppsEnabled(profile_)); @@ -360,21 +347,16 @@ translation_manager_ = std::make_unique<WebAppTranslationManager>(profile); install_finalizer_ = std::make_unique<WebAppInstallFinalizer>(profile); - if (g_os_integration_manager_factory_for_testing) { - os_integration_manager_ = - g_os_integration_manager_factory_for_testing(profile); - } else { - auto file_handler_manager = - std::make_unique<WebAppFileHandlerManager>(profile); - auto protocol_handler_manager = - std::make_unique<WebAppProtocolHandlerManager>(profile); - auto shortcut_manager = std::make_unique<WebAppShortcutManager>( - profile, file_handler_manager.get(), protocol_handler_manager.get()); + auto file_handler_manager = + std::make_unique<WebAppFileHandlerManager>(profile); + auto protocol_handler_manager = + std::make_unique<WebAppProtocolHandlerManager>(profile); + auto shortcut_manager = std::make_unique<WebAppShortcutManager>( + profile, file_handler_manager.get(), protocol_handler_manager.get()); - os_integration_manager_ = std::make_unique<OsIntegrationManager>( - profile, std::move(shortcut_manager), std::move(file_handler_manager), - std::move(protocol_handler_manager)); - } + os_integration_manager_ = std::make_unique<OsIntegrationManager>( + profile, std::move(shortcut_manager), std::move(file_handler_manager), + std::move(protocol_handler_manager)); command_manager_ = std::make_unique<WebAppCommandManager>(profile); command_scheduler_ = std::make_unique<WebAppCommandScheduler>(*profile);
diff --git a/chrome/browser/web_applications/web_app_provider.h b/chrome/browser/web_applications/web_app_provider.h index 4d97bd8a..635e7a60 100644 --- a/chrome/browser/web_applications/web_app_provider.h +++ b/chrome/browser/web_applications/web_app_provider.h
@@ -105,8 +105,6 @@ using OsIntegrationManagerFactory = std::unique_ptr<OsIntegrationManager> (*)(Profile*); - static void SetOsIntegrationManagerFactoryForTesting( - OsIntegrationManagerFactory factory); explicit WebAppProvider(Profile* profile); WebAppProvider(const WebAppProvider&) = delete;
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.cc b/chrome/browser/web_applications/web_app_sync_bridge.cc index 988bfe3..d0f7de36 100644 --- a/chrome/browser/web_applications/web_app_sync_bridge.cc +++ b/chrome/browser/web_applications/web_app_sync_bridge.cc
@@ -763,8 +763,9 @@ apps_to_delete, callback); } else { for (const webapps::AppId& app_id : apps_to_delete) { - command_scheduler_->RemoveUserUninstallableManagements( - app_id, webapps::WebappUninstallSource::kSync, + command_scheduler_->RemoveAllManagementTypesAndUninstall( + base::PassKey<WebAppSyncBridge>(), app_id, + webapps::WebappUninstallSource::kSync, base::BindOnce(callback, app_id)); } } @@ -960,8 +961,9 @@ base::BindRepeating(&WebAppSyncBridge::OnWebAppUninstallComplete, weak_ptr_factory_.GetWeakPtr()); for (const auto& app_id : apps_uninstalling) { - command_scheduler_->RemoveUserUninstallableManagements( - app_id, webapps::WebappUninstallSource::kSync, + command_scheduler_->RemoveAllManagementTypesAndUninstall( + base::PassKey<WebAppSyncBridge>(), app_id, + webapps::WebappUninstallSource::kSync, base::BindOnce(callback, app_id)); } }
diff --git a/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc b/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc index 2b78800d..934eb43 100644 --- a/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc +++ b/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc
@@ -30,7 +30,6 @@ #include "chrome/browser/web_applications/test/web_app_test_observers.h" #include "chrome/browser/web_applications/test/web_app_test_utils.h" #include "chrome/browser/web_applications/web_app.h" -#include "chrome/browser/web_applications/web_app_command_manager.h" #include "chrome/browser/web_applications/web_app_command_scheduler.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_helpers.h" @@ -1250,6 +1249,45 @@ run_loop.Run(); } +// Tests that non user installable apps can also be removed by the +// WebAppSyncBridge during system startup, if `is_uninstalling` is set to true. +// Test for crbug.com/335253048, by using kSystem to mock that behavior. Since +// System Web Apps are only on Ash chrome, kPolicy is used instead on Lacro +TEST_F(WebAppSyncBridgeTest, CanDeleteNonUserInstallableApps) { + AppsList system_apps; + + // This app should be uninstalled, since the `is_uninstalling` field is set. + std::unique_ptr<WebApp> app1 = + test::CreateWebApp(GURL("https://example.com/app1")); +#if BUILDFLAG(IS_CHROMEOS_LACROS) + app1->AddSource(WebAppManagement::kPolicy); +#else + app1->AddSource(WebAppManagement::kSystem); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + app1->SetIsUninstalling(/*is_uninstalling=*/true); + const webapps::AppId app_id1 = app1->app_id(); + system_apps.push_back(std::move(app1)); + + // This app will not be uninstalled. + std::unique_ptr<WebApp> app2 = + test::CreateWebApp(GURL("https://example.com/app2")); +#if BUILDFLAG(IS_CHROMEOS_LACROS) + app2->AddSource(WebAppManagement::kPolicy); +#else + app2->AddSource(WebAppManagement::kSystem); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + const webapps::AppId app_id2 = app2->app_id(); + system_apps.push_back(std::move(app2)); + + Registry registry; + InsertAppsListIntoRegistry(®istry, system_apps); + database_factory().WriteRegistry(registry); + StartWebAppProvider(); + + EXPECT_FALSE(registrar().IsInstalled(app_id1)); + EXPECT_TRUE(registrar().IsInstalled(app_id2)); +} + // Tests that OnWebAppsWillBeUpdatedFromSync observer notification is called // properly. TEST_F(WebAppSyncBridgeTest,
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 49a1107..af497f7 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1713355171-b44ad20149199537d2c8265dac0605bd4e2d6490-3b980d0bd50a84f848f2bf420646bf9fbcbb1b98.profdata +chrome-linux-main-1713376773-7b0566891c51886cbdb77315dbb14db01a5e90e1-8cc1a248d1d7e9332208a6174ed0d44ee621affa.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 31d97cf..3c8083b9 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1713333322-40f5810d369cb8ed952a8867c60608f525e99db5-7bc4966503946ba325f1e1423e17fad345759c10.profdata +chrome-mac-main-1713376773-3408893c430a4f941667222519dd285658ce099e-8cc1a248d1d7e9332208a6174ed0d44ee621affa.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index 51688a0..060ca64 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1713355171-2ec78fd32eba8596f40d3b05141495c93d5f5af1-3b980d0bd50a84f848f2bf420646bf9fbcbb1b98.profdata +chrome-win-arm64-main-1713376773-4bbfeea1beeb6913c2d073d967ed0fb6ade09989-8cc1a248d1d7e9332208a6174ed0d44ee621affa.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 8fcaa98f..885be35c 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1713355171-82a021371f8f4f2b85f42da8f96dd684d5ddd892-3b980d0bd50a84f848f2bf420646bf9fbcbb1b98.profdata +chrome-win32-main-1713376773-0a2138f96e5d869c1903f37004a43d6ebfd3852e-8cc1a248d1d7e9332208a6174ed0d44ee621affa.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 4fa9505..b9ee36b 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1713365905-e9647723fe3c51687f256483b2c666efaa8b5e31-e4b2169c4cc286f2c8970f87af0ae945e2637f09.profdata +chrome-win64-main-1713376773-ca688a73be5affd1e7003c753db25cbe2adae9e3-8cc1a248d1d7e9332208a6174ed0d44ee621affa.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index ba19af5..84d80b7 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -1119,7 +1119,7 @@ #endif // Enables Safety Hub feature. -BASE_FEATURE(kSafetyHub, "SafetyHub", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kSafetyHub, "SafetyHub", base::FEATURE_ENABLED_BY_DEFAULT); // Time between automated runs of the password check. const base::FeatureParam<base::TimeDelta> kBackgroundPasswordCheckInterval{
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.cc b/chrome/renderer/accessibility/read_anything_app_controller.cc index c9f6f627..fc58798b 100644 --- a/chrome/renderer/accessibility/read_anything_app_controller.cc +++ b/chrome/renderer/accessibility/read_anything_app_controller.cc
@@ -22,11 +22,13 @@ #include "components/translate/core/common/translate_constants.h" #include "content/public/renderer/chrome_object_extensions_utils.h" #include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_thread.h" #include "gin/converter.h" #include "gin/dictionary.h" #include "gin/handle.h" #include "gin/object_template_builder.h" -#include "read_anything_app_controller.h" +#include "services/metrics/public/cpp/mojo_ukm_recorder.h" +#include "services/metrics/public/cpp/ukm_builders.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -380,9 +382,16 @@ distiller_ = std::make_unique<AXTreeDistiller>( base::BindRepeating(&ReadAnythingAppController::OnAXTreeDistilled, weak_ptr_factory_.GetWeakPtr())); + // TODO(crbug.com/1450930): Use a global ukm recorder instance instead. + mojo::Remote<ukm::mojom::UkmRecorderFactory> factory; + content::RenderThread::Get()->BindHostReceiver( + factory.BindNewPipeAndPassReceiver()); + ukm_recorder_ = ukm::MojoUkmRecorder::Create(*factory); } -ReadAnythingAppController::~ReadAnythingAppController() = default; +ReadAnythingAppController::~ReadAnythingAppController() { + RecordNumSelections(); +} void ReadAnythingAppController::AccessibilityEventReceived( const ui::AXTreeID& tree_id, @@ -433,8 +442,9 @@ if (tree_id == model_.active_tree_id() && !is_pdf) { return; } + RecordNumSelections(); model_.set_active_tree_id(tree_id); - model_.SetActiveUkmSourceId(ukm_source_id); + model_.set_ukm_source_id(ukm_source_id); model_.set_is_pdf(is_pdf); // Delete all pending updates on the formerly active AXTree. // TODO(crbug.com/1266555): If distillation is in progress, cancel the @@ -454,6 +464,14 @@ } } +void ReadAnythingAppController::RecordNumSelections() { + ukm::builders::Accessibility_ReadAnything_EmptyState( + model_.ukm_source_id()) + .SetTotalNumSelections(model_.num_selections()) + .Record(ukm_recorder_.get()); + model_.set_num_selections(0); +} + void ReadAnythingAppController::OnAXTreeDestroyed(const ui::AXTreeID& tree_id) { model_.OnAXTreeDestroyed(tree_id); } @@ -491,7 +509,7 @@ } CHECK(serializer.SerializeChanges(tree->root(), &snapshot)); model_.SetDistillationInProgress(true); - distiller_->Distill(*tree, snapshot, model_.active_ukm_source_id()); + distiller_->Distill(*tree, snapshot, model_.ukm_source_id()); } void ReadAnythingAppController::OnAXTreeDistilled(
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.h b/chrome/renderer/accessibility/read_anything_app_controller.h index 6ceb62bd..5757341 100644 --- a/chrome/renderer/accessibility/read_anything_app_controller.h +++ b/chrome/renderer/accessibility/read_anything_app_controller.h
@@ -36,6 +36,10 @@ class AXTree; } // namespace ui +namespace ukm { +class MojoUkmRecorder; +} // namespace ukm + class AXTreeDistiller; class ReadAnythingAppControllerTest; @@ -261,6 +265,10 @@ // node isn't in the current segment. int GetCurrentTextEndIndex(ui::AXNodeID node_id); + // Records the number of selections that occurred for the active page. Called + // when the active tree changes. + void RecordNumSelections(); + // SetContentForTesting, SetThemeForTesting, and SetLanguageForTesting are // used by ReadAnythingAppTest and thus need to be kept in // ReadAnythingAppController even though ReadAnythingAppControllerBrowserTest @@ -310,6 +318,8 @@ // For metrics logging + std::unique_ptr<ukm::MojoUkmRecorder> ukm_recorder_; + // The time when the renderer constructor is first triggered. base::TimeTicks renderer_load_triggered_time_ms_;
diff --git a/chrome/renderer/accessibility/read_anything_app_model.cc b/chrome/renderer/accessibility/read_anything_app_model.cc index 48a5d88..eaca3b73 100644 --- a/chrome/renderer/accessibility/read_anything_app_model.cc +++ b/chrome/renderer/accessibility/read_anything_app_model.cc
@@ -10,8 +10,6 @@ #include "base/containers/contains.h" #include "base/metrics/histogram_functions.h" #include "content/public/renderer/render_thread.h" -#include "services/metrics/public/cpp/mojo_ukm_recorder.h" -#include "services/metrics/public/cpp/ukm_builders.h" #include "ui/accessibility/accessibility_features.h" #include "ui/accessibility/ax_enum_util.h" #include "ui/accessibility/ax_enums.mojom-shared.h" @@ -21,6 +19,7 @@ #include "ui/accessibility/ax_serializable_tree.h" #include "ui/accessibility/ax_text_utils.h" #include "ui/accessibility/ax_tree_update_util.h" +#include "url/gurl.h" namespace { @@ -44,17 +43,9 @@ } // namespace -ReadAnythingAppModel::ReadAnythingAppModel() { - // TODO(crbug.com/1450930): Use a global ukm recorder instance instead. - mojo::Remote<ukm::mojom::UkmRecorderFactory> factory; - content::RenderThread::Get()->BindHostReceiver( - factory.BindNewPipeAndPassReceiver()); - ukm_recorder_ = ukm::MojoUkmRecorder::Create(*factory); -} +ReadAnythingAppModel::ReadAnythingAppModel() = default; -ReadAnythingAppModel::~ReadAnythingAppModel() { - SetActiveUkmSourceId(ukm::kInvalidSourceId); -} +ReadAnythingAppModel::~ReadAnythingAppModel() = default; ReadAnythingAppModel::AXTreeInfo::AXTreeInfo( std::unique_ptr<ui::AXTreeManager> other) { @@ -161,7 +152,7 @@ base::UmaHistogramEnumeration( string_constants::kEmptyStateHistogramName, ReadAnythingEmptyState::kSelectionAfterEmptyStateShown); - num_selections_++; + tree_infos_.at(active_tree_id_)->num_selections++; } // If the main panel selection contains content outside of the distilled @@ -579,23 +570,61 @@ // TODO(crbug.com/1266555): If distillation is in progress, cancel the // distillation request. active_tree_id_ = ui::AXTreeIDUnknown(); - SetActiveUkmSourceId(ukm::kInvalidSourceId); + set_ukm_source_id(ukm::kInvalidSourceId); } EraseTree(tree_id); } -void ReadAnythingAppModel::SetActiveUkmSourceId( - const ukm::SourceId& source_id) { - // Record the number of selections made on the current page if it was not - // distillable. - if (active_ukm_source_id_ != ukm::kInvalidSourceId && - content_node_ids_.empty()) { - ukm::builders::Accessibility_ReadAnything_EmptyState(active_ukm_source_id_) - .SetTotalNumSelections(num_selections_) - .Record(ukm_recorder_.get()); +const ukm::SourceId& ReadAnythingAppModel::ukm_source_id() { + if (base::Contains(tree_infos_, active_tree_id_)) { + ReadAnythingAppModel::AXTreeInfo* tree_info = + tree_infos_.at(active_tree_id_).get(); + if (tree_info) { + return tree_info->ukm_source_id; + } } - num_selections_ = 0; - active_ukm_source_id_ = source_id; + return ukm::kInvalidSourceId; +} + +void ReadAnythingAppModel::set_ukm_source_id( + const ukm::SourceId ukm_source_id) { + if (!base::Contains(tree_infos_, active_tree_id_)) { + return; + } + ReadAnythingAppModel::AXTreeInfo* tree_info = + tree_infos_.at(active_tree_id_).get(); + if (!tree_info) { + return; + } + if (tree_info->ukm_source_id == ukm::kInvalidSourceId) { + tree_info->ukm_source_id = ukm_source_id; + } else { + DCHECK_EQ(tree_info->ukm_source_id, ukm_source_id); + } +} + +int32_t ReadAnythingAppModel::num_selections() { + if (base::Contains(tree_infos_, active_tree_id_)) { + ReadAnythingAppModel::AXTreeInfo* tree_info = + tree_infos_.at(active_tree_id_).get(); + if (tree_info) { + return tree_info->num_selections; + } + } + return 0; +} + +void ReadAnythingAppModel::set_num_selections( + const int32_t& num_selections) { + if (!base::Contains(tree_infos_, active_tree_id_)) { + return; + } + ReadAnythingAppModel::AXTreeInfo* tree_info = + tree_infos_.at(active_tree_id_).get(); + if (!tree_info) { + return; + } + tree_info->num_selections = num_selections; } ui::AXNode* ReadAnythingAppModel::GetAXNode(
diff --git a/chrome/renderer/accessibility/read_anything_app_model.h b/chrome/renderer/accessibility/read_anything_app_model.h index 381d5a0..d48a37a 100644 --- a/chrome/renderer/accessibility/read_anything_app_model.h +++ b/chrome/renderer/accessibility/read_anything_app_model.h
@@ -26,10 +26,6 @@ class AXSerializableTree; } // namespace ui -namespace ukm { -class MojoUkmRecorder; -} - // A class that holds state for the ReadAnythingAppController for the Read // Anything WebUI app. class ReadAnythingAppModel { @@ -49,17 +45,27 @@ // AXTreeManagers. std::unique_ptr<ui::AXTreeManager> manager; + // The UKM source ID of the main frame that sources this AXTree. This is + // used for metrics collection. Only root AXTrees have this set. + ukm::SourceId ukm_source_id = ukm::kInvalidSourceId; + + // Used to keep track of how many selections were made for the + // ukm_source_id. Only recorded during the select-to-distill flow (when the + // empty state page is shown). + int32_t num_selections = 0; + // Whether URL information, namely is_docs, has been set. bool is_url_information_set = false; // Google Docs are different from regular webpages. We want to distill - // content from the annotated canvas elements, not the main tree. + // content from the annotated canvas elements, not the main tree. Only root + // AXTrees have this set. bool is_docs = false; // TODO(41496290): Include any information that is associated with a - // particular AXTree, namely is_pdf and ukm_id. Right now, those are set - // every time the active ax tree id changes; instead, they should be set - // once when a new tree is added. + // particular AXTree, namely is_pdf. Right now, this is set every time the + // active ax tree id changes; instead, it should be set once when a new tree + // is added. }; // A current segment of text that will be consumed by Read Aloud. @@ -171,10 +177,6 @@ page_finished_loading_ = value; } - const ukm::SourceId& active_ukm_source_id() const { - return active_ukm_source_id_; - } - const std::vector<ui::AXNodeID>& content_node_ids() const { return content_node_ids_; } @@ -193,7 +195,12 @@ void SetDistillationInProgress(bool distillation) { distillation_in_progress_ = distillation; } - void SetActiveUkmSourceId(const ukm::SourceId& source_id); + + const ukm::SourceId& ukm_source_id(); + void set_ukm_source_id(const ukm::SourceId ukm_source_id); + int32_t num_selections(); + void set_num_selections(const int32_t& num_selections); + void AddUrlInformationForTreeId(const ui::AXTreeID& tree_id); bool IsDocs() const; @@ -420,10 +427,6 @@ // child). ui::AXTreeID active_tree_id_ = ui::AXTreeIDUnknown(); - // The UKM source ID of the main frame of the active web contents, whose - // AXTree has ID active_tree_id_. This is used for metrics collection. - ukm::SourceId active_ukm_source_id_ = ukm::kInvalidSourceId; - // PDFs are handled differently than regular webpages. That is because they // are stored in a different web contents and the actual PDF text is inside an // iframe. In order to get tree information from the PDF web contents, we need @@ -489,13 +492,6 @@ ui::AXNodeID image_to_update_node_id_ = ui::kInvalidAXNodeID; bool selection_from_action_ = false; - std::unique_ptr<ukm::MojoUkmRecorder> ukm_recorder_; - - // Used to keep track of how many selections were made for the - // active_ukm_source_id_. Only recorded during the select-to-distill flow - // (when the empty state page is shown). - int32_t num_selections_ = 0; - // For screen2x data collection, Chrome is launched from the CLI to open one // webpage. We record the result of the distill() call for this entire // webpage, so we only make the call once the webpage finished loading.
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7564c971..958c811 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3509,7 +3509,10 @@ "../browser/lifetime/application_lifetime_browsertest.cc", "../browser/ui/views/enable_link_capturing_infobar_browsertest.cc", ] - deps += [ "//chrome/browser/apps/link_capturing" ] + deps += [ + "//chrome/browser/apps/link_capturing", + "//chrome/browser/shortcuts:browser_tests", + ] } if (is_win || is_chromeos || is_mac) { @@ -5586,6 +5589,7 @@ "../browser/accessibility/live_caption/live_caption_surface_browsertest.cc", "../browser/chromeos/enterprise/cloud_storage/one_drive_pref_observer_browsertest.cc", "../browser/chromeos/extensions/contact_center_insights/contact_center_insights_extension_manager_lacros_browsertest.cc", + "../browser/chromeos/extensions/info_private_lacros_apitest.cc", "../browser/chromeos/extensions/login_screen/login_screen_storage/login_screen_storage_apitest.cc", "../browser/chromeos/extensions/odfs_config_private/odfs_config_private_api_browsertest.cc", "../browser/chromeos/extensions/wallpaper_apitest.cc",
diff --git a/chrome/test/base/ash/extension_js_browser_test.cc b/chrome/test/base/ash/extension_js_browser_test.cc index a84d111..0b6d33a 100644 --- a/chrome/test/base/ash/extension_js_browser_test.cc +++ b/chrome/test/base/ash/extension_js_browser_test.cc
@@ -13,21 +13,95 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" +#include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/test/base/ash/javascript_browser_test.h" +#include "chrome/test/base/test_switches.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_utils.h" #include "extensions/browser/background_script_executor.h" #include "extensions/browser/browsertest_util.h" #include "extensions/browser/extension_host.h" #include "extensions/browser/extension_host_test_helper.h" -#include "chrome/test/base/test_switches.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_registry_observer.h" +#include "extensions/browser/process_manager.h" +#include "extensions/browser/service_worker/service_worker_host.h" +#include "extensions/browser/service_worker/service_worker_task_queue.h" +#include "extensions/common/extension.h" #include "ui/base/ime/ash/extension_ime_util.h" namespace { +// Class to observe service worker readiness for the execution of test JS. +class ExtensionTestObserver + : public extensions::ServiceWorkerTaskQueue::TestObserver, + public extensions::ExtensionRegistryObserver { + public: + explicit ExtensionTestObserver(const char* extension_id, + content::BrowserContext* context) + : extension_id_(extension_id), context_(context) { + extensions::ExtensionRegistry::Get(context_)->AddObserver(this); + extensions::ServiceWorkerTaskQueue::SetObserverForTest(this); + } + + ~ExtensionTestObserver() override { + extensions::ExtensionRegistry::Get(context_)->RemoveObserver(this); + extensions::ServiceWorkerTaskQueue::SetObserverForTest(nullptr); + } + + int WaitForManifestVersion() { + if (manifest_version_) { + return manifest_version_; + } + base::RunLoop waiter; + manifest_quit_ = waiter.QuitClosure(); + waiter.Run(); + return manifest_version_; + } + + void WaitForServiceWorkerStart() { + if (started_) { + return; + } + base::RunLoop waiter; + started_quit_ = waiter.QuitClosure(); + waiter.Run(); + } + + // extensions::ExtensionRegistryObserver: + void OnExtensionLoaded(content::BrowserContext* context, + const extensions::Extension* extension) override { + if (context == context_ && extension->id() == extension_id_) { + manifest_version_ = extension->manifest_version(); + if (manifest_quit_) { + std::move(manifest_quit_).Run(); + } + } + } + + // extensions::ServiceWorkerTaskQueue::TestObserver: + void DidStartWorker(const std::string& extension_id) override { + if (extension_id == extension_id_) { + started_ = true; + if (started_quit_) { + std::move(started_quit_).Run(); + } + } + } + + private: + const std::string extension_id_; + // Not owned. + raw_ptr<content::BrowserContext> context_; + size_t manifest_version_ = 0; + bool started_ = false; + base::OnceClosure manifest_quit_; + base::OnceClosure started_quit_; +}; + const std::vector<std::string>& GetExtensionIdsToCollectCoverage() { static const std::vector<std::string> extensions_for_coverage = { extension_misc::kChromeVoxExtensionId, @@ -73,8 +147,20 @@ void ExtensionJSBrowserTest::WaitForExtension(const char* extension_id, base::OnceClosure load_cb) { extension_id_ = extension_id; + + // ExtensionHosts only exist when there is an associated RenderFrame. + // Initialize both an ExtensionHostTestHelper and a ServiceWorkerObserver + // before running the load callback, to avoid missing the relevant event. extensions::ExtensionHostTestHelper host_helper(GetProfile(), extension_id); + ExtensionTestObserver observer(extension_id, GetProfile()); std::move(load_cb).Run(); + + if (observer.WaitForManifestVersion() == 3) { + observer.WaitForServiceWorkerStart(); + extension_host_browser_context_ = GetProfile(); + return; + } + extensions::ExtensionHost* extension_host = host_helper.WaitForHostCompletedFirstLoad(); ASSERT_TRUE(extension_host);
diff --git a/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js b/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js index ab1228f6..9b446fcb 100644 --- a/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js +++ b/chrome/test/data/extensions/api_test/chromeos_info_private/extended/background.js
@@ -18,6 +18,8 @@ 'assistantStatus', 'isMeetDevice', 'deviceRequisition', + 'hwid', + 'customizationId', ], chrome.test.callbackPass(function(values) { switch (testName) { case 'kiosk': @@ -68,11 +70,20 @@ case 'Is Meet Device - False' : chrome.test.assertFalse(values['isMeetDevice']); break; - case 'Device Requisition - Remora' : + case 'Machine Statistics Properties - Unset' : + chrome.test.assertEq('', values['deviceRequisition']); + chrome.test.assertEq('', values['hwid']); + chrome.test.assertEq('', values['customizationId']); + break; + case 'Device Requisition - Remora': chrome.test.assertEq('remora', values['deviceRequisition']); break; - case 'Device Requisition - Unset' : - chrome.test.assertEq('', values['deviceRequisition']); + case 'HWID': + chrome.test.assertEq('test_hw', values['hwid']); + break; + case 'CustomizationId': + chrome.test.assertEq('test_customization_id', + values['customizationId']); break; } }));
diff --git a/chrome/test/data/extensions/api_test/user_scripts/configure_world/worker.js b/chrome/test/data/extensions/api_test/user_scripts/configure_world/worker.js index 75c42b2..9fd001a 100644 --- a/chrome/test/data/extensions/api_test/user_scripts/configure_world/worker.js +++ b/chrome/test/data/extensions/api_test/user_scripts/configure_world/worker.js
@@ -50,6 +50,19 @@ } chrome.test.runTests([ + async function UserScriptWorld_worldIdValidation() { + await chrome.test.assertPromiseRejects( + chrome.userScripts.configureWorld({csp: '', worldId: ''}), + 'Error: If specified, `worldId` must be non-empty.'); + await chrome.test.assertPromiseRejects( + chrome.userScripts.configureWorld({csp: '', worldId: '_foobar'}), + `Error: World IDs beginning with '_' are reserved.`); + await chrome.test.assertPromiseRejects( + chrome.userScripts.configureWorld({csp: '', worldId: 'a'.repeat(257)}), + 'Error: World IDs must be at most 256 characters.'); + chrome.test.succeed(); + }, + // Tests that a registered user script in the USER_SCRIPT world cannot send or // receive messages when messaging is disabled. async function UserScriptWorld_messagingDisabled() {
diff --git a/chrome/test/data/extensions/api_test/user_scripts/register/worker.js b/chrome/test/data/extensions/api_test/user_scripts/register/worker.js index e289274..bcb04a1 100644 --- a/chrome/test/data/extensions/api_test/user_scripts/register/worker.js +++ b/chrome/test/data/extensions/api_test/user_scripts/register/worker.js
@@ -223,6 +223,22 @@ chrome.test.succeed(); }, + async function registeringScriptWithInvalidWorldIdThrowsAnError() { + await chrome.userScripts.unregister(); + + const scripts = [{ + id: 'invalidMatchPattern', + matches: ['http://example.com/*'], + js: [{file: 'script.js'}], + worldId: '_' + }]; + + await chrome.test.assertPromiseRejects( + chrome.userScripts.register(scripts), + `Error: World IDs beginning with '_' are reserved.`); + chrome.test.succeed(); + }, + // Tests that a registered user script with files is injected into a frame // where the extension has host permissions for and matches the script match // patterns.
diff --git a/chrome/test/data/extensions/api_test/user_scripts/update/worker.js b/chrome/test/data/extensions/api_test/user_scripts/update/worker.js index 751714c..629e5e4 100644 --- a/chrome/test/data/extensions/api_test/user_scripts/update/worker.js +++ b/chrome/test/data/extensions/api_test/user_scripts/update/worker.js
@@ -171,6 +171,32 @@ chrome.test.succeed(); }, + async function updatingToAnInvalidWorldIdThrowsError() { + await chrome.userScripts.unregister(); + + // Register user script. + const scriptToRegister = [ + {id: 'us1', matches: ['*://*/*'], js: [{file: 'user_script.js'}]}, + ]; + await chrome.userScripts.register(scriptToRegister); + + // Updating a script with an invalid world ID should fail. + const scriptUpdate = [ + { + id: 'us1', + matches: ['*://*/*'], + js: [{file: 'user_script.js'}], + worldId: '_', + } + ]; + + await chrome.test.assertPromiseRejects( + chrome.userScripts.update(scriptUpdate), + `Error: World IDs beginning with '_' are reserved.`); + + chrome.test.succeed(); + }, + // Tests that calling userScripts.update with a specific ID updates such // script and does not inject them into a (former) matching frame. async function scriptUpdated() {
diff --git a/chrome/test/data/focus_rings/focus_ring_browsertest_anchor_win.png b/chrome/test/data/focus_rings/focus_ring_browsertest_anchor_win.png index 6b146c1..b50c35e 100644 --- a/chrome/test/data/focus_rings/focus_ring_browsertest_anchor_win.png +++ b/chrome/test/data/focus_rings/focus_ring_browsertest_anchor_win.png Binary files differ
diff --git a/chrome/test/data/focus_rings/focus_ring_browsertest_button_win.png b/chrome/test/data/focus_rings/focus_ring_browsertest_button_win.png index 3fced26..0680afc6 100644 --- a/chrome/test/data/focus_rings/focus_ring_browsertest_button_win.png +++ b/chrome/test/data/focus_rings/focus_ring_browsertest_button_win.png Binary files differ
diff --git a/chrome/test/data/focus_rings/focus_ring_browsertest_checkbox_win.png b/chrome/test/data/focus_rings/focus_ring_browsertest_checkbox_win.png index e13284c..5eb51cb 100644 --- a/chrome/test/data/focus_rings/focus_ring_browsertest_checkbox_win.png +++ b/chrome/test/data/focus_rings/focus_ring_browsertest_checkbox_win.png Binary files differ
diff --git a/chrome/test/data/focus_rings/focus_ring_browsertest_dark_mode_button_win.png b/chrome/test/data/focus_rings/focus_ring_browsertest_dark_mode_button_win.png index 89d7308..a621f12e 100644 --- a/chrome/test/data/focus_rings/focus_ring_browsertest_dark_mode_button_win.png +++ b/chrome/test/data/focus_rings/focus_ring_browsertest_dark_mode_button_win.png Binary files differ
diff --git a/chrome/test/data/focus_rings/focus_ring_browsertest_radio_win.png b/chrome/test/data/focus_rings/focus_ring_browsertest_radio_win.png index 62241ce..0bce232 100644 --- a/chrome/test/data/focus_rings/focus_ring_browsertest_radio_win.png +++ b/chrome/test/data/focus_rings/focus_ring_browsertest_radio_win.png Binary files differ
diff --git a/chrome/test/data/shortcuts/default_icon_has_two/16_favicon_part.png b/chrome/test/data/shortcuts/default_icon_has_two/16_favicon_part.png new file mode 100644 index 0000000..4d217e8 --- /dev/null +++ b/chrome/test/data/shortcuts/default_icon_has_two/16_favicon_part.png Binary files differ
diff --git a/chrome/test/data/shortcuts/default_icon_has_two/32_favicon_part.png b/chrome/test/data/shortcuts/default_icon_has_two/32_favicon_part.png new file mode 100644 index 0000000..81e1fa4 --- /dev/null +++ b/chrome/test/data/shortcuts/default_icon_has_two/32_favicon_part.png Binary files differ
diff --git a/chrome/test/data/shortcuts/default_icon_has_two/favicon.ico b/chrome/test/data/shortcuts/default_icon_has_two/favicon.ico new file mode 100644 index 0000000..e27eec3 --- /dev/null +++ b/chrome/test/data/shortcuts/default_icon_has_two/favicon.ico Binary files differ
diff --git a/chrome/test/data/shortcuts/default_icon_has_two/index.html b/chrome/test/data/shortcuts/default_icon_has_two/index.html new file mode 100644 index 0000000..94d7fa4 --- /dev/null +++ b/chrome/test/data/shortcuts/default_icon_has_two/index.html
@@ -0,0 +1,11 @@ +<html> + +<title>Page without default favicon</title> + +<head></head> + +<body> + <h1>This page has a default favicon, with two icons inside it.</h1> +</body> + +</html> \ No newline at end of file
diff --git a/chrome/test/data/shortcuts/green.png b/chrome/test/data/shortcuts/green.png new file mode 100644 index 0000000..c7510d38 --- /dev/null +++ b/chrome/test/data/shortcuts/green.png Binary files differ
diff --git a/chrome/test/data/shortcuts/no_icons_page.html b/chrome/test/data/shortcuts/no_icons_page.html new file mode 100644 index 0000000..42d323d --- /dev/null +++ b/chrome/test/data/shortcuts/no_icons_page.html
@@ -0,0 +1,10 @@ +<html> +<title>Page without icons</title> + +<head></head> + +<body> + <h1>This page has no icons.</h1> +</body> + +</html> \ No newline at end of file
diff --git a/chrome/test/data/shortcuts/noise.png b/chrome/test/data/shortcuts/noise.png new file mode 100644 index 0000000..81acb31 --- /dev/null +++ b/chrome/test/data/shortcuts/noise.png Binary files differ
diff --git a/chrome/test/data/shortcuts/page_icons.html b/chrome/test/data/shortcuts/page_icons.html new file mode 100644 index 0000000..40f787d91 --- /dev/null +++ b/chrome/test/data/shortcuts/page_icons.html
@@ -0,0 +1,13 @@ +<html> +<title>Page with icon links</title> + +<head> + <link rel="apple-touch-icon" href="green.png" /> + <link rel="icon" href="noise.png" /> +</head> + +<body> + <h1>Page with icon links</h1> +</body> + +</html> \ No newline at end of file
diff --git a/chrome/test/data/webui/commerce/product_specifications/BUILD.gn b/chrome/test/data/webui/commerce/product_specifications/BUILD.gn index 268ab75..975aa4a 100644 --- a/chrome/test/data/webui/commerce/product_specifications/BUILD.gn +++ b/chrome/test/data/webui/commerce/product_specifications/BUILD.gn
@@ -7,14 +7,16 @@ build_webui_tests("build") { files = [ "app_test.ts", + "product_selector_test.ts", "table_test.ts", ] - ts_path_mappings = - [ "chrome://compare/*|" + - rebase_path("$root_gen_dir/chrome/browser/resources/commerce/product_specifications/tsc/*", - target_gen_dir) ] + ts_path_mappings = [ "chrome://compare/*|" + rebase_path( + "$root_gen_dir/chrome/browser/resources/commerce/product_specifications/tsc/*", + target_gen_dir) ] ts_deps = [ "//chrome/browser/resources/commerce/product_specifications:build_ts", "//ui/webui/resources/cr_components/commerce:build_ts", + "//ui/webui/resources/js:build_ts", + "//ui/webui/resources/mojo:build_ts", ] }
diff --git a/chrome/test/data/webui/commerce/product_specifications/product_selector_test.ts b/chrome/test/data/webui/commerce/product_specifications/product_selector_test.ts new file mode 100644 index 0000000..445742ac --- /dev/null +++ b/chrome/test/data/webui/commerce/product_specifications/product_selector_test.ts
@@ -0,0 +1,55 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://compare/product_selector.js'; + +import type {ProductSelectorElement} from 'chrome://compare/product_selector.js'; +import {BrowserProxyImpl} from 'chrome://resources/cr_components/commerce/browser_proxy.js'; +import {stringToMojoString16, stringToMojoUrl} from 'chrome://resources/js/mojo_type_util.js'; +import {assertEquals} from 'chrome://webui-test/chai_assert.js'; +import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; +import {TestMock} from 'chrome://webui-test/test_mock.js'; + +suite('ProductSelectorTest', () => { + const shoppingServiceApi = TestMock.fromClass(BrowserProxyImpl); + + async function createSelector(): Promise<ProductSelectorElement> { + const selector = document.createElement('product-selector'); + document.body.appendChild(selector); + await flushTasks(); + return selector; + } + + setup(async () => { + shoppingServiceApi.reset(); + document.body.innerHTML = window.trustedTypes!.emptyHTML; + BrowserProxyImpl.setInstance(shoppingServiceApi); + }); + + test('OpenTabsShown', async () => { + const titleString = 'title'; + const openTabs = [{ + title: stringToMojoString16(titleString), + url: stringToMojoUrl('http://example.com'), + }]; + const selector = await createSelector(); + + shoppingServiceApi.setResultFor( + 'getUrlInfosForOpenTabs', Promise.resolve({urlInfos: openTabs})); + + assertEquals(0, shoppingServiceApi.getCallCount('getUrlInfosForOpenTabs')); + + selector.$.currentItemButton.click(); + + await shoppingServiceApi.whenCalled('getUrlInfosForOpenTabs'); + + await flushTasks(); + + // Ensure the number of list items is equal to the number of open tabs. + assertEquals(openTabs.length, selector.openTabs.length); + + assertEquals(titleString, selector.openTabs[0]!.title); + assertEquals(openTabs[0]!.url.url, selector.openTabs[0]!.url); + }); +});
diff --git a/chrome/test/data/webui/commerce/product_specifications/product_specifications_browsertest.cc b/chrome/test/data/webui/commerce/product_specifications/product_specifications_browsertest.cc index e8f1b615..09b3791 100644 --- a/chrome/test/data/webui/commerce/product_specifications/product_specifications_browsertest.cc +++ b/chrome/test/data/webui/commerce/product_specifications/product_specifications_browsertest.cc
@@ -28,3 +28,8 @@ IN_PROC_BROWSER_TEST_F(ProductSpecificationsTest, Table) { RunTest("commerce/product_specifications/table_test.js", "mocha.run()"); } + +IN_PROC_BROWSER_TEST_F(ProductSpecificationsTest, ProductSelector) { + RunTest("commerce/product_specifications/product_selector_test.js", + "mocha.run()"); +}
diff --git a/chrome/test/data/webui/commerce/product_specifications/table_test.ts b/chrome/test/data/webui/commerce/product_specifications/table_test.ts index 3f24ec6..48eb41b0 100644 --- a/chrome/test/data/webui/commerce/product_specifications/table_test.ts +++ b/chrome/test/data/webui/commerce/product_specifications/table_test.ts
@@ -17,21 +17,17 @@ document.body.appendChild(tableElement); }); - test('product columns show the correct data', async () => { - // Arrange. - const title1 = 'foo'; - const title2 = 'bar'; - - // Act. - tableElement.columns = [{title: title1}, {title: title2}]; + test('column count correct', async () => { + // Arrange / Act. + tableElement.columns = [ + {selectedItem: {title: 'title', url: '', imageUrl: ''}}, + {selectedItem: {title: 'title2', url: '', imageUrl: ''}}, + ]; await waitAfterNextRender(tableElement); // Assert. - const columnTitles = - tableElement.shadowRoot!.querySelectorAll('.col .col-card'); - assertEquals(2, columnTitles.length); - assertEquals(title1, columnTitles[0]!.textContent); - assertEquals(title2, columnTitles[1]!.textContent); + const columns = tableElement.shadowRoot!.querySelectorAll('.col'); + assertEquals(2, columns.length); }); test('product rows show the correct data', async () => {
diff --git a/chrome/test/data/webui/cr_elements/cr_icon_test.ts b/chrome/test/data/webui/cr_elements/cr_icon_test.ts index 6c736049..6aa6a27 100644 --- a/chrome/test/data/webui/cr_elements/cr_icon_test.ts +++ b/chrome/test/data/webui/cr_elements/cr_icon_test.ts
@@ -126,4 +126,39 @@ svg = icon.shadowRoot!.querySelector('svg'); assertTrue(!!svg); }); + + test('cr-iconset used rather than iron-iconset', async () => { + // Add an iron-iconset to the document. + const template = html`<iron-iconset-svg name="cr20-test" size="20"> + <svg> + <defs> + <g id="arrow"> + <path d="M7 10l5 5 5-5z"></path> + </g> + </defs> + </svg> + </iron-iconset-svg>`; + document.head.appendChild(template.content); + + // Add a cr-iconset with the same name. + const iconsetHtml = litHtml` + <cr-iconset name="cr20-test" size="20"> + <svg> + <defs> + <g id="arrow"> + <path d="M7 14l5-5 5 5z"></path> + </g> + </defs> + </svg> + </cr-iconset>`; + render(iconsetHtml, document.head); + + icon.icon = 'cr20-test:arrow'; + await microtasksFinished(); + const svg = icon.shadowRoot!.querySelector('svg'); + assertTrue(!!svg); + + // Confirm the cr-iconset value. + assertSvgPath(svg, 'M7 14l5-5 5 5z'); + }); });
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index bab12d1..72cf7bb 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -350,6 +350,7 @@ "os_settings_ui/os_settings_ui_menu_test.ts", "os_settings_ui/os_settings_ui_page_availability_test.ts", "os_settings_ui/os_settings_ui_page_visibility_revamp_test.ts", + "os_settings_ui/os_settings_ui_pref_sync_test.ts", "os_settings_ui/os_settings_ui_test.ts", "os_settings_ui/os_settings_ui_toolbar_test.ts", "os_settings_ui/page_availability_test_helpers.ts",
diff --git a/chrome/test/data/webui/settings/chromeos/internet_page/internet_detail_subpage_test.ts b/chrome/test/data/webui/settings/chromeos/internet_page/internet_detail_subpage_test.ts index 0c6a9df..e925626 100644 --- a/chrome/test/data/webui/settings/chromeos/internet_page/internet_detail_subpage_test.ts +++ b/chrome/test/data/webui/settings/chromeos/internet_page/internet_detail_subpage_test.ts
@@ -1963,6 +1963,79 @@ }); }); + [true, false].forEach(isApnPoliciesEnabled => { + test( + `Managed APN icon visibility when isApnPoliciesEnabled is ${ + isApnPoliciesEnabled}`, + async () => { + loadTimeData.overrideValues({ + isApnRevampEnabled: true, + isApnPoliciesEnabled: isApnPoliciesEnabled, + }); + init(); + mojoApi.setNetworkTypeEnabledState(NetworkType.kCellular, true); + const apnName = 'test'; + const testIccid = '11111'; + const cellularNetwork = + getManagedProperties(NetworkType.kCellular, 'cellular'); + cellularNetwork.typeProperties.cellular!.connectedApn = { + accessPointName: '', + id: '', + authentication: ApnAuthenticationType.kAutomatic, + language: undefined, + localizedName: undefined, + name: undefined, + password: undefined, + username: undefined, + attach: undefined, + state: ApnState.kEnabled, + ipType: ApnIpType.kAutomatic, + apnTypes: [], + source: ApnSource.kModb, + }; + cellularNetwork.typeProperties.cellular!.connectedApn! + .accessPointName = apnName; + cellularNetwork.typeProperties.cellular!.iccid = testIccid; + mojoApi.setManagedPropertiesForTest(cellularNetwork); + internetDetailPage.init('cellular_guid', 'Cellular', 'cellular'); + + // Set cellular network as active SIM so that APN row should show up + // if the flag is enabled. + mojoApi.setDeviceStateForTest({ + ...getDefaultDeviceStateProps(), + deviceState: DeviceStateType.kEnabled, + simInfos: [{ + iccid: testIccid, + isPrimary: true, + slotId: 0, + eid: '', + }], + }); + await flushTasks(); + assertTrue(!!internetDetailPage.shadowRoot!.querySelector( + '#apnSubpageButton')); + + // Check for APN policies managed icon. + const getApnManagedIcon = () => + internetDetailPage.shadowRoot!.querySelector('#apnManagedIcon'); + assertFalse(!!getApnManagedIcon()); + + internetDetailPage.globalPolicy = { + ...getDefaultGlobalPolicy(), + allowApnModification: true, + }; + await flushTasks(); + assertFalse(!!getApnManagedIcon()); + + internetDetailPage.globalPolicy = { + ...getDefaultGlobalPolicy(), + allowApnModification: false, + }; + await flushTasks(); + assertEquals(isApnPoliciesEnabled, !!getApnManagedIcon()); + }); + }); + test('Cellular network not found while in detail subpage', async () => { init(); mojoApi.setNetworkTypeEnabledState(NetworkType.kCellular, true);
diff --git a/chrome/test/data/webui/settings/chromeos/os_apps_page/os_apps_page_test.ts b/chrome/test/data/webui/settings/chromeos/os_apps_page/os_apps_page_test.ts index 413da33..be504cc 100644 --- a/chrome/test/data/webui/settings/chromeos/os_apps_page/os_apps_page_test.ts +++ b/chrome/test/data/webui/settings/chromeos/os_apps_page/os_apps_page_test.ts
@@ -25,6 +25,8 @@ const isRevampWayfindingEnabled = loadTimeData.getBoolean('isRevampWayfindingEnabled'); +const isAppParentalControlsAvailable = + loadTimeData.getBoolean('isAppParentalControlsFeatureAvailable'); let appsPage: OsSettingsAppsPageElement; let androidAppsBrowserProxy: TestAndroidAppsBrowserProxy; @@ -49,6 +51,13 @@ value: 2, }, }, + on_device_app_controls: { + setup_completed: { + key: 'on_device_app_controls.setup_completed', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: false, + }, + }, }; } @@ -376,33 +385,74 @@ assertTrue(isVisible(rowLink)); }); - test( - 'Clicking app parental controls row opens subpage', + if (isAppParentalControlsAvailable) { + test( + 'Clicking set up sets up parental controls and navigates to subpage', () => { - const rowLink = appsPage.shadowRoot!.querySelector<CrLinkRowElement>( - '#appParentalControlsRow'); - // Row link is visible when the parental controls feature is enabled. - if (loadTimeData.getBoolean( - 'isAppParentalControlsFeatureAvailable')) { - assertTrue(!!rowLink); - assertTrue(isVisible(rowLink)); + const parentalControlsRow = + appsPage.shadowRoot!.querySelector<HTMLElement>( + '#appParentalControls'); + assertTrue(!!parentalControlsRow); + assertTrue(isVisible(parentalControlsRow)); + + const setUpButton = + parentalControlsRow.querySelector<HTMLElement>('cr-button'); + assertTrue(!!setUpButton); + setUpButton.click(); + flush(); assertNull(appsPage.shadowRoot!.querySelector( 'settings-app-parental-controls-subpage')); - rowLink.click(); + const subpageArrow = parentalControlsRow.querySelector<HTMLElement>( + '.subpage-arrow'); + assertTrue(!!subpageArrow); + subpageArrow.click(); + flush(); + assertTrue(!!appsPage.shadowRoot!.querySelector( - 'settings-app-parental-controls-subpage')); - } else { - assertNull(rowLink); - } + 'settings-app-parental-controls-subpage')); }); + test('Toggling parental controls resets parental controls', () => { + const parentalControlsRow = + appsPage.shadowRoot!.querySelector<HTMLElement>( + '#appParentalControls'); + assertTrue(!!parentalControlsRow); + assertTrue(isVisible(parentalControlsRow)); + + const setUpButton = + parentalControlsRow.querySelector<HTMLElement>('cr-button'); + assertTrue(!!setUpButton); + setUpButton.click(); + flush(); + + const toggle = + parentalControlsRow.querySelector<HTMLElement>('cr-toggle'); + assertTrue(!!toggle); + toggle.click(); + flush(); + + assertTrue( + !!parentalControlsRow.querySelector<HTMLElement>('cr-button')); + }); + } + + if (!isAppParentalControlsAvailable) { + test('Parental controls row not visible when feature off', () => { + const parentalControlsRow = + appsPage.shadowRoot!.querySelector<HTMLElement>( + '#appParentalControls'); + assertNull(parentalControlsRow); + }); + } + test('Clicking enable button enables ARC', () => { - const button = - appsPage.shadowRoot!.querySelector<HTMLButtonElement>('#enable'); + const androidApps = appsPage.shadowRoot!.querySelector('#androidApps'); + assertTrue(!!androidApps); + const button = androidApps.querySelector<HTMLButtonElement>('#arcEnable'); assertTrue(!!button); assertTrue(isVisible(button)); - assertNull(appsPage.shadowRoot!.querySelector('.subpage-arrow')); + assertNull(androidApps.querySelector('.subpage-arrow')); button.click(); flush(); @@ -413,8 +463,7 @@ settingsAppAvailable: false, }; flush(); - assertTrue( - isVisible(appsPage.shadowRoot!.querySelector('.subpage-arrow'))); + assertTrue(isVisible(androidApps.querySelector('.subpage-arrow'))); }); // On startup row does not exist in the apps page under the revamp. @@ -490,7 +539,7 @@ Router.getInstance().navigateTo(routes.APPS, params); const deepLinkElement = - appsPage.shadowRoot!.querySelector<HTMLButtonElement>('#enable'); + appsPage.shadowRoot!.querySelector<HTMLButtonElement>('#arcEnable'); assertTrue(!!deepLinkElement); assertTrue(isVisible(deepLinkElement)); await waitAfterNextRender(deepLinkElement);
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.cc b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.cc index f12b9a8..143f2a0 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.cc +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.cc
@@ -1780,6 +1780,11 @@ RunSettingsTest("os_settings_ui/os_settings_ui_page_availability_test.js"); } +IN_PROC_BROWSER_TEST_P(OSSettingsRevampMochaTest, + OsSettingsUiPrefSync) { + RunSettingsTest("os_settings_ui/os_settings_ui_pref_sync_test.js"); +} + IN_PROC_BROWSER_TEST_F(OSSettingsMochaTestRevampEnabled, OsSettingsUiPageVisibilityRevamp) { RunSettingsTest( @@ -1886,6 +1891,58 @@ "parental_controls_page/parental_controls_settings_card_test.js"); } +class OSSettingsRevampMochaTestFasterSplitScreenEnabled + : public OSSettingsRevampMochaTest { + public: + OSSettingsRevampMochaTestFasterSplitScreenEnabled() { + scoped_feature_list_.InitWithFeatures( + /*enabled=*/{ash::features::kFasterSplitScreenSetup}, + /*disabled=*/{}); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +INSTANTIATE_TEST_SUITE_P( + RevampParameterized, + OSSettingsRevampMochaTestFasterSplitScreenEnabled, + testing::Bool(), + OSSettingsRevampMochaTestFasterSplitScreenEnabled::DescribeParams); + +class OSSettingsRevampMochaTestFasterSplitScreenDisabled + : public OSSettingsRevampMochaTest { + public: + OSSettingsRevampMochaTestFasterSplitScreenDisabled() { + scoped_feature_list_.InitWithFeatures( + /*enabled=*/{}, + /*disabled=*/{ash::features::kFasterSplitScreenSetup}); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +INSTANTIATE_TEST_SUITE_P( + RevampParameterized, + OSSettingsRevampMochaTestFasterSplitScreenDisabled, + testing::Bool(), + OSSettingsRevampMochaTestFasterSplitScreenDisabled::DescribeParams); + +IN_PROC_BROWSER_TEST_P(OSSettingsRevampMochaTestFasterSplitScreenEnabled, + PersonalizationPageWithPersonalizationHub) { + RunSettingsTest( + "personalization_page/" + "personalization_page_with_personalization_hub_test.js"); +} + +IN_PROC_BROWSER_TEST_P(OSSettingsRevampMochaTestFasterSplitScreenDisabled, + PersonalizationPageWithPersonalizationHub) { + RunSettingsTest( + "personalization_page/" + "personalization_page_with_personalization_hub_test.js"); +} + IN_PROC_BROWSER_TEST_F(OSSettingsMochaTest, PersonalizationPageWithPersonalizationHub) { RunSettingsTest(
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_ui/os_settings_ui_pref_sync_test.ts b/chrome/test/data/webui/settings/chromeos/os_settings_ui/os_settings_ui_pref_sync_test.ts new file mode 100644 index 0000000..e9677d0 --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/os_settings_ui/os_settings_ui_pref_sync_test.ts
@@ -0,0 +1,54 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview + * Suite of tests for the overall OS Settings UI asserting pref sync behavior + * via "user-action-setting-pref-change" event. Separated into a dedicated test + * suite to avoid timeouts since the <os-settings-ui> element is very large. + */ + +import 'chrome://os-settings/os_settings.js'; + +import {CrSettingsPrefs, OsSettingsUiElement, SettingsPrefsElement} from 'chrome://os-settings/os_settings.js'; +import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; + +suite('<os-settings-ui> pref sync', () => { + let uiElement: OsSettingsUiElement; + let settingsPrefs: SettingsPrefsElement; + + suiteSetup(async () => { + uiElement = document.createElement('os-settings-ui'); + document.body.appendChild(uiElement); + await flushTasks(); + await CrSettingsPrefs.initialized; + + const queriedElement = + uiElement.shadowRoot!.querySelector('settings-prefs'); + assertTrue(!!queriedElement); + settingsPrefs = queriedElement; + }); + + test('Pref is updated via "user-action-setting-pref-change" event', () => { + const prefKey = 'ash.app_notification_badging_enabled'; + + // Pref value is default true. + const defaultValue = true; + let prefObject = settingsPrefs.get(`prefs.${prefKey}`); + assertTrue(!!prefObject); + assertEquals(defaultValue, prefObject.value); + + uiElement.dispatchEvent(new CustomEvent('user-action-setting-pref-change', { + bubbles: true, + composed: true, + detail: {prefKey, value: !defaultValue}, + })); + + // Pref value is updated to false. + prefObject = settingsPrefs.get(`prefs.${prefKey}`); + assertTrue(!!prefObject); + assertEquals(!defaultValue, prefObject.value); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/personalization_page/personalization_page_with_personalization_hub_test.ts b/chrome/test/data/webui/settings/chromeos/personalization_page/personalization_page_with_personalization_hub_test.ts index 41700a3..3cd49b1d 100644 --- a/chrome/test/data/webui/settings/chromeos/personalization_page/personalization_page_with_personalization_hub_test.ts +++ b/chrome/test/data/webui/settings/chromeos/personalization_page/personalization_page_with_personalization_hub_test.ts
@@ -12,10 +12,11 @@ import {TestPersonalizationHubBrowserProxy} from './test_personalization_hub_browser_proxy.js'; -let personalizationPage: SettingsPersonalizationPageElement; -let personalizationHubBrowserProxy: TestPersonalizationHubBrowserProxy; - suite('<settings-personalization-page>', () => { + let personalizationPage: SettingsPersonalizationPageElement; + let personalizationHubBrowserProxy: TestPersonalizationHubBrowserProxy; + const shouldShowMultitaskingInPersonalization = loadTimeData.getBoolean('shouldShowMultitaskingInPersonalization'); + async function createPersonalizationPage(): Promise<void> { personalizationPage = document.createElement('settings-personalization-page'); @@ -70,45 +71,41 @@ await personalizationHubBrowserProxy.whenCalled('openPersonalizationHub'); }); - test( - 'Multitasking settings subsection is visible with feature enabled', - async () => { - loadTimeData.overrideValues( - {shouldShowMultitaskingInPersonalization: true}); - await createPersonalizationPage(); - const multitaskingSettingsSubsection = - personalizationPage.shadowRoot!.querySelector<HTMLButtonElement>( - '#snapWindowSuggestionsSubsection'); - assertTrue( - isVisible(multitaskingSettingsSubsection), - 'Multitasking settings subsection should be visible.'); - }); + if (shouldShowMultitaskingInPersonalization) { + test( + 'Multitasking settings subsection is visible with feature enabled', + async () => { + await createPersonalizationPage(); + const multitaskingSettingsSubsection = + personalizationPage.shadowRoot!.querySelector<HTMLButtonElement>( + '#snapWindowSuggestionsSubsection'); + assertTrue( + isVisible(multitaskingSettingsSubsection), + 'Multitasking settings subsection should be visible.'); + }); - test( + test('Multitasking settings subsection is deep-linkable', async () => { + await createPersonalizationPage(); + await deepLinkToSetting(settingMojom.Setting.kSnapWindowSuggestions); + + const multitaskingSettingsSubsection = + personalizationPage.shadowRoot!.querySelector<HTMLButtonElement>( + '#snapWindowSuggestionsSubsection'); + assertTrue(!!multitaskingSettingsSubsection); + await assertElementIsDeepLinked(multitaskingSettingsSubsection); + }); + } else { + test( 'Multitasking settings subsection is not visible with feature disabled', async () => { - loadTimeData.overrideValues( - {shouldShowMultitaskingInPersonalization: false}); await createPersonalizationPage(); const multitaskingSettingsSubsection = - personalizationPage.shadowRoot!.querySelector<HTMLButtonElement>( - '#snapWindowSuggestionsSubsection'); - assertFalse( - isVisible(multitaskingSettingsSubsection), - 'Multitasking settings subsection should not be visible.'); - }); - - test('Multitasking settings subsection is deep-linkable', async () => { - loadTimeData.overrideValues( - {shouldShowMultitaskingInPersonalization: true}); - await createPersonalizationPage(); - await deepLinkToSetting(settingMojom.Setting.kSnapWindowSuggestions); - - const multitaskingSettingsSubsection = - personalizationPage.shadowRoot!.querySelector<HTMLButtonElement>( + personalizationPage.shadowRoot!.querySelector<HTMLButtonElement>( '#snapWindowSuggestionsSubsection'); - assertTrue(!!multitaskingSettingsSubsection); - await assertElementIsDeepLinked(multitaskingSettingsSubsection); - }); + assertFalse( + isVisible(multitaskingSettingsSubsection), + 'Multitasking settings subsection should not be visible.'); + }); + } });
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/categories_test.ts b/chrome/test/data/webui/side_panel/customize_chrome/categories_test.ts index c7488fd..9b9ac52 100644 --- a/chrome/test/data/webui/side_panel/customize_chrome/categories_test.ts +++ b/chrome/test/data/webui/side_panel/customize_chrome/categories_test.ts
@@ -239,7 +239,7 @@ categoriesElement, '#classicChromeTile #cornerNewTabPageTile #cornerNewTabPage')!.src, 'chrome://customize-chrome-side-panel.top-chrome/icons/' + - 'gm3_corner_new_tab_page.svg'); + 'corner_new_tab_page.svg'); }); [true, false].forEach((flagEnabled) => {
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/theme_snapshot_test.ts b/chrome/test/data/webui/side_panel/customize_chrome/theme_snapshot_test.ts index 5a884ac..0b6dd5e 100644 --- a/chrome/test/data/webui/side_panel/customize_chrome/theme_snapshot_test.ts +++ b/chrome/test/data/webui/side_panel/customize_chrome/theme_snapshot_test.ts
@@ -158,7 +158,7 @@ $$<SVGUseElement>( themeSnapshotElement, '#classicChromeBackground svg use')!.href.baseVal, - 'icons/gm3_mini_new_tab_page.svg#miniNewTabPage'); + 'icons/mini_new_tab_page.svg#miniNewTabPage'); }); test(
diff --git a/chrome/test/data/webui/side_panel/read_anything/voice_selection_menu_test.ts b/chrome/test/data/webui/side_panel/read_anything/voice_selection_menu_test.ts index b85df2a..6a63196 100644 --- a/chrome/test/data/webui/side_panel/read_anything/voice_selection_menu_test.ts +++ b/chrome/test/data/webui/side_panel/read_anything/voice_selection_menu_test.ts
@@ -4,9 +4,10 @@ import 'chrome-untrusted://read-anything-side-panel.top-chrome/voice_selection_menu.js'; +import type {CrIconButtonElement} from '//resources/cr_elements/cr_icon_button/cr_icon_button.js'; import {flush} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import type {VoiceSelectionMenuElement} from 'chrome-untrusted://read-anything-side-panel.top-chrome/voice_selection_menu.js'; -import {assertEquals, assertFalse, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js'; +import {assertEquals, assertFalse, assertStringContains, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js'; function stringToHtmlTestId(s: string): string { return s.replace(/\s/g, '-').replace(/[()]/g, ''); @@ -271,17 +272,24 @@ test('it shows preview-playing button when preview plays', () => { const playIconVoice0 = getDropdownItemForVoice(availableVoices[0]!) - .querySelector<HTMLButtonElement>('#play-icon')!; + .querySelector<CrIconButtonElement>('#preview-icon')!; const playIconOfPreviewVoice = getDropdownItemForVoice(previewVoice) - .querySelector<HTMLButtonElement>('#play-icon')!; + .querySelector<CrIconButtonElement>('#preview-icon')!; - // The play icon should flip to disabled for the voice being previewed + // The play icon should flip to pause for the voice being previewed assertTrue(isPositionedOnPage(playIconOfPreviewVoice)); - assertTrue(isDisabled(playIconOfPreviewVoice)); - // The play icon should remain enabled for the other buttons + assertEquals( + playIconOfPreviewVoice.ironIcon, 'read-anything-20:pause-circle'); + assertStringContains( + playIconOfPreviewVoice.title.toLowerCase(), 'pause'); + assertStringContains( + playIconOfPreviewVoice.ariaLabel!.toLowerCase(), 'pause'); + // The play icon should remain unchanged for the other buttons assertTrue(isPositionedOnPage(playIconVoice0)); - assertFalse(isDisabled(playIconVoice0)); + assertEquals(playIconVoice0.ironIcon, 'read-anything-20:play-circle'); + assertStringContains(playIconVoice0.title.toLowerCase(), 'play'); + assertStringContains(playIconVoice0.ariaLabel!.toLowerCase(), 'play'); }); suite('when preview finishes playing', () => { @@ -293,20 +301,27 @@ flush(); }); - test('it flips the preview button back to enabled', () => { + test('it flips the preview button back to play icon', () => { const playIconVoice0 = getDropdownItemForVoice(availableVoices[0]!) - .querySelector<HTMLButtonElement>('#play-icon')!; + .querySelector<CrIconButtonElement>('#preview-icon')!; const playIconOfPreviewVoice = getDropdownItemForVoice(availableVoices[1]!) - .querySelector<HTMLButtonElement>('#play-icon')!; + .querySelector<CrIconButtonElement>('#preview-icon')!; - // All icons should be enabled play icons because no preview is + // All icons should be play icons because no preview is // playing assertTrue(isPositionedOnPage(playIconOfPreviewVoice)); assertTrue(isPositionedOnPage(playIconVoice0)); - assertFalse(isDisabled(playIconVoice0)); - assertFalse(isDisabled(playIconOfPreviewVoice)); + assertEquals( + playIconOfPreviewVoice.ironIcon, 'read-anything-20:play-circle'); + assertEquals(playIconVoice0.ironIcon, 'read-anything-20:play-circle'); + assertStringContains( + playIconOfPreviewVoice.title.toLowerCase(), 'play'); + assertStringContains(playIconVoice0.title.toLowerCase(), 'play'); + assertStringContains( + playIconOfPreviewVoice.ariaLabel!.toLowerCase(), 'play'); + assertStringContains(playIconVoice0.ariaLabel!.toLowerCase(), 'play'); }); }); }); @@ -322,7 +337,3 @@ !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length); } - -function isDisabled(element: HTMLButtonElement) { - return element.disabled; -}
diff --git a/chrome/updater/util/util_win_unittest.cc b/chrome/updater/util/util_win_unittest.cc index 940e89f..0e885cd 100644 --- a/chrome/updater/util/util_win_unittest.cc +++ b/chrome/updater/util/util_win_unittest.cc
@@ -56,4 +56,19 @@ EXPECT_TRUE(cmd_line->GetSwitchValueASCII("s3").empty()); } +TEST(UtilTest, CommandLineForLegacyFormat_SwitchWithEqualSign) { + std::optional<base::CommandLine> cmd_line = CommandLineForLegacyFormat( + L"updater.exe /enable-logging " + L"/vmodule=*/components/update_client/*=2,*/chrome/updater/*=2 " + L"/handoff \"appguid={CDABE316-39CD-43BA-8440-6D1E0547AEE6}&lang=en\""); + + EXPECT_TRUE(cmd_line); + EXPECT_TRUE(cmd_line->HasSwitch("enable-logging")); + EXPECT_TRUE(cmd_line->GetSwitchValueASCII("enable-logging").empty()); + EXPECT_EQ(cmd_line->GetSwitchValueASCII("vmodule"), + "*/components/update_client/*=2,*/chrome/updater/*=2"); + EXPECT_EQ(cmd_line->GetSwitchValueASCII("handoff"), + "appguid={CDABE316-39CD-43BA-8440-6D1E0547AEE6}&lang=en"); +} + } // namespace updater
diff --git a/chrome/updater/util/win_util.cc b/chrome/updater/util/win_util.cc index a4dee5d..3e036c5 100644 --- a/chrome/updater/util/win_util.cc +++ b/chrome/updater/util/win_util.cc
@@ -44,6 +44,7 @@ #include "base/ranges/algorithm.h" #include "base/scoped_native_library.h" #include "base/strings/strcat.h" +#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" @@ -975,7 +976,13 @@ VLOG(1) << "Empty switch in command line: [" << cmd_string << "]"; return std::nullopt; } - + if (base::StringPairs switch_value_pairs; + base::SplitStringIntoKeyValuePairs(switch_name, '=', '\n', + &switch_value_pairs)) { + command_line.AppendSwitchASCII(switch_value_pairs[0].first, + switch_value_pairs[0].second); + continue; + } if (is_legacy_switch(next_arg) || next_arg.empty()) { command_line.AppendSwitch(switch_name); } else {
diff --git a/chromeos/ash/components/growth/campaigns_model.h b/chromeos/ash/components/growth/campaigns_model.h index 40013ed..27151bb 100644 --- a/chromeos/ash/components/growth/campaigns_model.h +++ b/chromeos/ash/components/growth/campaigns_model.h
@@ -29,7 +29,7 @@ // Entries should not be renumbered and numeric values should never be reused // as it is used for logging metrics as well. Please keep in sync with -// "CampaignSlot" in src/tools/metrics/histograms/enums.xml. +// "CampaignSlot" in tools/metrics/histograms/metadata/ash_growth/enums.xml. enum class Slot { kDemoModeApp = 0, kDemoModeFreePlayApps = 1,
diff --git a/chromeos/ash/components/system/fake_statistics_provider.cc b/chromeos/ash/components/system/fake_statistics_provider.cc index a63eaad..a75ec8ec 100644 --- a/chromeos/ash/components/system/fake_statistics_provider.cc +++ b/chromeos/ash/components/system/fake_statistics_provider.cc
@@ -70,6 +70,10 @@ machine_statistics_.erase(key); } +void FakeStatisticsProvider::ClearAllMachineStatistics() { + machine_statistics_.clear(); +} + void FakeStatisticsProvider::SetMachineFlag(const std::string& key, bool value) { machine_flags_[key] = value;
diff --git a/chromeos/ash/components/system/fake_statistics_provider.h b/chromeos/ash/components/system/fake_statistics_provider.h index a767be7b..fb5e92e 100644 --- a/chromeos/ash/components/system/fake_statistics_provider.h +++ b/chromeos/ash/components/system/fake_statistics_provider.h
@@ -39,6 +39,7 @@ void SetMachineStatistic(const std::string& key, const std::string& value); void ClearMachineStatistic(std::string_view key); + void ClearAllMachineStatistics(); void SetMachineFlag(const std::string& key, bool value); void ClearMachineFlag(std::string_view key); void SetVpdStatus(VpdStatus new_status);
diff --git a/chromeos/ash/services/libassistant/chromium_http_connection.cc b/chromeos/ash/services/libassistant/chromium_http_connection.cc index ce16ea3..45ce9c97 100644 --- a/chromeos/ash/services/libassistant/chromium_http_connection.cc +++ b/chromeos/ash/services/libassistant/chromium_http_connection.cc
@@ -326,7 +326,7 @@ if (!upload_pipe_.is_valid() || upload_body_.empty()) return; - uint32_t write_bytes = upload_body_.size(); + size_t write_bytes = upload_body_.size(); MojoResult result = upload_pipe_->WriteData(upload_body_.data(), &write_bytes, MOJO_WRITE_DATA_FLAG_NONE);
diff --git a/chromeos/crosapi/mojom/test_controller.mojom b/chromeos/crosapi/mojom/test_controller.mojom index 59d2306..c566182 100644 --- a/chromeos/crosapi/mojom/test_controller.mojom +++ b/chromeos/crosapi/mojom/test_controller.mojom
@@ -48,6 +48,14 @@ kTrue, }; +[Stable, Extensible] +enum MachineStatisticKeyType { + [Default] kUnknown = 0, + kOemDeviceRequisitionKey = 1, + kHardwareClassKey = 2, + kCustomizationIdKey = 3, +}; + // Dev mode IWAs are either installed from a proxy origin, or from a Web Bundle // file. [Stable] @@ -336,8 +344,8 @@ // This interface is implemented by Ash-Chrome. // This interface provides tests a mechanism to mutate or query ash. // In the future, this interface may merge with an automation or a11y interface. -// Next version: 35 -// Next method id: 50 +// Next version: 36 +// Next method id: 53 [Stable, Uuid="1f93f9d7-e466-466c-a675-c21b48cf30d3"] interface TestController { // Clicks the middle of the views element identified by |element_name|. @@ -602,4 +610,15 @@ // Sets the number of displays through the `DisplayManagerTestApi`. // The values can be in the range [1, 8]. [MinVersion=34] UpdateDisplay@49(int32 number_of_displays) => (); + + // Enables or disables FakeStatisticsProvider for testing. + [MinVersion=35] EnableStatisticsProviderForTesting@50(bool enable) => (); + + // Clears all machine statistics data from FakeStatisficsProvider for testing. + [MinVersion=35] ClearAllMachineStatistics@51() => (); + + // Sets the machine statistics data with FakeStatisficsProvider for testing. + // Returns true if succeeded. + [MinVersion=35] SetMachineStatistic@52(MachineStatisticKeyType key, + string value) => (bool success); };
diff --git a/clank b/clank index ef9ed76..4ccf9ec 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit ef9ed7638a0a413170457f22032944d1b61febbb +Subproject commit 4ccf9ec2cc92967d39ca0e3d0b0158bfd7937c81
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc index d35380b..ef59a75 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator.cc
@@ -1999,7 +1999,8 @@ // interactions. metadata_logging_context.instrument_ids_with_benefits_available.insert( credit_card.instrument_id()); - if (credit_card.IsCardEligibleForBenefits()) { + if (personal_data().payments_data_manager().IsCardEligibleForBenefits( + credit_card)) { labels.push_back({*benefit_label}); } suggestion.feature_for_iph = @@ -2159,7 +2160,9 @@ suggestion.labels = {}; std::optional<Suggestion::Text> benefit_label = GetCreditCardBenefitSuggestionLabel(credit_card); - if (benefit_label && credit_card.IsCardEligibleForBenefits()) { + if (benefit_label && + personal_data().payments_data_manager().IsCardEligibleForBenefits( + credit_card)) { suggestion.labels.push_back({*benefit_label}); } }
diff --git a/components/autofill/core/browser/data_model/credit_card.cc b/components/autofill/core/browser/data_model/credit_card.cc index 3ff6d31..a585dcd 100644 --- a/components/autofill/core/browser/data_model/credit_card.cc +++ b/components/autofill/core/browser/data_model/credit_card.cc
@@ -1253,15 +1253,6 @@ card_art_url().spec() != kCapitalOneCardArtUrl; } -bool CreditCard::IsCardEligibleForBenefits() const { - return (issuer_id() == kAmexCardIssuerId && - base::FeatureList::IsEnabled( - features::kAutofillEnableCardBenefitsForAmericanExpress)) || - (issuer_id() == kCapitalOneCardIssuerId && - base::FeatureList::IsEnabled( - features::kAutofillEnableCardBenefitsForCapitalOne)); -} - void CreditCard::GetSupportedTypes(FieldTypeSet* supported_types) const { supported_types->insert(CREDIT_CARD_NAME_FULL); supported_types->insert(CREDIT_CARD_NAME_FIRST);
diff --git a/components/autofill/core/browser/data_model/credit_card.h b/components/autofill/core/browser/data_model/credit_card.h index 97eb8293..b7860dc3 100644 --- a/components/autofill/core/browser/data_model/credit_card.h +++ b/components/autofill/core/browser/data_model/credit_card.h
@@ -467,12 +467,6 @@ // image. bool HasRichCardArtImageFromMetadata() const; - // Returns whether the card is from an issuer eligible for benefits and the - // user is in a benefits Chrome experiment for the card's issuer. - // TODO(crbug.com/330908547): Move IsCardEligibleForBenefits to the - // PaymentsDataManager. - bool IsCardEligibleForBenefits() const; - const std::u16string& product_description() const { return product_description_; }
diff --git a/components/autofill/core/browser/payments/autofill_payments_feature_availability.cc b/components/autofill/core/browser/payments/autofill_payments_feature_availability.cc index f7ab396..b066829 100644 --- a/components/autofill/core/browser/payments/autofill_payments_feature_availability.cc +++ b/components/autofill/core/browser/payments/autofill_payments_feature_availability.cc
@@ -6,7 +6,7 @@ #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/data_model/credit_card.h" -#include "components/autofill/core/browser/personal_data_manager.h" +#include "components/autofill/core/browser/payments_data_manager.h" #include "components/autofill/core/common/autofill_payments_features.h" namespace autofill { @@ -23,9 +23,9 @@ bool DidDisplayBenefitForCard( const CreditCard& card, const AutofillClient& autofill_client, - const PersonalDataManager& personal_data_manager) { - return card.IsCardEligibleForBenefits() && - !personal_data_manager.payments_data_manager() + const PaymentsDataManager& payments_data_manager) { + return payments_data_manager.IsCardEligibleForBenefits(card) && + !payments_data_manager .GetApplicableBenefitDescriptionForCardAndOrigin( card, autofill_client.GetLastCommittedPrimaryMainFrameOrigin(),
diff --git a/components/autofill/core/browser/payments/autofill_payments_feature_availability.h b/components/autofill/core/browser/payments/autofill_payments_feature_availability.h index e155301..f954dce 100644 --- a/components/autofill/core/browser/payments/autofill_payments_feature_availability.h +++ b/components/autofill/core/browser/payments/autofill_payments_feature_availability.h
@@ -9,13 +9,13 @@ class AutofillClient; class CreditCard; -class PersonalDataManager; +class PaymentsDataManager; // Returns whether the `card` is shown in an Autofill suggestion dropdown with a // benefit label. bool DidDisplayBenefitForCard(const CreditCard& card, const AutofillClient& autofill_client, - const PersonalDataManager& personal_data_manager); + const PaymentsDataManager& payments_data_manager); // Returns whether the `card` is populated with a card art image and a card // product name and whether they both should be shown.
diff --git a/components/autofill/core/browser/payments/credit_card_otp_authenticator.cc b/components/autofill/core/browser/payments/credit_card_otp_authenticator.cc index 388cb37..c92df66 100644 --- a/components/autofill/core/browser/payments/credit_card_otp_authenticator.cc +++ b/components/autofill/core/browser/payments/credit_card_otp_authenticator.cc
@@ -43,7 +43,8 @@ ClientBehaviorConstants::kShowingCardArtImageAndCardProductName); } if (DidDisplayBenefitForCard(*card_, *autofill_client_, - *autofill_client_->GetPersonalDataManager())) { + autofill_client_->GetPersonalDataManager() + ->payments_data_manager())) { unmask_request_->client_behavior_signals.push_back( ClientBehaviorConstants::kShowingCardBenefits); }
diff --git a/components/autofill/core/browser/payments/credit_card_risk_based_authenticator.cc b/components/autofill/core/browser/payments/credit_card_risk_based_authenticator.cc index d6bd751..d6aff830 100644 --- a/components/autofill/core/browser/payments/credit_card_risk_based_authenticator.cc +++ b/components/autofill/core/browser/payments/credit_card_risk_based_authenticator.cc
@@ -70,7 +70,8 @@ } if (DidDisplayBenefitForCard(unmask_request_details_->card, autofill_client_.get(), - *autofill_client_->GetPersonalDataManager())) { + autofill_client_->GetPersonalDataManager() + ->payments_data_manager())) { unmask_request_details_->client_behavior_signals.push_back( ClientBehaviorConstants::kShowingCardBenefits); }
diff --git a/components/autofill/core/browser/payments/full_card_request.cc b/components/autofill/core/browser/payments/full_card_request.cc index 88ad344..457a551e 100644 --- a/components/autofill/core/browser/payments/full_card_request.cc +++ b/components/autofill/core/browser/payments/full_card_request.cc
@@ -177,8 +177,9 @@ // TODO(crbug.com/332715322): Refactor FullCardRequest to use // AutofillClient::GetPersonalDataManager() instead of a separate class // variable. - if (DidDisplayBenefitForCard(card, autofill_client_.get(), - *personal_data_manager_)) { + if (DidDisplayBenefitForCard( + card, autofill_client_.get(), + personal_data_manager_->payments_data_manager())) { request_->client_behavior_signals.push_back( ClientBehaviorConstants::kShowingCardBenefits); }
diff --git a/components/autofill/core/browser/payments_data_manager.cc b/components/autofill/core/browser/payments_data_manager.cc index 1d61a58b..b1431b6 100644 --- a/components/autofill/core/browser/payments_data_manager.cc +++ b/components/autofill/core/browser/payments_data_manager.cc
@@ -23,6 +23,7 @@ #include "components/autofill/core/browser/metrics/payments/mandatory_reauth_metrics.h" #include "components/autofill/core/browser/metrics/payments/offers_metrics.h" #include "components/autofill/core/browser/metrics/payments/wallet_usage_data_metrics.h" +#include "components/autofill/core/browser/payments/constants.h" #include "components/autofill/core/browser/payments/payments_data_cleaner.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/ui/autofill_image_fetcher_base.h" @@ -862,6 +863,16 @@ base::Unretained(this))); } +bool PaymentsDataManager::IsCardEligibleForBenefits( + const CreditCard& card) const { + return (card.issuer_id() == kAmexCardIssuerId && + base::FeatureList::IsEnabled( + features::kAutofillEnableCardBenefitsForAmericanExpress)) || + (card.issuer_id() == kCapitalOneCardIssuerId && + base::FeatureList::IsEnabled( + features::kAutofillEnableCardBenefitsForCapitalOne)); +} + bool PaymentsDataManager::IsCardBenefitsFeatureEnabled() { return base::FeatureList::IsEnabled( features::kAutofillEnableCardBenefitsForAmericanExpress) ||
diff --git a/components/autofill/core/browser/payments_data_manager.h b/components/autofill/core/browser/payments_data_manager.h index c63d595..4238c22 100644 --- a/components/autofill/core/browser/payments_data_manager.h +++ b/components/autofill/core/browser/payments_data_manager.h
@@ -294,6 +294,10 @@ // present in the cache, this function will return a nullptr. gfx::Image* GetCachedCardArtImageForUrl(const GURL& card_art_url) const; + // Checks if a specific card is eligible to see benefits based on its issuer + // id. + bool IsCardEligibleForBenefits(const CreditCard& card) const; + // Checks if the user is in an experiment for seeing credit card benefits in // Autofill suggestions. bool IsCardBenefitsFeatureEnabled();
diff --git a/components/autofill/core/common/autofill_prefs.cc b/components/autofill/core/common/autofill_prefs.cc index 054cd27a..0add69aa 100644 --- a/components/autofill/core/common/autofill_prefs.cc +++ b/components/autofill/core/common/autofill_prefs.cc
@@ -106,6 +106,12 @@ registry->RegisterBooleanPref(prefs::kAutofillUsingVirtualViewStructure, false); #endif + +#if BUILDFLAG(IS_ANDROID) + registry->RegisterBooleanPref( + prefs::kFacilitatedPaymentsPix, /*default_value=*/true, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); +#endif } void MigrateDeprecatedAutofillPrefs(PrefService* pref_service) {
diff --git a/components/autofill/core/common/autofill_prefs.h b/components/autofill/core/common/autofill_prefs.h index c5e8ee3..10a44f2 100644 --- a/components/autofill/core/common/autofill_prefs.h +++ b/components/autofill/core/common/autofill_prefs.h
@@ -115,6 +115,10 @@ "autofill.using_virtual_view_structure"; #endif // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_ANDROID) +inline constexpr char kFacilitatedPaymentsPix[] = "facilitated_payments.pix"; +#endif // BUILDFLAG(IS_ANDROID) + // The maximum value for the // `kAutofillPaymentMethodsMandatoryReauthPromoShownCounter` pref. If this // value is reached, we should not show a mandatory re-auth promo. @@ -194,6 +198,10 @@ bool UsesVirtualViewStructureForAutofill(const PrefService* prefs); +void SetFacilitatedPaymentsPix(PrefService* prefs, bool value); + +bool IsFacilitatedPaymentsPixEnabled(const PrefService* prefs); + } // namespace autofill::prefs #endif // COMPONENTS_AUTOFILL_CORE_COMMON_AUTOFILL_PREFS_H_
diff --git a/components/autofill/core/common/autofill_prefs_unittest.cc b/components/autofill/core/common/autofill_prefs_unittest.cc index ef9c8cf..000e177 100644 --- a/components/autofill/core/common/autofill_prefs_unittest.cc +++ b/components/autofill/core/common/autofill_prefs_unittest.cc
@@ -156,5 +156,11 @@ EXPECT_EQ(dictionary, *base::JSONReader::Read(output_js)); } +#if BUILDFLAG(IS_ANDROID) +TEST_F(AutofillPrefsTest, FacilitatedPaymentsPixPref_DefaultValueSetToTrue) { + EXPECT_TRUE(pref_service()->GetBoolean(prefs::kFacilitatedPaymentsPix)); +} +#endif // BUILDFLAG(IS_ANDROID) + } // namespace prefs } // namespace autofill
diff --git a/components/cast_streaming/browser/cast_message_port_impl_unittest.cc b/components/cast_streaming/browser/cast_message_port_impl_unittest.cc index cefd968..9689526 100644 --- a/components/cast_streaming/browser/cast_message_port_impl_unittest.cc +++ b/components/cast_streaming/browser/cast_message_port_impl_unittest.cc
@@ -86,7 +86,7 @@ std::move(receiver_message_closure_).Run(); } } - void OnError(openscreen::Error error) override { + void OnError(const openscreen::Error& error) override { latest_error_ = error; if (error_closure_) { std::move(error_closure_).Run();
diff --git a/components/cast_streaming/browser/cast_streaming_session.cc b/components/cast_streaming/browser/cast_streaming_session.cc index 0c1c4c8..369b263 100644 --- a/components/cast_streaming/browser/cast_streaming_session.cc +++ b/components/cast_streaming/browser/cast_streaming_session.cc
@@ -431,7 +431,7 @@ void CastStreamingSession::ReceiverSessionClient::OnError( const openscreen::cast::ReceiverSession* session, - openscreen::Error error) { + const openscreen::Error& error) { DCHECK_EQ(session, receiver_session_.get()); LOG(ERROR) << error; if (!is_initialized_) {
diff --git a/components/cast_streaming/browser/cast_streaming_session.h b/components/cast_streaming/browser/cast_streaming_session.h index 3099b9f..3d99a70 100644 --- a/components/cast_streaming/browser/cast_streaming_session.h +++ b/components/cast_streaming/browser/cast_streaming_session.h
@@ -188,7 +188,7 @@ void OnReceiversDestroying(const openscreen::cast::ReceiverSession* session, ReceiversDestroyingReason reason) override; void OnError(const openscreen::cast::ReceiverSession* session, - openscreen::Error error) override; + const openscreen::Error& error) override; void OnDataTimeout(); void OnCastChannelClosed();
diff --git a/components/cast_streaming/test/cast_streaming_test_sender.cc b/components/cast_streaming/test/cast_streaming_test_sender.cc index 5c9756d..fd3d4cf 100644 --- a/components/cast_streaming/test/cast_streaming_test_sender.cc +++ b/components/cast_streaming/test/cast_streaming_test_sender.cc
@@ -264,7 +264,7 @@ void CastStreamingTestSender::OnError( const openscreen::cast::SenderSession* session, - openscreen::Error error) { + const openscreen::Error& error) { LOG(ERROR) << "Sender Session error: " << error.ToString(); CHECK_EQ(session, sender_session_.get()); Stop();
diff --git a/components/cast_streaming/test/cast_streaming_test_sender.h b/components/cast_streaming/test/cast_streaming_test_sender.h index 6ac2eed..baa5c17 100644 --- a/components/cast_streaming/test/cast_streaming_test_sender.h +++ b/components/cast_streaming/test/cast_streaming_test_sender.h
@@ -99,7 +99,7 @@ openscreen::cast::capture_recommendations::Recommendations capture_recommendations) final; void OnError(const openscreen::cast::SenderSession* session, - openscreen::Error error) final; + const openscreen::Error& error) final; openscreen_platform::TaskRunner task_runner_; openscreen::cast::Environment environment_;
diff --git a/components/commerce_strings.grdp b/components/commerce_strings.grdp index 918de57..2b5083b 100644 --- a/components/commerce_strings.grdp +++ b/components/commerce_strings.grdp
@@ -297,6 +297,11 @@ </message> </if> <!-- not use_titlecase --> + <!-- For Desktop Product Specifications --> + <message name="IDS_PRODUCT_SPECIFICATIONS_OPEN_TABS_SECTION" translateable="false" desc="The title of the section in the product selection drop-down in the product specifications UI that shows a list of open tabs."> + Open Tabs + </message> + <message name="IDS_SHOPPING_INSIGHTS_BUYING_OPTIONS" desc="Text shown in Shopping Insights side panel. Clicking this link will bring users to a new tab where users can check price insights of all available buying options."> Buying options </message>
diff --git a/components/embedder_support/ios/BUILD.gn b/components/embedder_support/ios/BUILD.gn new file mode 100644 index 0000000..d028990a --- /dev/null +++ b/components/embedder_support/ios/BUILD.gn
@@ -0,0 +1,28 @@ +# Copyright 2024 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +static_library("web_contents_delegate") { + sources = [ + "delegate/color_chooser/color_chooser_consumer_ios.h", + "delegate/color_chooser/color_chooser_controller_ios.h", + "delegate/color_chooser/color_chooser_controller_ios.mm", + "delegate/color_chooser/color_chooser_coordinator_ios.h", + "delegate/color_chooser/color_chooser_coordinator_ios.mm", + "delegate/color_chooser/color_chooser_delegate_ios.h", + "delegate/color_chooser/color_chooser_ios.h", + "delegate/color_chooser/color_chooser_ios.mm", + "delegate/color_chooser/color_chooser_mediator_ios.h", + "delegate/color_chooser/color_chooser_mediator_ios.mm", + ] + + deps = [ + "//base", + "//content/public/browser", + "//content/public/common", + "//skia", + "//ui/base", + "//ui/gfx", + "//url", + ] +}
diff --git a/components/embedder_support/ios/DEPS b/components/embedder_support/ios/DEPS new file mode 100644 index 0000000..df385638 --- /dev/null +++ b/components/embedder_support/ios/DEPS
@@ -0,0 +1,6 @@ +include_rules = [ + "+skia/ext/skia_utils_ios.h", + "+third_party/blink/public/mojom/choosers/color_chooser.mojom.h", + "+third_party/skia/include/core/SkColor.h", + "+ui/gfx/native_widget_types.h", +]
diff --git a/components/embedder_support/ios/delegate/color_chooser/color_chooser_consumer_ios.h b/components/embedder_support/ios/delegate/color_chooser/color_chooser_consumer_ios.h new file mode 100644 index 0000000..01967b14 --- /dev/null +++ b/components/embedder_support/ios/delegate/color_chooser/color_chooser_consumer_ios.h
@@ -0,0 +1,23 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_CONSUMER_IOS_H_ +#define COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_CONSUMER_IOS_H_ + +#import <Foundation/Foundation.h> + +@class UIColor; + +// Consumer for model to request actions to the color chooser UI. +@protocol ColorChooserConsumerIOS <NSObject> + +// Closes the color chooser. +- (void)closeColorChooser; + +// Sets the selected color in the color chooser with `color`. +- (void)setColor:(UIColor*)color; + +@end + +#endif // COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_CONSUMER_IOS_H_
diff --git a/components/embedder_support/ios/delegate/color_chooser/color_chooser_controller_ios.h b/components/embedder_support/ios/delegate/color_chooser/color_chooser_controller_ios.h new file mode 100644 index 0000000..bab59aa --- /dev/null +++ b/components/embedder_support/ios/delegate/color_chooser/color_chooser_controller_ios.h
@@ -0,0 +1,33 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_CONTROLLER_IOS_H_ +#define COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_CONTROLLER_IOS_H_ + +#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> + +#import "components/embedder_support/ios/delegate/color_chooser/color_chooser_consumer_ios.h" + +@protocol ColorChooserDelegateIOS; + +// The color chooser controller that is opened as a popover. +@interface ColorChooserControllerIOS + : UIColorPickerViewController <ColorChooserConsumerIOS, + UIColorPickerViewControllerDelegate, + UIPopoverPresentationControllerDelegate> + +// The view controller this coordinator was initialized with. +@property(weak, nonatomic, readonly) UIViewController* baseViewController; + +// Delegate used to handle the actions in the color chooser. +@property(nonatomic, weak) id<ColorChooserDelegateIOS> chooserDelegate; + +// Initializer. +- (instancetype)initWithChooserDelegate:(id<ColorChooserDelegateIOS>)delegate + color:(UIColor*)color; + +@end + +#endif // COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_CONTROLLER_IOS_H_
diff --git a/components/embedder_support/ios/delegate/color_chooser/color_chooser_controller_ios.mm b/components/embedder_support/ios/delegate/color_chooser/color_chooser_controller_ios.mm new file mode 100644 index 0000000..f2f2eb1 --- /dev/null +++ b/components/embedder_support/ios/delegate/color_chooser/color_chooser_controller_ios.mm
@@ -0,0 +1,42 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "components/embedder_support/ios/delegate/color_chooser/color_chooser_controller_ios.h" + +#import "components/embedder_support/ios/delegate/color_chooser/color_chooser_delegate_ios.h" + +@implementation ColorChooserControllerIOS +- (instancetype)initWithChooserDelegate: + (id<ColorChooserDelegateIOS>)chooserDelegate + color:(UIColor*)color { + if (!(self = [super init])) { + return nil; + } + + _chooserDelegate = chooserDelegate; + [self setDelegate:self]; + [self setColor:color]; + [self setSupportsAlpha:FALSE]; + return self; +} + +- (void)viewWillDisappear:(BOOL)animated { + // Update the selected color here when UIColorPickerViewController is closed + // by tapping the close button or swiping down the popover. + // `UIColorPickerViewControllerDelegate::colorPickerViewControllerDidFinish` + // is called only when a user taps the close button. + [self.chooserDelegate onColorChosen:self selectedColor:self.selectedColor]; +} + +#pragma mark - ColorChooserConsumerIOS + +- (void)closeColorChooser { + [self dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)setColor:(UIColor*)color { + [self setSelectedColor:color]; +} + +@end
diff --git a/components/embedder_support/ios/delegate/color_chooser/color_chooser_coordinator_ios.h b/components/embedder_support/ios/delegate/color_chooser/color_chooser_coordinator_ios.h new file mode 100644 index 0000000..89a9550 --- /dev/null +++ b/components/embedder_support/ios/delegate/color_chooser/color_chooser_coordinator_ios.h
@@ -0,0 +1,44 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_COORDINATOR_IOS_H_ +#define COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_COORDINATOR_IOS_H_ + +#import <Foundation/Foundation.h> + +namespace web_contents_delegate_ios { +class ColorChooserIOS; +} + +@class ColorChooserControllerIOS; +@class ColorChooserMediatorIOS; +@class UIViewController; +@class UIColor; + +// Holds a controller and a mediator so that communicates the controller and +// content implementations. +@interface ColorChooserCoordinatorIOS : NSObject + +// The controller that has UI components. +@property(nonatomic, strong) ColorChooserControllerIOS* colorChooserController; + +// The mediator that implements ColorChooserDelegateIOS. +@property(nonatomic, strong) ColorChooserMediatorIOS* colorChooserMediator; + +// Initializer. +- (instancetype)initWithBaseViewController:(UIViewController*)baseViewController + colorChooser: + (web_contents_delegate_ios::ColorChooserIOS*) + colorChooser + color:(UIColor*)color; + +// Closes the color chooser. +- (void)closeColorChooser; + +// Sets the selected color in the color chooser. +- (void)setColor:(UIColor*)color; + +@end + +#endif // COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_COORDINATOR_IOS_H_
diff --git a/components/embedder_support/ios/delegate/color_chooser/color_chooser_coordinator_ios.mm b/components/embedder_support/ios/delegate/color_chooser/color_chooser_coordinator_ios.mm new file mode 100644 index 0000000..ec7fe9df --- /dev/null +++ b/components/embedder_support/ios/delegate/color_chooser/color_chooser_coordinator_ios.mm
@@ -0,0 +1,52 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "components/embedder_support/ios/delegate/color_chooser/color_chooser_coordinator_ios.h" + +#import "components/embedder_support/ios/delegate/color_chooser/color_chooser_controller_ios.h" +#import "components/embedder_support/ios/delegate/color_chooser/color_chooser_mediator_ios.h" +#import "ui/gfx/native_widget_types.h" + +@implementation ColorChooserCoordinatorIOS + +- (instancetype)initWithBaseViewController:(UIViewController*)baseViewController + colorChooser: + (web_contents_delegate_ios::ColorChooserIOS*) + colorChooser + color:(UIColor*)color { + if (!(self = [super init])) { + return nil; + } + + _colorChooserMediator = + [[ColorChooserMediatorIOS alloc] initWithColorChooser:colorChooser]; + + _colorChooserController = [[ColorChooserControllerIOS alloc] + initWithChooserDelegate:_colorChooserMediator + color:color]; + _colorChooserController.modalInPresentation = YES; + _colorChooserController.modalPresentationStyle = UIModalPresentationPopover; + _colorChooserController.popoverPresentationController.delegate = + _colorChooserController; + _colorChooserController.popoverPresentationController.sourceView = + baseViewController.view; + _colorChooserController.popoverPresentationController.sourceRect = + baseViewController.view.bounds; + + _colorChooserMediator.consumer = _colorChooserController; + [baseViewController presentViewController:_colorChooserController + animated:YES + completion:nil]; + return self; +} + +- (void)closeColorChooser { + [self.colorChooserMediator closeColorChooser]; +} + +- (void)setColor:(UIColor*)color { + [self.colorChooserMediator setColor:color]; +} + +@end
diff --git a/components/embedder_support/ios/delegate/color_chooser/color_chooser_delegate_ios.h b/components/embedder_support/ios/delegate/color_chooser/color_chooser_delegate_ios.h new file mode 100644 index 0000000..92047b1 --- /dev/null +++ b/components/embedder_support/ios/delegate/color_chooser/color_chooser_delegate_ios.h
@@ -0,0 +1,22 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_DELEGATE_IOS_H_ +#define COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_DELEGATE_IOS_H_ + +#import <Foundation/Foundation.h> + +@class ColorChooserControllerIOS; +@class UIColor; + +// Delegate to handle actions. +@protocol ColorChooserDelegateIOS <NSObject> + +// Method invoked when the user closes the UIColorPickerViewController. +- (void)onColorChosen:(ColorChooserControllerIOS*)controller + selectedColor:(UIColor*)color; + +@end + +#endif // COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_DELEGATE_IOS_H_
diff --git a/components/embedder_support/ios/delegate/color_chooser/color_chooser_ios.h b/components/embedder_support/ios/delegate/color_chooser/color_chooser_ios.h new file mode 100644 index 0000000..9c81213 --- /dev/null +++ b/components/embedder_support/ios/delegate/color_chooser/color_chooser_ios.h
@@ -0,0 +1,55 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_IOS_H_ +#define COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_IOS_H_ + +#include <vector> + +#include "base/compiler_specific.h" +#include "base/memory/raw_ptr.h" +#include "content/public/browser/color_chooser.h" +#include "third_party/blink/public/mojom/choosers/color_chooser.mojom.h" + +namespace content { +class WebContents; +} + +@class ColorChooserCoordinatorIOS; + +namespace web_contents_delegate_ios { + +class ColorChooserIOS : public content::ColorChooser { + public: + ColorChooserIOS( + content::WebContents* web_contents, + SkColor initial_color, + const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions); + + ColorChooserIOS(const ColorChooserIOS&) = delete; + ColorChooserIOS& operator=(const ColorChooserIOS&) = delete; + + ~ColorChooserIOS() override; + + void OnColorChosen(SkColor color); + + // content::ColorChooser interface + void End() override; + void SetSelectedColor(SkColor color) override; + + // Return a weak pointer to the current object. + base::WeakPtr<ColorChooserIOS> AsWeakPtr(); + + private: + // The web contents invoking the color chooser. No ownership because it will + // outlive this class. + raw_ptr<content::WebContents> web_contents_; + ColorChooserCoordinatorIOS* __strong coordinator_; + + base::WeakPtrFactory<ColorChooserIOS> weak_ptr_factory_{this}; +}; + +} // namespace web_contents_delegate_ios + +#endif // COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_IOS_H_
diff --git a/components/embedder_support/ios/delegate/color_chooser/color_chooser_ios.mm b/components/embedder_support/ios/delegate/color_chooser/color_chooser_ios.mm new file mode 100644 index 0000000..7fe0bc81 --- /dev/null +++ b/components/embedder_support/ios/delegate/color_chooser/color_chooser_ios.mm
@@ -0,0 +1,59 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/embedder_support/ios/delegate/color_chooser/color_chooser_ios.h" + +#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> + +#include "components/embedder_support/ios/delegate/color_chooser/color_chooser_coordinator_ios.h" +#include "components/embedder_support/ios/delegate/color_chooser/color_chooser_mediator_ios.h" +#include "content/public/browser/web_contents.h" +#include "skia/ext/skia_utils_ios.h" +#include "ui/gfx/native_widget_types.h" + +namespace web_contents_delegate_ios { + +ColorChooserIOS::ColorChooserIOS( + content::WebContents* web_contents, + SkColor initial_color, + const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions) + : web_contents_(web_contents) { + gfx::NativeWindow native_window = web_contents_->GetTopLevelNativeWindow(); + coordinator_ = [[ColorChooserCoordinatorIOS alloc] + initWithBaseViewController:native_window.Get().rootViewController + colorChooser:this + color:skia::UIColorFromSkColor(initial_color)]; +} + +ColorChooserIOS::~ColorChooserIOS() {} + +void ColorChooserIOS::End() { + if (!coordinator_) { + return; + } + [coordinator_ closeColorChooser]; + coordinator_ = nullptr; +} + +void ColorChooserIOS::SetSelectedColor(SkColor color) { + if (!coordinator_) { + return; + } + [coordinator_ setColor:skia::UIColorFromSkColor(color)]; +} + +void ColorChooserIOS::OnColorChosen(SkColor color) { + // Clean up |coordinator_| since this is called after the UI chooser is + // closed. + coordinator_ = nullptr; + web_contents_->DidChooseColorInColorChooser(color); + web_contents_->DidEndColorChooser(); +} + +base::WeakPtr<ColorChooserIOS> ColorChooserIOS::AsWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); +} + +} // namespace web_contents_delegate_ios
diff --git a/components/embedder_support/ios/delegate/color_chooser/color_chooser_mediator_ios.h b/components/embedder_support/ios/delegate/color_chooser/color_chooser_mediator_ios.h new file mode 100644 index 0000000..555681e4 --- /dev/null +++ b/components/embedder_support/ios/delegate/color_chooser/color_chooser_mediator_ios.h
@@ -0,0 +1,43 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_MEDIATOR_IOS_H_ +#define COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_MEDIATOR_IOS_H_ + +#import <Foundation/Foundation.h> + +#import "base/memory/weak_ptr.h" +#import "components/embedder_support/ios/delegate/color_chooser/color_chooser_delegate_ios.h" + +namespace web_contents_delegate_ios { +class ColorChooserIOS; +} // namespace web_contents_delegate_ios + +@protocol ColorChooserConsumerIOS; +@class UIColor; + +// The mediator that implements ColorChooserDelegateIOS. It also communicates +// with the controller, referring to `consumer`. +@interface ColorChooserMediatorIOS : NSObject <ColorChooserDelegateIOS> + +@property(nonatomic, assign) + base::WeakPtr<web_contents_delegate_ios::ColorChooserIOS> + colorChooser; + +// Consumer that is configured by this mediator. +@property(nonatomic, assign) id<ColorChooserConsumerIOS> consumer; + +// Initializer. +- (instancetype)initWithColorChooser: + (web_contents_delegate_ios::ColorChooserIOS*)colorChooser; + +// Closes the color chooser. +- (void)closeColorChooser; + +// Sets the selected color in the color chooser. +- (void)setColor:(UIColor*)color; + +@end + +#endif // COMPONENTS_EMBEDDER_SUPPORT_IOS_DELEGATE_COLOR_CHOOSER_COLOR_CHOOSER_MEDIATOR_IOS_H_
diff --git a/components/embedder_support/ios/delegate/color_chooser/color_chooser_mediator_ios.mm b/components/embedder_support/ios/delegate/color_chooser/color_chooser_mediator_ios.mm new file mode 100644 index 0000000..2fd2c70 --- /dev/null +++ b/components/embedder_support/ios/delegate/color_chooser/color_chooser_mediator_ios.mm
@@ -0,0 +1,42 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "components/embedder_support/ios/delegate/color_chooser/color_chooser_mediator_ios.h" + +#import <UIKit/UIKit.h> + +#import "components/embedder_support/ios/delegate/color_chooser/color_chooser_consumer_ios.h" +#import "components/embedder_support/ios/delegate/color_chooser/color_chooser_ios.h" +#import "third_party/skia/include/core/SkColor.h" + +@implementation ColorChooserMediatorIOS + +- (instancetype)initWithColorChooser: + (web_contents_delegate_ios::ColorChooserIOS*)colorChooser { + if (!(self = [super init])) { + return nil; + } + _colorChooser = colorChooser->AsWeakPtr(); + return self; +} + +- (void)closeColorChooser { + [self.consumer closeColorChooser]; +} + +- (void)setColor:(UIColor*)color { + [self.consumer setColor:color]; +} + +#pragma mark - ColorChooserDelegateIOS + +- (void)onColorChosen:(ColorChooserControllerIOS*)controller + selectedColor:(UIColor*)color { + CGFloat red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0; + [color getRed:&red green:&green blue:&blue alpha:&alpha]; + self.colorChooser->OnColorChosen(SkColorSetARGB( + alpha * 255.0f, red * 255.0f, green * 255.0f, blue * 255.0f)); +} + +@end
diff --git a/components/history_clusters/core/config.cc b/components/history_clusters/core/config.cc index 285ac9e4..1709564 100644 --- a/components/history_clusters/core/config.cc +++ b/components/history_clusters/core/config.cc
@@ -71,21 +71,6 @@ sort_clusters_within_batch_for_query); } - // The `kJourneysLabels` feature and child params. - { - labels_from_hostnames = GetFieldTrialParamByFeatureAsBool( - internal::kJourneysLabels, "labels_from_hostnames", - labels_from_hostnames); - - labels_from_entities = GetFieldTrialParamByFeatureAsBool( - internal::kJourneysLabels, "labels_from_entities", - labels_from_entities); - - labels_from_search_visit_entities = GetFieldTrialParamByFeatureAsBool( - internal::kJourneysLabels, "labels_from_search_visit_entities", - labels_from_search_visit_entities); - } - // The `kJourneysImages` feature. { images = base::FeatureList::IsEnabled(internal::kJourneysImages);
diff --git a/components/history_clusters/core/config.h b/components/history_clusters/core/config.h index 9573b67..96ec1931 100644 --- a/components/history_clusters/core/config.h +++ b/components/history_clusters/core/config.h
@@ -63,23 +63,6 @@ // reverse chronologically, but the clusters within batches will be resorted. bool sort_clusters_within_batch_for_query = false; - // The `kJourneysLabels` feature and child params. - - // Whether to assign labels to clusters from the hostnames of the cluster. - // Does nothing if `should_label_clusters` is false. Note that since every - // cluster has a hostname, this flag in conjunction with - // `should_label_clusters` will give every cluster a label. - bool labels_from_hostnames = true; - - // Whether to assign labels to clusters from the Entities of the cluster. - // Does nothing if `should_label_clusters` is false. - bool labels_from_entities = false; - - // Whether to assign labels to clusters from the entities associated with - // search visits within a cluster if there are multiple search visits for the - // cluster. - bool labels_from_search_visit_entities = false; - // The `kJourneysImages` feature and child params. // Whether to attempt to provide images for eligible Journeys.
diff --git a/components/history_clusters/core/features.cc b/components/history_clusters/core/features.cc index c2696b6..b15074c 100644 --- a/components/history_clusters/core/features.cc +++ b/components/history_clusters/core/features.cc
@@ -29,10 +29,6 @@ BASE_FEATURE(kJourneys, "Journeys", enabled_by_default_desktop_only); -BASE_FEATURE(kJourneysLabels, - "JourneysLabel", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kJourneysImages, "JourneysImages", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/components/history_clusters/core/features.h b/components/history_clusters/core/features.h index ad7f6141..ee16c95 100644 --- a/components/history_clusters/core/features.h +++ b/components/history_clusters/core/features.h
@@ -22,9 +22,6 @@ // directly. Instead use `IsJourneysEnabled()` for the system language filter. BASE_DECLARE_FEATURE(kJourneys); -// Enables labelling of Journeys in UI. -BASE_DECLARE_FEATURE(kJourneysLabels); - // Enables images for Journeys in UI. BASE_DECLARE_FEATURE(kJourneysImages);
diff --git a/components/history_clusters/core/label_cluster_finalizer.cc b/components/history_clusters/core/label_cluster_finalizer.cc index 004406e7..ea57ddf 100644 --- a/components/history_clusters/core/label_cluster_finalizer.cc +++ b/components/history_clusters/core/label_cluster_finalizer.cc
@@ -46,7 +46,7 @@ } // If we haven't found a label yet, use hostnames if the flag is enabled. - if (GetConfig().labels_from_hostnames && !current_highest_scoring_label) { + if (!current_highest_scoring_label) { base::flat_map<std::u16string, float> hostname_to_score; for (const auto& visit : cluster.visits) { std::u16string host =
diff --git a/components/history_clusters/core/label_cluster_finalizer_unittest.cc b/components/history_clusters/core/label_cluster_finalizer_unittest.cc index 8ff3c3c..ad0824c 100644 --- a/components/history_clusters/core/label_cluster_finalizer_unittest.cc +++ b/components/history_clusters/core/label_cluster_finalizer_unittest.cc
@@ -56,26 +56,6 @@ {"baz", 25}, {"someotherentity", 10}}; { - // With only search term labelling active, there should be no label. - Config config; - config.labels_from_hostnames = false; - config.labels_from_entities = false; - SetConfigForTesting(config); - - history::Cluster cluster; - cluster.visits = {visit2, visit3}; - FinalizeCluster(cluster); - EXPECT_EQ(cluster.raw_label, std::nullopt); - EXPECT_EQ(cluster.label, std::nullopt); - EXPECT_EQ(cluster.label_source, LabelSource::kUnknown); - } - - { - // With hostname labelling active only, we should use the hostname. - Config config; - config.labels_from_hostnames = true; - SetConfigForTesting(config); - history::Cluster cluster; cluster.visits = {visit2, visit3}; FinalizeCluster(cluster); @@ -86,20 +66,11 @@ } TEST_F(LabelClusterFinalizerTest, TakesHighestScoringSearchTermIfAvailable) { - // Verify that search terms take precedence even if labels from entities are - // enabled. - Config config; - config.labels_from_hostnames = true; - config.labels_from_entities = true; - config.labels_from_search_visit_entities = false; - SetConfigForTesting(config); - + // Verify that search terms take precedence. history::ClusterVisit visit = testing::CreateClusterVisit(testing::CreateDefaultAnnotatedVisit( 2, GURL("https://nosearchtermsbuthighscorevisit.com/"))); visit.engagement_score = 0.9; - visit.annotated_visit.content_annotations.model_annotations.entities = { - {"github", 100}, {"onlyinnoisyvisit", 99}}; history::ClusterVisit visit2 = testing::CreateClusterVisit(testing::CreateDefaultAnnotatedVisit( @@ -110,8 +81,6 @@ history::ClusterVisit visit3 = testing::CreateClusterVisit( testing::CreateDefaultAnnotatedVisit(2, GURL("https://baz.com/"))); visit3.score = 0.8; - visit3.annotated_visit.content_annotations.model_annotations.entities = { - {"github", 100}, {"someotherentity", 100}}; visit3.annotated_visit.content_annotations.search_terms = u"searchtermlabel"; history::Cluster cluster;
diff --git a/components/js_injection/browser/js_communication_host.cc b/components/js_injection/browser/js_communication_host.cc index c0eb2bb3..dd24977 100644 --- a/components/js_injection/browser/js_communication_host.cc +++ b/components/js_injection/browser/js_communication_host.cc
@@ -138,7 +138,7 @@ std::unique_ptr<WebMessageHostFactory> factory, const std::u16string& js_object_name, const std::vector<std::string>& allowed_origin_rules) { - // TODO(crbug.com/331250164): Cancel all bfcached / prerendered pages when + // TODO(crbug.com/331250164): Cancel all prerendered pages when // addWebMessageListener() is called. OriginMatcher origin_matcher; @@ -156,6 +156,13 @@ js_objects_.push_back(std::make_unique<JsObject>( js_object_name, origin_matcher, std::move(factory))); + // If a new message listener is added when a page is in BFCache, the + // listener won't be available when be page is restored since it is + // not injected for the page. To avoid this behavior difference when + // BFCache is involved vs not, evict all BFCached pages so that we won't + // restore any pages that don't have this object injected. + web_contents()->GetController().GetBackForwardCache().Flush(); + ForEachRenderFrameHostWithinSameWebContents( web_contents()->GetPrimaryMainFrame(), [this](content::RenderFrameHost* render_frame_host) {
diff --git a/components/js_injection/browser/js_to_browser_messaging.cc b/components/js_injection/browser/js_to_browser_messaging.cc index 4e64e30..4dc0562 100644 --- a/components/js_injection/browser/js_to_browser_messaging.cc +++ b/components/js_injection/browser/js_to_browser_messaging.cc
@@ -203,8 +203,6 @@ // TODO(crbug.com/40752101): this should really call // IsInactiveAndDisallowReactivation(). - // TODO(crbug.com/331250166): If an associated page is bfcached, evict it. - // A RenderFrame may inject JsToBrowserMessaging in the JavaScript context // more than once because of reusing of RenderFrame. host_.reset();
diff --git a/components/mirroring/service/openscreen_message_port_unittest.cc b/components/mirroring/service/openscreen_message_port_unittest.cc index 4b61dbe..9af8b0e 100644 --- a/components/mirroring/service/openscreen_message_port_unittest.cc +++ b/components/mirroring/service/openscreen_message_port_unittest.cc
@@ -32,7 +32,7 @@ OnMessage, (const std::string&, const std::string&, const std::string&), (override)); - MOCK_METHOD(void, OnError, (openscreen::Error), (override)); + MOCK_METHOD(void, OnError, (const openscreen::Error&), (override)); const std::string& source_id() override { return source_id_; }
diff --git a/components/mirroring/service/openscreen_session_host.cc b/components/mirroring/service/openscreen_session_host.cc index 380310a..9d1a5fb5 100644 --- a/components/mirroring/service/openscreen_session_host.cc +++ b/components/mirroring/service/openscreen_session_host.cc
@@ -613,7 +613,7 @@ void OpenscreenSessionHost::OnError( const openscreen::cast::SenderSession* session, - openscreen::Error error) { + const openscreen::Error& error) { switch (error.code()) { case openscreen::Error::Code::kAnswerTimeout: ReportAndLogError(SessionError::ANSWER_TIME_OUT, error.ToString());
diff --git a/components/mirroring/service/openscreen_session_host.h b/components/mirroring/service/openscreen_session_host.h index f1fa323..b2461a18 100644 --- a/components/mirroring/service/openscreen_session_host.h +++ b/components/mirroring/service/openscreen_session_host.h
@@ -111,7 +111,7 @@ const openscreen::cast::SenderSession* session, openscreen::cast::RemotingCapabilities capabilities) override; void OnError(const openscreen::cast::SenderSession* session, - openscreen::Error error) override; + const openscreen::Error& error) override; // RtpStreamClient overrides. void OnError(const std::string& message) override;
diff --git a/components/openscreen_platform/message_port_tls_connection_unittest.cc b/components/openscreen_platform/message_port_tls_connection_unittest.cc index fc25719..fdf8d85 100644 --- a/components/openscreen_platform/message_port_tls_connection_unittest.cc +++ b/components/openscreen_platform/message_port_tls_connection_unittest.cc
@@ -42,7 +42,8 @@ ~MockTlsConnectionClient() override = default; MOCK_METHOD2(OnRead, void(openscreen::TlsConnection*, std::vector<uint8_t>)); - MOCK_METHOD2(OnError, void(openscreen::TlsConnection*, openscreen::Error)); + MOCK_METHOD2(OnError, + void(openscreen::TlsConnection*, const openscreen::Error&)); }; class MockTaskRunner : public openscreen::TaskRunner {
diff --git a/components/openscreen_platform/tls_client_connection_unittest.cc b/components/openscreen_platform/tls_client_connection_unittest.cc index 81b9fcc..aa2f6cd0 100644 --- a/components/openscreen_platform/tls_client_connection_unittest.cc +++ b/components/openscreen_platform/tls_client_connection_unittest.cc
@@ -130,7 +130,7 @@ class MockTlsConnectionClient : public TlsConnection::Client { public: - MOCK_METHOD(void, OnError, (TlsConnection*, Error), (override)); + MOCK_METHOD(void, OnError, (TlsConnection*, const Error&), (override)); MOCK_METHOD(void, OnRead, (TlsConnection*, std::vector<uint8_t>), (override)); };
diff --git a/components/openscreen_platform/tls_connection_factory_unittest.cc b/components/openscreen_platform/tls_connection_factory_unittest.cc index e34efae8..140cf0e 100644 --- a/components/openscreen_platform/tls_connection_factory_unittest.cc +++ b/components/openscreen_platform/tls_connection_factory_unittest.cc
@@ -56,7 +56,7 @@ (override)); MOCK_METHOD(void, OnError, - (openscreen::TlsConnectionFactory*, Error), + (openscreen::TlsConnectionFactory*, const Error&), (override)); };
diff --git a/components/optimization_guide/OWNERS b/components/optimization_guide/OWNERS index 6839ccc..f4d6cbb 100644 --- a/components/optimization_guide/OWNERS +++ b/components/optimization_guide/OWNERS
@@ -1,5 +1,6 @@ -sophiechang@chromium.org +holte@chromium.org mcrouse@chromium.org rajendrant@chromium.org robertogden@chromium.org +sophiechang@chromium.org tbansal@chromium.org
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm index 5c7b15aa..10c26ba 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
@@ -763,17 +763,6 @@ pending_restoration_data_.clear(); session_restore_in_progress = true; - - // During an immersive fullscreen restore the key view loop can become - // corrupted. In certain situation this can cause an infinite loop when - // looking for the next valid key view, leading to an OOM. Recalculate the - // loop after the restore to prevent this. See https://crbug.com/324812653 - // for details. - // TODO(http://crbug.com/40261565): Remove when FB12010731 is fixed in - // AppKit. - if ([window_ immersiveFullscreen]) { - [window_ recalculateKeyViewLoop]; - } } // Ensure that:
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc index 02d064b..2f6a209 100644 --- a/components/safe_browsing/core/common/features.cc +++ b/components/safe_browsing/core/common/features.cc
@@ -133,7 +133,7 @@ BASE_FEATURE(kHashPrefixRealTimeLookups, "SafeBrowsingHashPrefixRealTimeLookups", #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ - BUILDFLAG(IS_CHROMEOS) + BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_IOS) base::FEATURE_ENABLED_BY_DEFAULT #else base::FEATURE_DISABLED_BY_DEFAULT
diff --git a/components/sync_preferences/common_syncable_prefs_database.cc b/components/sync_preferences/common_syncable_prefs_database.cc index efbd924..4beaf5a 100644 --- a/components/sync_preferences/common_syncable_prefs_database.cc +++ b/components/sync_preferences/common_syncable_prefs_database.cc
@@ -110,6 +110,7 @@ kAutofillPaymentCardBenefits = 69, // kCloseTabs = 70, (no longer synced) kShowTabGroupsInBookmarkBar = 71, + kFacilitatedPaymentsPix = 72, // See components/sync_preferences/README.md about adding new entries here. // vvvvv IMPORTANT! vvvvv // Note to the reviewer: IT IS YOUR RESPONSIBILITY to ensure that new syncable @@ -280,6 +281,11 @@ {autofill::prefs::kAutofillPaymentCardBenefits, {syncable_prefs_ids::kAutofillPaymentCardBenefits, syncer::PREFERENCES, PrefSensitivity::kNone, MergeBehavior::kNone}}, +#if BUILDFLAG(IS_ANDROID) + {autofill::prefs::kFacilitatedPaymentsPix, + {syncable_prefs_ids::kFacilitatedPaymentsPix, syncer::PREFERENCES, + PrefSensitivity::kNone, MergeBehavior::kNone}}, +#endif // BUILDFLAG(IS_ANDROID) }); } // namespace
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc index f9648e7..6ccf1a72 100644 --- a/components/viz/host/host_frame_sink_manager.cc +++ b/components/viz/host/host_frame_sink_manager.cc
@@ -300,6 +300,22 @@ capture_exact_surface_id); } +void HostFrameSinkManager::SetOnCopyOutputReadyCallback( + const blink::SameDocNavigationScreenshotDestinationToken& destination_token, + ScreenshotDestinationReadyCallback callback) { + CHECK(screenshot_destinations_.find(destination_token) == + screenshot_destinations_.end()); + screenshot_destinations_[destination_token] = std::move(callback); +} + +void HostFrameSinkManager::InvalidateCopyOutputReadyCallback( + const blink::SameDocNavigationScreenshotDestinationToken& + destination_token) { + auto it = screenshot_destinations_.find(destination_token); + CHECK(it != screenshot_destinations_.end()); + screenshot_destinations_.erase(it); +} + void HostFrameSinkManager::Throttle(const std::vector<FrameSinkId>& ids, base::TimeDelta interval) { frame_sink_manager_->Throttle(ids, interval); @@ -417,6 +433,20 @@ } #endif +void HostFrameSinkManager::OnScreenshotCaptured( + const blink::SameDocNavigationScreenshotDestinationToken& destination_token, + std::unique_ptr<CopyOutputResult> copy_output_result) { + auto it = screenshot_destinations_.find(destination_token); + if (it == screenshot_destinations_.end()) { + return; + } + SkBitmap immutable = + copy_output_result->ScopedAccessSkBitmap().GetOutScopedBitmap(); + immutable.setImmutable(); + std::move(it->second).Run(destination_token, std::move(immutable)); + screenshot_destinations_.erase(it); +} + uint32_t HostFrameSinkManager::CacheBackBufferForRootSink( const FrameSinkId& root_sink_id) { auto it = frame_sink_data_map_.find(root_sink_id);
diff --git a/components/viz/host/host_frame_sink_manager.h b/components/viz/host/host_frame_sink_manager.h index c3e3b12..a2bf0e2 100644 --- a/components/viz/host/host_frame_sink_manager.h +++ b/components/viz/host/host_frame_sink_manager.h
@@ -9,6 +9,7 @@ #include <optional> #include <string> #include <unordered_map> +#include <utility> #include <vector> #include "base/compiler_specific.h" @@ -205,6 +206,28 @@ std::unique_ptr<CopyOutputRequest> request, bool capture_exact_surface_id = false); + using ScreenshotDestinationReadyCallback = base::OnceCallback<void( + const blink::SameDocNavigationScreenshotDestinationToken& + destination_token, + SkBitmap copy_output)>; + // Sets the callback which is invoked when a `CopyOutputResult` associated + // with `destination_token` is received by the host/browser process from the + // Viz process. Must be called once per `destination_token`. + // This is used to save screenshots for same-document navigations committed in + // the renderer process. + void SetOnCopyOutputReadyCallback( + const blink::SameDocNavigationScreenshotDestinationToken& + destination_token, + ScreenshotDestinationReadyCallback callback); + + // Invalidates the `ScreenshotDestinationReadyCallback` for + // `destination_token`. Used when the destination is no longer eligible for + // storing the screenshot (e.g., a later-arrival screenshot after the + // destination is destroyed). + void InvalidateCopyOutputReadyCallback( + const blink::SameDocNavigationScreenshotDestinationToken& + destination_token); + void Throttle(const std::vector<FrameSinkId>& ids, base::TimeDelta interval); void StartThrottlingAllFrameSinks(base::TimeDelta interval); void StopThrottlingAllFrameSinks(); @@ -320,6 +343,10 @@ const std::vector<int32_t>& thread_ids, VerifyThreadIdsDoNotBelongToHostCallback callback) override; #endif + void OnScreenshotCaptured( + const blink::SameDocNavigationScreenshotDestinationToken& + destination_token, + std::unique_ptr<CopyOutputResult> copy_output_result) override; // Connections to/from FrameSinkManagerImpl. mojo::Remote<mojom::FrameSinkManager> frame_sink_manager_remote_; @@ -351,6 +378,13 @@ // This is kept in sync with implementation. DebugRendererSettings debug_renderer_settings_; + // When Viz sends the screenshot back to the host process, + // `ScreenshotDestinationReadyCallback` is invoked to stash the screenshot to + // the correct destination. + base::flat_map<blink::SameDocNavigationScreenshotDestinationToken, + ScreenshotDestinationReadyCallback> + screenshot_destinations_; + base::WeakPtrFactory<HostFrameSinkManager> weak_ptr_factory_{this}; };
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index 6fe8c2e..1a6fed8 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -509,7 +509,7 @@ public_deps += [ "//third_party/dawn/include/dawn:headers" ] deps += [ - "//third_party/dawn/src/dawn:cpp", + "//third_party/dawn/include/dawn:cpp_headers", "//third_party/dawn/src/dawn:proc", "//third_party/dawn/src/dawn/native", ]
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc index 261aa36..bf97443 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -94,6 +94,20 @@ return intersected.value_or(gfx::Rect{}); } +void RemoveSurfaceReferenceAndDispatchCopyOutputRequestCallback( + base::WeakPtr<FrameSinkManagerImpl> frame_sink_manager, + SurfaceId copied_surface, + const blink::SameDocNavigationScreenshotDestinationToken& destination_token, + std::unique_ptr<CopyOutputResult> result) { + if (!frame_sink_manager) { + return; + } + frame_sink_manager->surface_manager()->RemoveTemporaryReferenceAfterCopy( + copied_surface); + frame_sink_manager->OnScreenshotCaptured(destination_token, + std::move(result)); +} + } // namespace CompositorFrameSinkSupport::CompositorFrameSinkSupport( @@ -890,6 +904,26 @@ current_surface = surface_manager_->CreateSurface( weak_factory_.GetWeakPtr(), surface_info); + + // The previous surface needs to be valid to generate a screenshot. + if (frame.metadata.screenshot_destination.has_value() && prev_surface) { + surface_manager_->AddTemporaryReference(last_created_surface_id_); + auto copy_request = std::make_unique<CopyOutputRequest>( + CopyOutputRequest::ResultFormat::RGBA, + CopyOutputRequest::ResultDestination::kSystemMemory, + base::BindOnce( + &RemoveSurfaceReferenceAndDispatchCopyOutputRequestCallback, + frame_sink_manager_->GetWeakPtr(), last_created_surface_id_, + frame.metadata.screenshot_destination.value())); + copy_request->set_result_task_runner( + base::SequencedTaskRunner::GetCurrentDefault()); + + RequestCopyOfOutput( + PendingCopyOutputRequest(last_created_surface_id_.local_surface_id(), + SubtreeCaptureId{}, std::move(copy_request), + /*capture_exact_id=*/true)); + } + if (!current_surface) { TRACE_EVENT_INSTANT0("viz", "Surface belongs to another client", TRACE_EVENT_SCOPE_THREAD);
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc index b89230a3..09462b06 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
@@ -113,6 +113,10 @@ const std::vector<int32_t>& thread_ids, VerifyThreadIdsDoNotBelongToHostCallback callback) override {} #endif + void OnScreenshotCaptured( + const blink::SameDocNavigationScreenshotDestinationToken& + destination_token, + std::unique_ptr<CopyOutputResult> copy_output_result) override {} }; class CompositorFrameSinkSupportTest : public testing::Test {
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 fd661e5..9388db5f 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -894,6 +894,13 @@ navigation_to_animation_manager_.erase(navigation_id); } +void FrameSinkManagerImpl::OnScreenshotCaptured( + const blink::SameDocNavigationScreenshotDestinationToken& destination_token, + std::unique_ptr<CopyOutputResult> copy_output_result) { + client_->OnScreenshotCaptured(destination_token, + std::move(copy_output_result)); +} + void FrameSinkManagerImpl::StartFrameCountingForTest( base::TimeTicks start_time, base::TimeDelta bucket_size) {
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 e2bccd12..aac1418 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -286,6 +286,17 @@ return frame_counter_ ? &frame_counter_.value() : nullptr; } + // Sends `copy_output_result` tagged by `destination_token` back to + // `mojom::FrameSinkManagerClient`. + void OnScreenshotCaptured( + const blink::SameDocNavigationScreenshotDestinationToken& + destination_token, + std::unique_ptr<CopyOutputResult> copy_output_result); + + base::WeakPtr<FrameSinkManagerImpl> GetWeakPtr() { + return weak_factory_.GetWeakPtr(); + } + private: friend class FrameSinkManagerTest; friend class CompositorFrameSinkSupportTest; @@ -470,6 +481,8 @@ // Counts frames for test. std::optional<FrameCounter> frame_counter_; + + base::WeakPtrFactory<FrameSinkManagerImpl> weak_factory_{this}; }; } // namespace viz
diff --git a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc index 713120e..0e545a4 100644 --- a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc +++ b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
@@ -85,26 +85,15 @@ // could be RGBA/BGRA depends on platform and the preference of the buffer // format. When user wants ARGB result, it requests a CopyOutputRequest with // ResultFormat::RGBA which gives RGBA/BGRA results depends on platform and -// where the result is stored (system memory or shared texture). -// In our case, when requesting a kPreferGpuMemoryBuffer, it will create a blit -// request, results in CopyOutputRequest uses whatever RGBA/BGRA pixel format -// the GMB is, which we created in advance. For now, it is determined by -// GetFramePoolPlatformPixelFormat. +// where the result is stored (buffer format preference). +// Currently, kPreferGpuMemoryBuffer + ARGB will request BGRA as pixel format, +// but kDefault + ARGB will be platform dependent because CopyOutputRequest +// will use kN32_SkColorType (RGBA on Android, BGRA elsewhere) mostly, and use +// kRGBA_8888_SkColorType on iOS. // This is also documented in the mojom comments (https://crrev.com/c/5418235) // about SetFormat, indicating the ARGB format may produce RGBA/BGRA frames // depends on platform. -media::VideoPixelFormat GetFramePoolPlatformPixelFormat( - media::VideoPixelFormat format, - mojom::BufferFormatPreference buffer_format_preference) { - if (format == media::PIXEL_FORMAT_ARGB && - buffer_format_preference == - mojom::BufferFormatPreference::kPreferGpuMemoryBuffer) { - return media::PIXEL_FORMAT_ABGR; - } - return format; -} - // Get the frame pool for the specific format. We need context_provider if the // format is NV12 or ARGB (when buffer_format_preference is kNativeTexture). // Thus, buffer_format_preference is also needed to tell which mode ARGB use. @@ -124,9 +113,8 @@ switch (buffer_format_preference) { case mojom::BufferFormatPreference::kPreferGpuMemoryBuffer: return std::make_unique<GpuMemoryBufferVideoFramePool>( - capacity, - GetFramePoolPlatformPixelFormat(format, buffer_format_preference), - gfx::ColorSpace::CreateSRGB(), context_provider); + capacity, format, gfx::ColorSpace::CreateSRGB(), + context_provider); case mojom::BufferFormatPreference::kDefault: return std::make_unique<SharedMemoryVideoFramePool>(capacity); default: @@ -863,10 +851,7 @@ region_properties->render_pass_subrect.ToString()); auto reserve_start_time = base::TimeTicks::Now(); - frame = frame_pool_->ReserveVideoFrame( - GetFramePoolPlatformPixelFormat(pixel_format_, - buffer_format_preference_), - capture_size); + frame = frame_pool_->ReserveVideoFrame(pixel_format_, capture_size); UMA_HISTOGRAM_CUSTOM_TIMES( "Viz.FrameSinkVideoCapturer.ReserveFrameDuration",
diff --git a/components/viz/service/surfaces/surface_manager.cc b/components/viz/service/surfaces/surface_manager.cc index a163e1d4..1140031e 100644 --- a/components/viz/service/surfaces/surface_manager.cc +++ b/components/viz/service/surfaces/surface_manager.cc
@@ -607,6 +607,11 @@ RemoveTemporaryReferenceImpl(surface_id, RemovedReason::DROPPED); } +void SurfaceManager::RemoveTemporaryReferenceAfterCopy( + const SurfaceId& surface_id) { + RemoveTemporaryReferenceImpl(surface_id, RemovedReason::COPIED); +} + SurfaceAllocationGroup* SurfaceManager::GetOrCreateAllocationGroupForSurfaceId( const SurfaceId& surface_id) { std::unique_ptr<SurfaceAllocationGroup>& allocation_group =
diff --git a/components/viz/service/surfaces/surface_manager.h b/components/viz/service/surfaces/surface_manager.h index ece1d5f8d..19ef7b4c 100644 --- a/components/viz/service/surfaces/surface_manager.h +++ b/components/viz/service/surfaces/surface_manager.h
@@ -188,6 +188,13 @@ // next display frame. We will notify SurfaceObservers accordingly. void SurfaceWillBeDrawn(Surface* surface); + // Adds a temporary reference to |surface_id|. The reference will not have an + // owner initially. + void AddTemporaryReference(const SurfaceId& surface_id); + + // Removes the temporary reference after the `surface_id` is copied. + void RemoveTemporaryReferenceAfterCopy(const SurfaceId& surface_id); + // Removes temporary reference to |surface_id| and older surfaces. void DropTemporaryReference(const SurfaceId& surface_id); @@ -244,6 +251,7 @@ DROPPED = 1, // The surface won't be embedded so it was dropped. SKIPPED = 2, // A newer surface was embedded and the surface was skipped. EXPIRED = 4, // The surface was never embedded and expired. + COPIED = 5, // The surface was copied. COUNT }; @@ -266,10 +274,6 @@ // Returns whether |surface_id| has a temporary reference or not. bool HasTemporaryReference(const SurfaceId& surface_id) const; - // Adds a temporary reference to |surface_id|. The reference will not have an - // owner initially. - void AddTemporaryReference(const SurfaceId& surface_id); - // Removes temporary reference to |surface_id| and older surfaces. The // |reason| for removing will be recorded with UMA. void RemoveTemporaryReferenceImpl(const SurfaceId& surface_id, @@ -364,8 +368,6 @@ // Maximum length of uncommitted queue, zero means all frames are committed // automatically. const size_t max_uncommitted_frames_; - - base::WeakPtrFactory<SurfaceManager> weak_factory_{this}; }; } // namespace viz
diff --git a/components/webapps/browser/android/ambient_badge_manager.cc b/components/webapps/browser/android/ambient_badge_manager.cc index 314f55c..affdb65e 100644 --- a/components/webapps/browser/android/ambient_badge_manager.cc +++ b/components/webapps/browser/android/ambient_badge_manager.cc
@@ -8,9 +8,7 @@ #include <optional> #include <string> -#include "base/feature_list.h" #include "base/metrics/histogram_macros.h" -#include "components/messages/android/messages_feature.h" #include "components/prefs/pref_service.h" #include "components/segmentation_platform/public/constants.h" #include "components/segmentation_platform/public/input_context.h" @@ -22,8 +20,6 @@ #include "components/webapps/browser/android/install_prompt_prefs.h" #include "components/webapps/browser/android/shortcut_info.h" #include "components/webapps/browser/banners/app_banner_settings_helper.h" -#include "components/webapps/browser/features.h" -#include "components/webapps/browser/installable/installable_manager.h" #include "components/webapps/browser/installable/ml_installability_promoter.h" #include "components/webapps/browser/webapps_client.h" #include "content/public/browser/web_contents.h" @@ -32,8 +28,6 @@ namespace { -constexpr base::TimeDelta kSuppressedForFirsVisitPeriod = base::Days(30); - constexpr char kSegmentationResultHistogramName[] = "WebApk.InstallPrompt.SegmentationResult"; @@ -46,6 +40,9 @@ kMaxValue = kShowInstallPrompt, }; +bool gOverrideSegmentationResultForTesting = false; +bool gShowInstallPromptForTesting = false; + } // namespace AmbientBadgeManager::AmbientBadgeManager( @@ -76,12 +73,7 @@ maybe_show_pwa_bottom_sheet_ = std::move(maybe_show_pwa_bottom_sheet); UpdateState(State::kActive); - - if (base::FeatureList::IsEnabled(features::kInstallPromptSegmentation)) { - MaybeShowAmbientBadgeSmart(); - } else { - MaybeShowAmbientBadgeLegacy(); - } + MaybeShowAmbientBadgeSmart(); } void AmbientBadgeManager::AddToHomescreenFromBadge() { @@ -125,79 +117,6 @@ state_ = state; } -void AmbientBadgeManager::MaybeShowAmbientBadgeLegacy() { - // Do not show the ambient badge if it was recently dismissed. - if (AppBannerSettingsHelper::WasBannerRecentlyBlocked( - web_contents(), validated_url_, app_identifier_, - AppBannerManager::GetCurrentTime())) { - UpdateState(State::kBlocked); - return; - } - - if (ShouldSuppressAmbientBadgeOnFirstVisit()) { - UpdateState(State::kPendingEngagement); - return; - } - - // if it's showing for web app (not native app), only show if the worker check - // already passed. - if (a2hs_params_->app_type == AddToHomescreenParams::AppType::WEBAPK && - !passed_worker_check_) { - PerformWorkerCheckForAmbientBadge( - base::BindOnce(&AmbientBadgeManager::OnWorkerCheckResult, - weak_factory_.GetWeakPtr())); - return; - } - - ShowAmbientBadge(); -} - -bool AmbientBadgeManager::ShouldSuppressAmbientBadgeOnFirstVisit() { - if (!base::FeatureList::IsEnabled( - features::kAmbientBadgeSuppressFirstVisit)) { - return false; - } - - std::optional<base::Time> last_could_show_time = - AppBannerSettingsHelper::GetSingleBannerEvent( - web_contents(), validated_url_, app_identifier_, - AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW_AMBIENT_BADGE); - - AppBannerSettingsHelper::RecordBannerEvent( - web_contents(), validated_url_, app_identifier_, - AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW_AMBIENT_BADGE, - AppBannerManager::GetCurrentTime()); - - if (!last_could_show_time || last_could_show_time->is_null()) { - return true; - } - - return AppBannerManager::GetCurrentTime() - *last_could_show_time > - kSuppressedForFirsVisitPeriod; -} - -void AmbientBadgeManager::PerformWorkerCheckForAmbientBadge( - InstallableCallback callback) { - UpdateState(State::kPendingWorker); - InstallableParams params; - params.has_worker = true; - params.wait_for_worker = true; - InstallableManager* installable_manager = - InstallableManager::FromWebContents(&web_contents_.get()); - installable_manager->GetData(params, std::move(callback)); -} - -void AmbientBadgeManager::OnWorkerCheckResult(const InstallableData& data) { - if (!data.errors.empty()) { - return; - } - passed_worker_check_ = true; - - if (state_ == State::kPendingWorker) { - ShowAmbientBadge(); - } -} - void AmbientBadgeManager::MaybeShowAmbientBadgeSmart() { if (ShouldMessageBeBlockedByGuardrail()) { UpdateState(State::kBlocked); @@ -211,7 +130,18 @@ CHECK(validated_url_.is_valid()); CHECK(a2hs_params_); - UpdateState(State::kSegmentation); + UpdateState(State::kPendingSegmentation); + + if (gOverrideSegmentationResultForTesting) { + segmentation_platform::ClassificationResult result( + segmentation_platform::PredictionStatus::kSucceeded); + result.ordered_labels.emplace_back( + gShowInstallPromptForTesting + ? MLInstallabilityPromoter::kShowInstallPromptLabel + : MLInstallabilityPromoter::kDontShowLabel); + OnGotClassificationResult(result); + return; + } segmentation_platform::PredictionOptions prediction_options; prediction_options.on_demand_execution = true; @@ -241,9 +171,7 @@ UMA_HISTOGRAM_ENUMERATION(kSegmentationResultHistogramName, SegmentationResult::kInvalid, SegmentationResult::kMaxValue); - - // If the classification is not ready yet, fallback to the legacy logic. - MaybeShowAmbientBadgeLegacy(); + UpdateState(State::kSegmentationBlock); return; } @@ -255,9 +183,13 @@ show ? SegmentationResult::kShowInstallPrompt : SegmentationResult::kDontShow, SegmentationResult::kMaxValue); - if (show) { - ShowAmbientBadge(); + + if (!show) { + UpdateState(State::kSegmentationBlock); + return; } + + ShowAmbientBadge(); } bool AmbientBadgeManager::ShouldMessageBeBlockedByGuardrail() { @@ -312,4 +244,10 @@ a2hs_params_->HasMaskablePrimaryIcon(), url); } +// static +void AmbientBadgeManager::SetOverrideSegmentationResultForTesting(bool show) { + gOverrideSegmentationResultForTesting = true; + gShowInstallPromptForTesting = show; +} + } // namespace webapps
diff --git a/components/webapps/browser/android/ambient_badge_manager.h b/components/webapps/browser/android/ambient_badge_manager.h index 7e6a3e1a..887c6940d 100644 --- a/components/webapps/browser/android/ambient_badge_manager.h +++ b/components/webapps/browser/android/ambient_badge_manager.h
@@ -12,9 +12,7 @@ #include "components/segmentation_platform/public/segmentation_platform_service.h" #include "components/webapps/browser/android/installable/installable_ambient_badge_client.h" #include "components/webapps/browser/android/installable/installable_ambient_badge_message_controller.h" -#include "components/webapps/browser/installable/installable_data.h" #include "components/webapps/browser/installable/installable_metrics.h" -#include "components/webapps/browser/installable/installable_params.h" #include "content/public/browser/web_contents.h" #include "url/gurl.h" @@ -22,14 +20,12 @@ namespace webapps { -class InstallableManager; struct AddToHomescreenParams; -struct InstallableData; // Coordinates the creation of an install ambient badge, from detecting the // eligibility to promote the associated web/native app and creating the ambient -// badge. Lifecycle: This class is owned by the AppBannerManagerAndroidclass and -// is instantiated when an ambient badge may be shown. +// badge. Lifecycle: This class is owned by the AppBannerManagerAndroid class +// and is instantiated when an ambient badge may be shown. class AmbientBadgeManager : public InstallableAmbientBadgeClient { public: // Returns if the bottom sheet was shown. @@ -60,10 +56,10 @@ kBlocked = 2, // Waiting for service worker install to trigger the banner. - kPendingWorker = 3, + kPendingWorker = 3, // Deprecated // Waiting for sufficient engagement to trigger the ambient badge. - kPendingEngagement = 4, + kPendingEngagement = 4, // Deprecated // Showing Ambient Badge. kShowing = 5, @@ -78,9 +74,12 @@ kComplete = 8, // Getting classification result from the segmentation platform. - kSegmentation = 9, + kPendingSegmentation = 9, - kMaxValue = kSegmentation, + // Blocked by segmentation result. + kSegmentationBlock = 10, + + kMaxValue = kSegmentationBlock, }; State state() const { return state_; } @@ -100,9 +99,7 @@ // Hides the ambient badge if it is showing. void HideAmbientBadge(); - // Callback invoked by the InstallableManager once it has finished checking - // service worker for showing ambient badge. - void OnWorkerCheckResult(const InstallableData& data); + static void SetOverrideSegmentationResultForTesting(bool show); protected: virtual void UpdateState(State state); @@ -116,10 +113,6 @@ void ShowAmbientBadge(); private: - // Perform checks and shows the install ambient badge. Uses legacy conditions - // instead of the segmentation APIs. - void MaybeShowAmbientBadgeLegacy(); - // Uses the segmentation APIs to decide showing the install ambient badge void MaybeShowAmbientBadgeSmart(); @@ -129,11 +122,6 @@ // Returns true if the prompt should be block. bool ShouldMessageBeBlockedByGuardrail(); - void PerformWorkerCheckForAmbientBadge(InstallableCallback callback); - - // Returns true if it's the first visit and the badge should be suprressed. - bool ShouldSuppressAmbientBadgeOnFirstVisit(); - // Message controller for the ambient badge. InstallableAmbientBadgeMessageController message_controller_{this}; @@ -157,8 +145,6 @@ // The current ambient badge status. State state_ = State::kInactive; - bool passed_worker_check_ = false; - base::WeakPtrFactory<AmbientBadgeManager> weak_factory_{this}; };
diff --git a/components/webapps/browser/android/app_banner_manager_android.cc b/components/webapps/browser/android/app_banner_manager_android.cc index 4164f44d..34c998b 100644 --- a/components/webapps/browser/android/app_banner_manager_android.cc +++ b/components/webapps/browser/android/app_banner_manager_android.cc
@@ -761,4 +761,11 @@ AppBannerSettingsHelper::SetTotalEngagementToTrigger(engagement); } +// static +void JNI_AppBannerManager_SetOverrideSegmentationResultForTesting( // IN-TEST + JNIEnv* env, + jboolean show) { + AmbientBadgeManager::SetOverrideSegmentationResultForTesting(show); +} + } // namespace webapps
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppBannerManager.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppBannerManager.java index 2d914db03..9f0fa65b 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppBannerManager.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppBannerManager.java
@@ -211,6 +211,11 @@ AppBannerManagerJni.get().setTotalEngagementToTrigger(engagement); } + /** Sets the install promo result from segmentation service for testing purpose. */ + public static void setOverrideSegmentationResultForTesting(boolean show) { + AppBannerManagerJni.get().setOverrideSegmentationResultForTesting(show); + } + /** Returns the AppBannerManager object. This is owned by the C++ banner manager. */ public static AppBannerManager forWebContents(WebContents contents) { ThreadUtils.assertOnUiThread(); @@ -262,5 +267,7 @@ void setTimeDeltaForTesting(int days); void setTotalEngagementToTrigger(double engagement); + + void setOverrideSegmentationResultForTesting(boolean show); } }
diff --git a/components/webapps/browser/features.cc b/components/webapps/browser/features.cc index 0b3f0eb..b3a91840 100644 --- a/components/webapps/browser/features.cc +++ b/components/webapps/browser/features.cc
@@ -14,10 +14,6 @@ "AddToHomescreenMessaging", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kAmbientBadgeSuppressFirstVisit, - "AmbientBadgeSuppressFirstVisit", - base::FEATURE_ENABLED_BY_DEFAULT); - // Enables or disables the installable ambient badge message. BASE_FEATURE(kInstallPromptGlobalGuardrails, "InstallPromptGlobalGuardrails", @@ -45,11 +41,6 @@ #endif // BUILDFLAG(IS_ANDROID) -// Use segmentation to decide whether install prompt should be shown. -BASE_FEATURE(kInstallPromptSegmentation, - "InstallPromptSegmentation", - base::FEATURE_ENABLED_BY_DEFAULT); - // Keys to use when querying the variations params. BASE_FEATURE(kAppBannerTriggering, "AppBannerTriggering",
diff --git a/components/webapps/browser/features.h b/components/webapps/browser/features.h index 9d44c556..f97a68a2 100644 --- a/components/webapps/browser/features.h +++ b/components/webapps/browser/features.h
@@ -28,9 +28,6 @@ #if BUILDFLAG(IS_ANDROID) BASE_DECLARE_FEATURE(kAddToHomescreenMessaging); -BASE_DECLARE_FEATURE(kAmbientBadgeSuppressFirstVisit); -extern const base::FeatureParam<base::TimeDelta> - kAmbientBadgeSuppressFirstVisit_Period; BASE_DECLARE_FEATURE(kInstallPromptGlobalGuardrails); extern const base::FeatureParam<int> kInstallPromptGlobalGuardrails_DismissCount; @@ -45,8 +42,6 @@ BASE_DECLARE_FEATURE(kWebApkInstallFailureNotification); #endif // BUILDFLAG(IS_ANDROID) -BASE_DECLARE_FEATURE(kInstallPromptSegmentation); - BASE_DECLARE_FEATURE(kAppBannerTriggering); extern const base::FeatureParam<double> kBannerParamsEngagementTotalKey; extern const base::FeatureParam<int> kBannerParamsDaysAfterBannerDismissedKey;
diff --git a/components/webapps/browser/installable/ml_installability_promoter.h b/components/webapps/browser/installable/ml_installability_promoter.h index 2d32226..028a0933 100644 --- a/components/webapps/browser/installable/ml_installability_promoter.h +++ b/components/webapps/browser/installable/ml_installability_promoter.h
@@ -95,6 +95,7 @@ public content::WebContentsUserData<MLInstallabilityPromoter> { public: static constexpr char kShowInstallPromptLabel[] = "ShowInstallPrompt"; + static constexpr char kDontShowLabel[] = "DontShow"; ~MLInstallabilityPromoter() override;
diff --git a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm index 0dfce563..4da3e57 100644 --- a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm +++ b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm
@@ -4,7 +4,9 @@ #include "content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h" +#include "base/apple/foundation_util.h" #import "base/task/sequenced_task_runner.h" +#import "components/remote_cocoa/app_shim/native_widget_mac_nswindow.h" #include "components/remote_cocoa/app_shim/ns_view_ids.h" #import "content/app_shim_remote_cocoa/web_contents_view_cocoa.h" #include "content/browser/web_contents/web_contents_view_mac.h" @@ -82,6 +84,29 @@ } void WebContentsNSViewBridge::SetVisible(bool visible) { + // If the first responder is a child of the current view, AppKit will search + // for a new first responder during `-setHidden:`. The key view loop is + // searched for a view that can become key. Typically this search yields no + // results and the window becomes the default first responder. However if this + // occurs after an immersive fullscreen restore an infinite loop can occur + // leading to an OOM. This occurs because of the existence of an NSToolbar, + // which causes the key loop traversal to jump back and forth between the + // view's window and the AppKit owned NSToolbarFullscreenWindow which hosts + // the toolbar in immersive fullscreen. To prevent this set the window's first + // responder to nil which will make the window the first responder before the + // hide. + // TODO(http://crbug.com/40261565): Remove when FB12010731 is fixed in + // AppKit. + NativeWidgetMacNSWindow* widget_window = + base::apple::ObjCCast<NativeWidgetMacNSWindow>(ns_view_.window); + if (!visible && [widget_window immersiveFullscreen]) { + NSView* first_responder = + base::apple::ObjCCast<NSView>(ns_view_.window.firstResponder); + if ([first_responder isDescendantOf:ns_view_]) { + [ns_view_.window makeFirstResponder:nil]; + } + } + [ns_view_ setHidden:!visible]; }
diff --git a/content/browser/android/javascript_injector.cc b/content/browser/android/javascript_injector.cc index f48ff46..9a6050d 100644 --- a/content/browser/android/javascript_injector.cc +++ b/content/browser/android/javascript_injector.cc
@@ -50,6 +50,14 @@ const JavaParamRef<jstring>& name, const JavaParamRef<jclass>& safe_annotation_clazz) { DCHECK(java_bridge_dispatcher_host_); + // If a new js object is added or removed when a page is in BFCache, + // the change won't apply after restoring the page. + // To avoid this behavior difference when BFCache is involved vs not, + // evict all BFCached pages so that we won't + // restore any pages that don't have this object modified. + // Same for RemoveInterface below. + // TODO(crbug.com/331250164): Evict prerendered pages as well + GetWebContents().GetController().GetBackForwardCache().Flush(); java_bridge_dispatcher_host_->AddNamedObject( ConvertJavaStringToUTF8(env, name), object, safe_annotation_clazz); } @@ -58,6 +66,7 @@ const JavaParamRef<jobject>& /* obj */, const JavaParamRef<jstring>& name) { DCHECK(java_bridge_dispatcher_host_); + GetWebContents().GetController().GetBackForwardCache().Flush(); java_bridge_dispatcher_host_->RemoveNamedObject( ConvertJavaStringToUTF8(env, name)); }
diff --git a/content/browser/renderer_host/render_frame_host_delegate.cc b/content/browser/renderer_host/render_frame_host_delegate.cc index 0f08d81..fe2f96f 100644 --- a/content/browser/renderer_host/render_frame_host_delegate.cc +++ b/content/browser/renderer_host/render_frame_host_delegate.cc
@@ -76,8 +76,7 @@ #endif bool RenderFrameHostDelegate::CanEnterFullscreenMode( - RenderFrameHostImpl* requesting_frame, - const blink::mojom::FullscreenOptions& options) { + RenderFrameHostImpl* requesting_frame) { return true; }
diff --git a/content/browser/renderer_host/render_frame_host_delegate.h b/content/browser/renderer_host/render_frame_host_delegate.h index d2369638..4e766c2 100644 --- a/content/browser/renderer_host/render_frame_host_delegate.h +++ b/content/browser/renderer_host/render_frame_host_delegate.h
@@ -318,9 +318,7 @@ #endif // Returns whether entering fullscreen with EnterFullscreenMode() is allowed. - virtual bool CanEnterFullscreenMode( - RenderFrameHostImpl* requesting_frame, - const blink::mojom::FullscreenOptions& options); + virtual bool CanEnterFullscreenMode(RenderFrameHostImpl* requesting_frame); // Notification that the frame with the given host wants to enter fullscreen // mode. Must only be called if CanEnterFullscreenMode returns true.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 16dc21f..aa31fd1 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -7524,7 +7524,7 @@ } } - if (!delegate_->CanEnterFullscreenMode(this, *options)) { + if (!delegate_->CanEnterFullscreenMode(this)) { std::move(callback).Run(/*granted=*/false); return; }
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 848cef4..6f5660c 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3928,8 +3928,7 @@ } bool WebContentsImpl::CanEnterFullscreenMode( - RenderFrameHostImpl* requesting_frame, - const blink::mojom::FullscreenOptions& options) { + RenderFrameHostImpl* requesting_frame) { // It's possible that this WebContents was spawned while blocking UI was on // the screen, or that it was downstream from a WebContents when UI was // blocked. Therefore, disqualify it from fullscreen if it or any upstream @@ -3938,14 +3937,14 @@ [](auto* opener) { return opener->fullscreen_blocker_count_ == 0; }) && - delegate_->CanEnterFullscreenModeForTab(requesting_frame, options); + delegate_->CanEnterFullscreenModeForTab(requesting_frame); } void WebContentsImpl::EnterFullscreenMode( RenderFrameHostImpl* requesting_frame, const blink::mojom::FullscreenOptions& options) { OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterFullscreenMode"); - DCHECK(CanEnterFullscreenMode(requesting_frame, options)); + DCHECK(CanEnterFullscreenMode(requesting_frame)); DCHECK(requesting_frame->IsActive()); DCHECK(ContainsOrIsFocusedWebContents()); if (base::FeatureList::IsEnabled(
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 4e02164..991ac5d 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -704,9 +704,7 @@ void GetNFC(RenderFrameHost*, mojo::PendingReceiver<device::mojom::NFC>) override; #endif - bool CanEnterFullscreenMode( - RenderFrameHostImpl* requesting_frame, - const blink::mojom::FullscreenOptions& options) override; + bool CanEnterFullscreenMode(RenderFrameHostImpl* requesting_frame) override; void EnterFullscreenMode( RenderFrameHostImpl* requesting_frame, const blink::mojom::FullscreenOptions& options) override;
diff --git a/content/public/browser/prerender_web_contents_delegate.cc b/content/public/browser/prerender_web_contents_delegate.cc index 83ac089..3a1155b 100644 --- a/content/public/browser/prerender_web_contents_delegate.cc +++ b/content/public/browser/prerender_web_contents_delegate.cc
@@ -78,8 +78,7 @@ } bool PrerenderWebContentsDelegate::CanEnterFullscreenModeForTab( - RenderFrameHost* requesting_frame, - const blink::mojom::FullscreenOptions& options) { + RenderFrameHost* requesting_frame) { // This should not be called for a prerendered page. NOTREACHED_NORETURN(); }
diff --git a/content/public/browser/prerender_web_contents_delegate.h b/content/public/browser/prerender_web_contents_delegate.h index f1b53283b..daaf42f 100644 --- a/content/public/browser/prerender_web_contents_delegate.h +++ b/content/public/browser/prerender_web_contents_delegate.h
@@ -42,9 +42,7 @@ const std::string& frame_name, const GURL& target_url, WebContents* new_contents) override; - bool CanEnterFullscreenModeForTab( - RenderFrameHost* requesting_frame, - const blink::mojom::FullscreenOptions& options) override; + bool CanEnterFullscreenModeForTab(RenderFrameHost* requesting_frame) override; void EnterFullscreenModeForTab( RenderFrameHost* requesting_frame, const blink::mojom::FullscreenOptions& options) override;
diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc index 18763ef8..f4d46da 100644 --- a/content/public/browser/web_contents_delegate.cc +++ b/content/public/browser/web_contents_delegate.cc
@@ -188,8 +188,7 @@ } bool WebContentsDelegate::CanEnterFullscreenModeForTab( - RenderFrameHost* requesting_frame, - const blink::mojom::FullscreenOptions& options) { + RenderFrameHost* requesting_frame) { return true; }
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index 55aa80726..4e003324 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h
@@ -469,9 +469,7 @@ // Returns whether entering fullscreen with |EnterFullscreenModeForTab()| is // allowed. - virtual bool CanEnterFullscreenModeForTab( - RenderFrameHost* requesting_frame, - const blink::mojom::FullscreenOptions& options); + virtual bool CanEnterFullscreenModeForTab(RenderFrameHost* requesting_frame); // Called when the renderer puts a tab into fullscreen mode. // |requesting_frame| is the specific content frame requesting fullscreen.
diff --git a/content/test/data/forms/form_controls_browsertest_button_win.png b/content/test/data/forms/form_controls_browsertest_button_win.png index b425e0f..d86595b7 100644 --- a/content/test/data/forms/form_controls_browsertest_button_win.png +++ b/content/test/data/forms/form_controls_browsertest_button_win.png Binary files differ
diff --git a/content/test/data/forms/form_controls_browsertest_checkbox_win.png b/content/test/data/forms/form_controls_browsertest_checkbox_win.png index 27342a78..f4a364c 100644 --- a/content/test/data/forms/form_controls_browsertest_checkbox_win.png +++ b/content/test/data/forms/form_controls_browsertest_checkbox_win.png Binary files differ
diff --git a/content/test/data/forms/form_controls_browsertest_color_input_win.png b/content/test/data/forms/form_controls_browsertest_color_input_win.png index d02f2852..57cadb7 100644 --- a/content/test/data/forms/form_controls_browsertest_color_input_win.png +++ b/content/test/data/forms/form_controls_browsertest_color_input_win.png Binary files differ
diff --git a/content/test/data/forms/form_controls_browsertest_dark_mode_text_selection_win.png b/content/test/data/forms/form_controls_browsertest_dark_mode_text_selection_win.png index 0193e49..e8985d2d 100644 --- a/content/test/data/forms/form_controls_browsertest_dark_mode_text_selection_win.png +++ b/content/test/data/forms/form_controls_browsertest_dark_mode_text_selection_win.png Binary files differ
diff --git a/content/test/data/forms/form_controls_browsertest_input_win.png b/content/test/data/forms/form_controls_browsertest_input_win.png index a58c8f14..2790f738c 100644 --- a/content/test/data/forms/form_controls_browsertest_input_win.png +++ b/content/test/data/forms/form_controls_browsertest_input_win.png Binary files differ
diff --git a/content/test/data/forms/form_controls_browsertest_meter_win.png b/content/test/data/forms/form_controls_browsertest_meter_win.png index 1b00a8b..73b8845 100644 --- a/content/test/data/forms/form_controls_browsertest_meter_win.png +++ b/content/test/data/forms/form_controls_browsertest_meter_win.png Binary files differ
diff --git a/content/test/data/forms/form_controls_browsertest_multi_select_win.png b/content/test/data/forms/form_controls_browsertest_multi_select_win.png index 7e7984a..e867deb8 100644 --- a/content/test/data/forms/form_controls_browsertest_multi_select_win.png +++ b/content/test/data/forms/form_controls_browsertest_multi_select_win.png Binary files differ
diff --git a/content/test/data/forms/form_controls_browsertest_progress_win.png b/content/test/data/forms/form_controls_browsertest_progress_win.png index 3197f23..8fb3cd950 100644 --- a/content/test/data/forms/form_controls_browsertest_progress_win.png +++ b/content/test/data/forms/form_controls_browsertest_progress_win.png Binary files differ
diff --git a/content/test/data/forms/form_controls_browsertest_radio_win.png b/content/test/data/forms/form_controls_browsertest_radio_win.png index 00576c64..172fbf9 100644 --- a/content/test/data/forms/form_controls_browsertest_radio_win.png +++ b/content/test/data/forms/form_controls_browsertest_radio_win.png Binary files differ
diff --git a/content/test/data/forms/form_controls_browsertest_range_win.png b/content/test/data/forms/form_controls_browsertest_range_win.png index 9eb052c..d90da00 100644 --- a/content/test/data/forms/form_controls_browsertest_range_win.png +++ b/content/test/data/forms/form_controls_browsertest_range_win.png Binary files differ
diff --git a/content/test/data/forms/form_controls_browsertest_select_win.png b/content/test/data/forms/form_controls_browsertest_select_win.png index 51ca511..225667d4 100644 --- a/content/test/data/forms/form_controls_browsertest_select_win.png +++ b/content/test/data/forms/form_controls_browsertest_select_win.png Binary files differ
diff --git a/content/test/data/forms/form_controls_browsertest_textarea_win.png b/content/test/data/forms/form_controls_browsertest_textarea_win.png index 1940e9d..26083754 100644 --- a/content/test/data/forms/form_controls_browsertest_textarea_win.png +++ b/content/test/data/forms/form_controls_browsertest_textarea_win.png Binary files differ
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index b23743d..bada212a 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -1003,6 +1003,22 @@ crbug.com/332743717 conformance/uniforms/uniform-location.html [ Failure ] crbug.com/332743717 [ android android-pixel-4 ] conformance2/canvas/drawingbuffer-storage-test.html [ Failure ] crbug.com/332743717 [ linux ] conformance2/canvas/drawingbuffer-storage-test.html [ Failure ] +crbug.com/332743717 [ mac angle-metal ] conformance2/query/occlusion-query-scissor.html [ Failure ] +crbug.com/332743717 [ mac intel angle-opengl ] conformance2/canvas/drawingbuffer-storage-test.html [ Failure ] +crbug.com/332743717 [ chromeos chromeos-board-amd64-generic ] conformance2/canvas/drawingbuffer-storage-test.html [ Failure ] +crbug.com/332743717 [ android android-pixel-2 ] conformance2/canvas/drawingbuffer-storage-test.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/bufferdata-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/bufferdata-4gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/buffersubdata-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/buffersubdata-4gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/getbuffersubdata-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/getbuffersubdata-4gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/readpixels-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/readpixels-4gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/teximage2d-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/teximage2d-4gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/texsubimage2d-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ android android-pixel-2 ] conformance2/wasm/texsubimage2d-4gb-wasm-memory.html [ Failure ] crbug.com/335203259 [ android android-pixel-4 ] conformance2/wasm/bufferdata-16gb-wasm-memory.html [ Failure ] crbug.com/335203259 [ android android-pixel-4 ] conformance2/wasm/bufferdata-4gb-wasm-memory.html [ Failure ] crbug.com/335203259 [ android android-pixel-4 ] conformance2/wasm/buffersubdata-16gb-wasm-memory.html [ Failure ] @@ -1039,8 +1055,18 @@ crbug.com/335203259 [ win target-cpu-32 ] conformance2/wasm/teximage2d-4gb-wasm-memory.html [ Failure ] crbug.com/335203259 [ win target-cpu-32 ] conformance2/wasm/texsubimage2d-16gb-wasm-memory.html [ Failure ] crbug.com/335203259 [ win target-cpu-32 ] conformance2/wasm/texsubimage2d-4gb-wasm-memory.html [ Failure ] -crbug.com/332743717 [ mac angle-metal ] conformance2/query/occlusion-query-scissor.html [ Failure ] -crbug.com/332743717 [ mac intel angle-opengl ] conformance2/canvas/drawingbuffer-storage-test.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-amd64-generic ] conformance2/wasm/bufferdata-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-amd64-generic ] conformance2/wasm/buffersubdata-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-amd64-generic ] conformance2/wasm/getbuffersubdata-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-amd64-generic ] conformance2/wasm/readpixels-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-amd64-generic ] conformance2/wasm/teximage2d-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-amd64-generic ] conformance2/wasm/texsubimage2d-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-jacuzzi ] conformance2/wasm/bufferdata-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-jacuzzi ] conformance2/wasm/buffersubdata-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-jacuzzi ] conformance2/wasm/getbuffersubdata-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-jacuzzi ] conformance2/wasm/readpixels-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-jacuzzi ] conformance2/wasm/teximage2d-16gb-wasm-memory.html [ Failure ] +crbug.com/335203259 [ chromeos chromeos-board-jacuzzi ] conformance2/wasm/texsubimage2d-16gb-wasm-memory.html [ Failure ] ################################################################# # Temporary suppressions for introduction of drawingBufferStorage
diff --git a/docs/linux/build_instructions.md b/docs/linux/build_instructions.md index 5196cf9..c0d17aea 100644 --- a/docs/linux/build_instructions.md +++ b/docs/linux/build_instructions.md
@@ -12,10 +12,12 @@ ## System requirements -* A 64-bit Intel machine with at least 8GB of RAM. More than 16GB is highly - recommended. -* At least 100GB of free disk space. -* You must have Git and Python v3.8+ installed already (and `python3` must point +* A 64-bit Intel machine with at least 8GB of RAM. More than 16GB is highly + recommended. If your machine has an SSD, it is recommended to have + \>=32GB/>=16GB of swap for machines with 8GB/16GB of RAM respectively. +* At least 100GB of free disk space. It does not have to be on the same drive; + Allocate ~50-80GB on HDD for build. +* You must have Git and Python v3.8+ installed already (and `python3` must point to a Python v3.8+ binary). Depot_tools bundles an appropriate version of Python in `$depot_tools/python-bin`, if you don't have an appropriate version already on your system. @@ -24,7 +26,6 @@ runs 22.04, Jammy Jellyfish). There are some instructions for other distros below, but they are mostly unsupported, but installation instructions can be found in [Docker](#docker). - ## Install `depot_tools` Clone the `depot_tools` repository: @@ -94,7 +95,7 @@ ``` You may need to adjust the build dependencies for other distros. There are -some [notes](#notes) at the end of this document, but we make no guarantees +some [notes](#notes-for-other-distros) at the end of this document, but we make no guarantees for their accuracy. ### Run the hooks @@ -134,7 +135,7 @@ * For more info on GN, run `gn help` on the command line or read the [quick start guide](https://gn.googlesource.com/gn/+/main/docs/quick_start.md). -### <a name="faster-builds"></a>Faster builds +### Faster builds This section contains some things you can change to speed up your builds, sorted so that the things that make the biggest difference are first. @@ -203,7 +204,7 @@ ] ``` -and run `gclient sync`. This will regenerate the config files in +And run `gclient sync`. This will regenerate the config files in `buildtools/reclient_cfgs` to use the `rbe_instance` that you just added to your `.gclient` file. @@ -290,7 +291,9 @@ to get to the local physical disk directory where you keep those working development directories, consider putting - alias cd="cd -P" +``` +alias cd="cd -P" +``` in your `.bashrc` so that `$PWD` or `cwd` always refers to a physical, not logical directory (and make sure `CCACHE_BASEDIR` also refers to a physical @@ -311,8 +314,9 @@ required. I.e. mount tmpfs to the output directory where the build output goes: As root: - - mount -t tmpfs -o size=20G,nr_inodes=40k,mode=1777 tmpfs /path/to/out +``` +mount -t tmpfs -o size=20G,nr_inodes=40k,mode=1777 tmpfs /path/to/out +``` *** note **Caveat:** You need to have enough RAM + swap to back the tmpfs. For a full @@ -323,10 +327,10 @@ Quick and dirty benchmark numbers on a HP Z600 (Intel core i7, 16 cores hyperthreaded, 12 GB RAM) -* With tmpfs: - * 12m:20s -* Without tmpfs - * 15m:40s +* With tmpfs: + * 12m:20s +* Without tmpfs + * 15m:40s ### Smaller builds @@ -447,12 +451,12 @@ configuration](https://www.chromium.org/developers/gn-build-configuration) for other settings): -* Build in release mode (debugging symbols require more memory): +* Build in release mode (debugging symbols require more memory): `is_debug = false` -* Turn off symbols: `symbol_level = 0` -* Build in component mode (this is for development only, it will be slower and +* Turn off symbols: `symbol_level = 0` +* Build in component mode (this is for development only, it will be slower and may have broken functionality): `is_component_build = true` -* For official (ThinLTO) builds on Linux, increase the vm.max_map_count kernel +* For official (ThinLTO) builds on Linux, increase the vm.max_map_count kernel parameter: increase the `vm.max_map_count` value from default (like 65530) to for example 262144. You can run the `sudo sysctl -w vm.max_map_count=262144` command to set it in the current session from the shell, or add the @@ -460,13 +464,13 @@ ### More links -* Information about [building with Clang](../clang.md). -* You may want to [use a chroot](using_a_chroot.md) to +* Information about [building with Clang](../clang.md). +* You may want to [use a chroot](using_a_chroot.md) to isolate yourself from versioning or packaging conflicts. -* Cross-compiling for ARM? See [LinuxChromiumArm](chromium_arm.md). -* Want to use Eclipse as your IDE? See +* Cross-compiling for ARM? See [LinuxChromiumArm](chromium_arm.md). +* Want to use Eclipse as your IDE? See [LinuxEclipseDev](eclipse_dev.md). -* Want to use your built version as your default browser? See +* Want to use your built version as your default browser? See [LinuxDevBuildAsDefaultBrowser](dev_build_as_default_browser.md). ## Next Steps @@ -475,7 +479,7 @@ Linux, please check out the [Linux Development page](development.md) for more information. -## Notes for other distros <a name="notes"></a> +## Notes for other distros ### Arch Linux @@ -489,8 +493,8 @@ For the optional packages on Arch Linux: -* `php-cgi` is provided with `pacman` -* `wdiff` is not in the main repository but `dwdiff` is. You can get `wdiff` +* `php-cgi` is provided with `pacman` +* `wdiff` is not in the main repository but `dwdiff` is. You can get `wdiff` in AUR/`yaourt` ### Crostini (Debian based) @@ -666,7 +670,7 @@ There may be additional Docker-specific issues during compilation. See [this bug](https://crbug.com/1377520) for additional details on this. -Note: Clone [depot_tools first](#install-depot_tools). +Note: [Clone depot_tools](#install-depot_tools) first. #### Build Steps @@ -697,9 +701,9 @@ # EXPOSE 8080 RUN useradd -u 1000 chrom-d -USER chrom-d # Default user, can be root (not advised) or removed +USER chrom-d # Create normal user with name "chrom-d". Optional and you can use root but not advised. -# Start Chromium Builder "chrom-d"(modify this command as needed) +# Start Chromium Builder "chrom-d" (modify this command as needed) # CMD ["autoninja -C out/Default chrome"] CMD ["bash"] ``` @@ -717,40 +721,44 @@ ```shell $ docker run --rm \ # close instance upon exit -it \ # Run docker interactively - --name chrom-b \ # with name "chrom-b" - -u root \ # with user root - -v /path/on/machine/to/chromium:/chromium \ # With chromium folder mounted - -v /path/on/machine/to/depot_tools:/depot_tools \ # With depot_tools mounted - chrom-b # Run container with image name "chrom-b" + --name chrom-b \ # with name "chrom-b" + -u root \ # with user root + -v /path/on/machine/to/chromium:/chromium \ # With chromium folder mounted + -v /path/on/machine/to/depot_tools:/depot_tools \ # With depot_tools mounted + chrom-b # Run container with image name "chrom-b" ``` -1. Install dependencies: +4. Install dependencies: ```shell # ./build/install-build-deps.sh # `#` here means run as root which is done in previous step. ``` 5. Save container image with tag-id name `dpv1.0`. Run this on the machine, not in container + ```shell $ docker ps # Get docker running instances, copy the id you get +# Save/tag running docker container with name "chrom-b" with "dpv1.0" +# You can choose any tag name you want but propagate name accordingly +# You will need to create new tags when working on different parts of +# chromium which requires installing additional dependencies $ docker commit <ID from above step> chrom-b:dpv1.0 # Optional, just saves space by deleting unnecessary images $ docker image rmi chrom-b:latest && docker image prune \ && docker container prune && docker builder prune ``` -6. [Run hooks](#run-the-hooks): (Optional step, can be done in container as root, normal user or on machine. Here it is done on machine) -7. Exit container. +1. [Run hooks](#run-the-hooks). (On docker or machine if you installed depot_tools on machine) +2. Exit container. #### Run container ```shell $ docker run --rm \ # close instance upon exit -it \ # Run docker interactively - --name chrom-b \ # with name "chrom-b" + --name chrom-b \ # with name "chrom-b" -u $(id -u):$(id -g) \ # Run container as a non-root user with same UID & GID - -u root \ # with user root - -v /path/on/machine/to/chromium:/chromium \ # With chromium folder mounted - -v /path/on/machine/to/depot_tools:/depot_tools \ # With depot_tools mounted - chrom-b:dpv1.0 # Run container with image name "chrom-b" and tag dpv1.0 + -v /path/on/machine/to/chromium:/chromium \ # With chromium folder mounted + -v /path/on/machine/to/depot_tools:/depot_tools \ # With depot_tools mounted + chrom-b:dpv1.0 # Run container with image name "chrom-b" and tag dpv1.0 ```
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index a09cc77..a44032d 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -832,6 +832,8 @@ "service_worker/service_worker_test_utils.h", "test_event_router_observer.cc", "test_event_router_observer.h", + "test_extension_console_observer.cc", + "test_extension_console_observer.h", "updater/extension_cache_fake.cc", "updater/extension_cache_fake.h", "updater/extension_downloader_test_helper.cc",
diff --git a/extensions/browser/api/user_scripts/user_scripts_api.cc b/extensions/browser/api/user_scripts/user_scripts_api.cc index 3a01b30..a1828b4 100644 --- a/extensions/browser/api/user_scripts/user_scripts_api.cc +++ b/extensions/browser/api/user_scripts/user_scripts_api.cc
@@ -39,6 +39,35 @@ constexpr char kMatchesMissingError[] = "User script with ID '*' must specify 'matches'."; +// Returns true if the given `world_id` is valid from the API perspective. +// If invalid, populates `error_out`. +bool IsValidWorldId(const std::optional<std::string>& world_id, + std::string* error_out) { + if (!world_id) { + // Omitting world ID is valid. + return true; + } + + if (world_id->empty()) { + *error_out = "If specified, `worldId` must be non-empty."; + return false; + } + + if (world_id->at(0) == '_') { + *error_out = "World IDs beginning with '_' are reserved."; + return false; + } + + static constexpr size_t kMaxWorldIdLength = 256; + if (world_id->length() > kMaxWorldIdLength) { + *error_out = "World IDs must be at most 256 characters."; + return false; + } + + // Valid world ID! + return true; +} + api::scripts_internal::SerializedUserScript ConvertRegisteredUserScriptToSerializedUserScript( api::user_scripts::RegisteredUserScript user_script) { @@ -120,6 +149,12 @@ } } + std::string utf8_error; + if (!IsValidWorldId(user_script.world_id, &utf8_error)) { + *error = base::UTF8ToUTF16(utf8_error); + return nullptr; + } + // After this, we can just convert to our internal type and rely on our // typical parsing to a `UserScript`. api::scripts_internal::SerializedUserScript serialized_script = @@ -558,8 +593,10 @@ world_id = std::move(params->properties.world_id); } - // TODO(https://crbug.com/331680187): Disallow world IDs that begin with - // underscores here and in the script registration flow. + std::string error; + if (!IsValidWorldId(world_id, &error)) { + return RespondNow(Error(std::move(error))); + } // TODO(https://crbug.com/331680187): Add some reasonable limit to the number // of worlds an extension may create and configure.
diff --git a/extensions/browser/test_extension_console_observer.cc b/extensions/browser/test_extension_console_observer.cc new file mode 100644 index 0000000..e2cf12a1a4 --- /dev/null +++ b/extensions/browser/test_extension_console_observer.cc
@@ -0,0 +1,91 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/test_extension_console_observer.h" + +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/console_message.h" +#include "content/public/test/browser_test_utils.h" +#include "extensions/browser/extension_host.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/process_manager.h" +#include "extensions/browser/service_worker/service_worker_test_utils.h" +#include "third_party/blink/public/mojom/devtools/console_message.mojom-shared.h" + +namespace extensions { + +TestExtensionConsoleObserver::TestExtensionConsoleObserver( + content::BrowserContext* context, + const ExtensionId& extension_id, + bool fail_on_error) + : extension_id_(extension_id), fail_on_error_(fail_on_error) { + int manifest_version = ExtensionRegistry::Get(context) + ->enabled_extensions() + .GetByID(extension_id) + ->manifest_version(); + if (manifest_version == 3) { + scoped_observation_.Observe( + service_worker_test_utils::GetServiceWorkerContext(context)); + } else { + CHECK_EQ(manifest_version, 2); + ExtensionHost* host = + ProcessManager::Get(context)->GetBackgroundHostForExtension( + extension_id); + WebContentsObserver::Observe(host->host_contents()); + } +} + +TestExtensionConsoleObserver::~TestExtensionConsoleObserver() = default; + +void TestExtensionConsoleObserver::SetAllowedErrorMessages( + base::flat_set<std::u16string> allowed_messages) { + if (!fail_on_error_) { + return; + } + allowed_errors_ = std::move(allowed_messages); +} + +std::string TestExtensionConsoleObserver::GetMessageAt(size_t index) { + if (index < 0 || static_cast<size_t>(index) >= messages_.size()) { + ADD_FAILURE() << "Tried to retrieve a non-existent message at index: " + << index; + return std::string(); + } + return base::UTF16ToUTF8(messages_[index]); +} + +void TestExtensionConsoleObserver::HandleConsoleMessage( + const std::u16string& message, + blink::mojom::ConsoleMessageLevel log_level) { + if (allowed_errors_.contains(message)) { + return; + } + if (log_level == blink::mojom::ConsoleMessageLevel::kWarning || + log_level == blink::mojom::ConsoleMessageLevel::kError) { + messages_.push_back(message); + } +} + +void TestExtensionConsoleObserver::OnReportConsoleMessage( + int64_t version_id, + const GURL& scope, + const content::ConsoleMessage& message) { + HandleConsoleMessage(message.message, message.message_level); +} + +void TestExtensionConsoleObserver::OnDidAddMessageToConsole( + content::RenderFrameHost* source_frame, + blink::mojom::ConsoleMessageLevel log_level, + const std::u16string& message, + int32_t line_no, + const std::u16string& source_id, + const std::optional<std::u16string>& untrusted_stack_trace) { + if (source_frame->GetLastCommittedURL().host_piece() != extension_id_) { + return; + } + HandleConsoleMessage(message, log_level); +} + +} // namespace extensions
diff --git a/extensions/browser/test_extension_console_observer.h b/extensions/browser/test_extension_console_observer.h new file mode 100644 index 0000000..002f3dc --- /dev/null +++ b/extensions/browser/test_extension_console_observer.h
@@ -0,0 +1,76 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_TEST_EXTENSION_CONSOLE_OBSERVER_H_ +#define EXTENSIONS_BROWSER_TEST_EXTENSION_CONSOLE_OBSERVER_H_ + +#include <string> +#include <vector> + +#include "base/containers/flat_set.h" +#include "base/scoped_observation.h" +#include "content/public/browser/service_worker_context.h" +#include "content/public/browser/service_worker_context_observer.h" +#include "content/public/browser/web_contents_observer.h" +#include "extensions/common/extension_id.h" +#include "url/gurl.h" + +namespace content { +class BrowserContext; +struct ConsoleMessage; +class RenderFrameHost; +} // namespace content + +namespace extensions { + +// Monitors an extension's console for errors or warnings. +class TestExtensionConsoleObserver + : public content::ServiceWorkerContextObserver, + public content::WebContentsObserver { + public: + TestExtensionConsoleObserver(content::BrowserContext* context, + const ExtensionId& extension_id, + bool fail_on_error); + ~TestExtensionConsoleObserver() override; + + TestExtensionConsoleObserver(const TestExtensionConsoleObserver&) = delete; + TestExtensionConsoleObserver& operator=(const TestExtensionConsoleObserver&) = + delete; + + // Add a set of allowed error messages, to ignore. + void SetAllowedErrorMessages(base::flat_set<std::u16string> allowed_messages); + size_t GetErrorCount() { return messages_.size(); } + std::string GetMessageAt(size_t index); + + private: + void HandleConsoleMessage(const std::u16string& message, + blink::mojom::ConsoleMessageLevel log_level); + + // ServiceWorkerContextObserver: + void OnReportConsoleMessage(int64_t version_id, + const GURL& scope, + const content::ConsoleMessage& message) override; + + // WebContentsObserver: + void OnDidAddMessageToConsole( + content::RenderFrameHost* source_frame, + blink::mojom::ConsoleMessageLevel log_level, + const std::u16string& message, + int32_t line_no, + const std::u16string& source_id, + const std::optional<std::u16string>& untrusted_stack_trace) override; + + ExtensionId extension_id_; + bool fail_on_error_; + base::flat_set<std::u16string> allowed_errors_; + std::vector<std::u16string> messages_; + + base::ScopedObservation<content::ServiceWorkerContext, + content::ServiceWorkerContextObserver> + scoped_observation_{this}; +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_TEST_EXTENSION_CONSOLE_OBSERVER_H_
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 473d01d..d8a267f 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -205,7 +205,7 @@ "//gpu/command_buffer/client:gles2_interface", "//gpu/command_buffer/client:webgpu_interface", "//gpu/ipc:gpu_thread_holder", - "//third_party/dawn/src/dawn:cpp", + "//third_party/dawn/include/dawn:cpp_headers", "//third_party/dawn/src/dawn:proc", ] deps = [
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index e14a7ef..5040fb93 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn
@@ -387,7 +387,7 @@ "//skia:buildflags", "//third_party/angle:angle_image_util", "//third_party/angle:angle_version_info", - "//third_party/dawn/src/dawn:cpp", + "//third_party/dawn/include/dawn:cpp_headers", "//third_party/dawn/src/dawn:proc", "//third_party/libyuv", "//third_party/protobuf:protobuf_lite",
diff --git a/gpu/config/BUILD.gn b/gpu/config/BUILD.gn index e9833d8..15aaa85b 100644 --- a/gpu/config/BUILD.gn +++ b/gpu/config/BUILD.gn
@@ -211,7 +211,7 @@ public_deps += [ "//third_party/dawn/include/dawn:headers" ] deps += [ - "//third_party/dawn/src/dawn:cpp", + "//third_party/dawn/include/dawn:cpp_headers", "//third_party/dawn/src/dawn:proc", "//third_party/dawn/src/dawn/native", ]
diff --git a/gpu/ipc/service/BUILD.gn b/gpu/ipc/service/BUILD.gn index a908f37..592487f1 100644 --- a/gpu/ipc/service/BUILD.gn +++ b/gpu/ipc/service/BUILD.gn
@@ -173,7 +173,7 @@ ] } if (skia_use_dawn) { - deps += [ "//third_party/dawn/src/dawn:cpp" ] + deps += [ "//third_party/dawn/include/dawn:cpp_headers" ] } }
diff --git a/infra/config/generated/testing/gn_isolate_map.pyl b/infra/config/generated/testing/gn_isolate_map.pyl index e7685cd..77d5e27 100644 --- a/infra/config/generated/testing/gn_isolate_map.pyl +++ b/infra/config/generated/testing/gn_isolate_map.pyl
@@ -905,6 +905,14 @@ "label": "//headless:headless_browsertests", "type": "console_test_launcher", }, + "headless_shell_wpt": { + "label": "//:headless_shell_wpt", + "type": "generated_script", + "args": [ + "--results-directory", + "${ISOLATED_OUTDIR}", + ], + }, "headless_unittests": { "label": "//headless:headless_unittests", "type": "console_test_launcher",
diff --git a/infra/config/generated/testing/test_suites.pyl b/infra/config/generated/testing/test_suites.pyl index 725c435..2f2279e 100644 --- a/infra/config/generated/testing/test_suites.pyl +++ b/infra/config/generated/testing/test_suites.pyl
@@ -1041,7 +1041,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'base_junit_tests': { 'mixins': [ @@ -1056,7 +1055,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'build_junit_tests': { 'mixins': [ @@ -1071,7 +1069,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'chrome_java_test_pagecontroller_junit_tests': { 'mixins': [ @@ -1086,7 +1083,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'chrome_junit_tests': { 'mixins': [ @@ -1101,7 +1097,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'components_junit_tests': { 'mixins': [ @@ -1116,7 +1111,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'content_junit_tests': { 'mixins': [ @@ -1131,7 +1125,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'device_junit_tests': { 'mixins': [ @@ -1146,7 +1139,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'junit_unit_tests': { 'mixins': [ @@ -1161,7 +1153,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'keyboard_accessory_junit_tests': { 'mixins': [ @@ -1176,7 +1167,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'media_base_junit_tests': { 'mixins': [ @@ -1191,7 +1181,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'module_installer_junit_tests': { 'mixins': [ @@ -1206,7 +1195,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'net_junit_tests': { 'mixins': [ @@ -1221,7 +1209,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'paint_preview_junit_tests': { 'mixins': [ @@ -1236,7 +1223,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'password_check_junit_tests': { 'mixins': [ @@ -1251,7 +1237,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'password_manager_junit_tests': { 'mixins': [ @@ -1266,7 +1251,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'services_junit_tests': { 'mixins': [ @@ -1281,7 +1265,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'touch_to_fill_junit_tests': { 'mixins': [ @@ -1296,7 +1279,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'ui_junit_tests': { 'mixins': [ @@ -1311,7 +1293,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'webapk_client_junit_tests': { 'mixins': [ @@ -1326,7 +1307,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'webapk_shell_apk_h2o_junit_tests': { 'mixins': [ @@ -1341,7 +1321,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'webapk_shell_apk_junit_tests': { 'mixins': [ @@ -1356,7 +1335,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, }, @@ -1649,33 +1627,6 @@ }, }, - 'chromium_wpt_tests_old_headless_isolated_scripts': { - 'chrome_wpt_tests_old_headless': { - 'test': 'chrome_wpt_tests', - 'results_handler': 'layout tests', - 'mixins': [ - 'has_native_resultdb_integration', - ], - 'args': [ - '--test-type', - 'testharness', - 'reftest', - 'crashtest', - 'print-reftest', - '--additional-driver-flag=--headless=old', - ], - 'swarming': { - 'shards': 1, - }, - 'merge': { - 'script': '//third_party/blink/tools/merge_web_test_results.py', - 'args': [ - '--verbose', - ], - }, - }, - }, - 'clang_tot_gtests': { 'base_unittests': {}, }, @@ -4118,6 +4069,25 @@ 'headless_unittests': {}, }, + 'headless_shell_wpt_tests_isolated_scripts': { + 'headless_shell_wpt_tests': { + 'test': 'headless_shell_wpt', + 'results_handler': 'layout tests', + 'mixins': [ + 'has_native_resultdb_integration', + ], + 'swarming': { + 'shards': 10, + }, + 'merge': { + 'script': '//third_party/blink/tools/merge_web_test_results.py', + 'args': [ + '--verbose', + ], + }, + }, + }, + 'ios_blink_tests': { 'absl_hardening_tests': {}, 'angle_unittests': { @@ -6042,7 +6012,7 @@ 'chrome_wpt_tests_three_modes': [ 'chromium_wpt_tests_headful_isolated_scripts', 'chromium_wpt_tests_isolated_scripts', - 'chromium_wpt_tests_old_headless_isolated_scripts', + 'headless_shell_wpt_tests_isolated_scripts', ], 'chromeos_device_no_gtests': [
diff --git a/infra/config/lib/targets.star b/infra/config/lib/targets.star index e6d3bdf..933812e 100644 --- a/infra/config/lib/targets.star +++ b/infra/config/lib/targets.star
@@ -903,7 +903,7 @@ spec, error = _apply_mixin(spec, m.props.mixin_values) if error: fail("modifying {} {} with {} failed: {}" - .format(spec.handler.type_name, test.key.id, mixin, error)) + .format(spec.handler.type_name, test.key.id, m, error)) test_spec_and_source_by_name[test.key.id] = spec, n.key for child in graph.children(n.key, kind = _targets_nodes.BUNDLE.kind):
diff --git a/infra/config/targets/basic_suites.star b/infra/config/targets/basic_suites.star index 50b5b6143..d781007 100644 --- a/infra/config/targets/basic_suites.star +++ b/infra/config/targets/basic_suites.star
@@ -1117,7 +1117,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "base_junit_tests": targets.legacy_test_config( mixins = [ @@ -1132,7 +1131,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "build_junit_tests": targets.legacy_test_config( mixins = [ @@ -1147,7 +1145,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "chrome_java_test_pagecontroller_junit_tests": targets.legacy_test_config( mixins = [ @@ -1162,7 +1159,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "chrome_junit_tests": targets.legacy_test_config( mixins = [ @@ -1177,7 +1173,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "components_junit_tests": targets.legacy_test_config( mixins = [ @@ -1192,7 +1187,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "content_junit_tests": targets.legacy_test_config( mixins = [ @@ -1207,7 +1201,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "device_junit_tests": targets.legacy_test_config( mixins = [ @@ -1222,7 +1215,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "junit_unit_tests": targets.legacy_test_config( mixins = [ @@ -1237,7 +1229,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "keyboard_accessory_junit_tests": targets.legacy_test_config( mixins = [ @@ -1252,7 +1243,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "media_base_junit_tests": targets.legacy_test_config( mixins = [ @@ -1267,7 +1257,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "module_installer_junit_tests": targets.legacy_test_config( mixins = [ @@ -1282,7 +1271,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "net_junit_tests": targets.legacy_test_config( mixins = [ @@ -1297,7 +1285,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "paint_preview_junit_tests": targets.legacy_test_config( mixins = [ @@ -1312,7 +1299,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "password_check_junit_tests": targets.legacy_test_config( mixins = [ @@ -1327,7 +1313,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "password_manager_junit_tests": targets.legacy_test_config( mixins = [ @@ -1342,7 +1327,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "services_junit_tests": targets.legacy_test_config( mixins = [ @@ -1357,7 +1341,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "touch_to_fill_junit_tests": targets.legacy_test_config( mixins = [ @@ -1372,7 +1355,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "ui_junit_tests": targets.legacy_test_config( mixins = [ @@ -1387,7 +1369,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "webapk_client_junit_tests": targets.legacy_test_config( mixins = [ @@ -1402,7 +1383,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "webapk_shell_apk_h2o_junit_tests": targets.legacy_test_config( mixins = [ @@ -1417,7 +1397,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), "webapk_shell_apk_junit_tests": targets.legacy_test_config( mixins = [ @@ -1432,7 +1411,6 @@ "walleye", "pie_fleet", ], - use_isolated_scripts_api = True, ), }, ) @@ -1591,19 +1569,11 @@ ) targets.legacy_basic_suite( - name = "chromium_wpt_tests_old_headless_isolated_scripts", + name = "headless_shell_wpt_tests_isolated_scripts", tests = { - "chrome_wpt_tests_old_headless": targets.legacy_test_config( - args = [ - "--test-type", - "testharness", - "reftest", - "crashtest", - "print-reftest", - "--additional-driver-flag=--headless=old", - ], + "headless_shell_wpt_tests": targets.legacy_test_config( swarming = targets.swarming( - shards = 1, + shards = 10, ), ), },
diff --git a/infra/config/targets/binaries.star b/infra/config/targets/binaries.star index 41a6fdb1..77f31ec 100644 --- a/infra/config/targets/binaries.star +++ b/infra/config/targets/binaries.star
@@ -832,6 +832,22 @@ label = "//media/gpu/vaapi/test/fake_libva_driver:fake_libva_driver_unittest", ) +targets.binaries.generated_script( + name = "headless_shell_wpt", + label = "//:headless_shell_wpt", + results_handler = "layout tests", + args = [ + "--results-directory", + "${ISOLATED_OUTDIR}", + ], + merge = targets.merge( + script = "//third_party/blink/tools/merge_web_test_results.py", + args = [ + "--verbose", + ], + ), +) + targets.binaries.console_test_launcher( name = "video_decode_accelerator_tests", label = "//media/gpu/test:video_decode_accelerator_tests",
diff --git a/infra/config/targets/compound_suites.star b/infra/config/targets/compound_suites.star index f7148ddc..b43dd6c3 100644 --- a/infra/config/targets/compound_suites.star +++ b/infra/config/targets/compound_suites.star
@@ -171,7 +171,7 @@ basic_suites = [ "chromium_wpt_tests_isolated_scripts", "chromium_wpt_tests_headful_isolated_scripts", - "chromium_wpt_tests_old_headless_isolated_scripts", + "headless_shell_wpt_tests_isolated_scripts", ], )
diff --git a/infra/config/targets/tests.star b/infra/config/targets/tests.star index 9ebe628..3d89a2a52 100644 --- a/infra/config/targets/tests.star +++ b/infra/config/targets/tests.star
@@ -568,11 +568,11 @@ ) targets.tests.isolated_script_test( - name = "chrome_wpt_tests_old_headless", + name = "headless_shell_wpt_tests", mixins = [ "has_native_resultdb_integration", ], - binary = "chrome_wpt_tests", + binary = "headless_shell_wpt", ) targets.tests.gtest_test(
diff --git a/internal b/internal index df97b0f..5178496 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit df97b0f7451528e858398030e718d637a29aaa5f +Subproject commit 51784961a549aa3eff970c32af08734422989955
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm index c7e97346..608039c 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm
@@ -391,7 +391,9 @@ // Creates and sets up the view hierarchy. - (void)createViewHierarchy { - self.layoutGuide = AddLayoutGuideToContentView(self.contentView); + self.layoutGuide = AddLayoutGuideToContentView( + self.contentView, + /*cell_has_header=*/!IsKeyboardAccessoryUpgradeEnabled()); self.selectionStyle = UITableViewCellSelectionStyleNone;
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm index bb6ed44e..ad757cac 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm
@@ -182,7 +182,8 @@ // Creates and sets up the view hierarchy. - (void)createViewHierarchy { - self.layoutGuide = AddLayoutGuideToContentView(self.contentView); + self.layoutGuide = + AddLayoutGuideToContentView(self.contentView, /*cell_has_header=*/YES); self.selectionStyle = UITableViewCellSelectionStyleNone;
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.h b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.h index eff84f49..387c265 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.h +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.h
@@ -38,6 +38,8 @@ kLabeledChipButton, // A chip button that is not the first of its group and is unlabeled. kOtherChipButton, + // A grey line to separate some parts of the cell. + kSeparator, // Any other element not falling into one of the above types. kOther, }; @@ -128,6 +130,10 @@ NSMutableAttributedString* CreateHeaderAttributedString(NSString* title, NSString* subtitle); +// Creates an horizontal stack view containing an icon and a label. Used to +// create the different manual fill cells' header. +UIStackView* CreateHeaderView(UIView* icon, UILabel* label); + // Creates a gray horizontal line separator, with the same margin as the other // components here. The gray line is added to the given `container` and proper // constraints are enabled to keep the line at the bottom of the container and @@ -135,6 +141,9 @@ UIView* CreateGraySeparatorForContainer(UIView* container); // Creates a layout guide for the cell and adds it to the given 'content_view`. -UILayoutGuide* AddLayoutGuideToContentView(UIView* content_view); +// `cell_has_header` indicates whether or not the layout guide should take a +// header into account. +UILayoutGuide* AddLayoutGuideToContentView(UIView* content_view, + BOOL cell_has_header); #endif // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_MANUAL_FILL_CELL_UTILS_H_
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.mm index 8b7dc68..e09a155 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_cell_utils.mm
@@ -24,10 +24,16 @@ // Line spacing for the cell's header title. constexpr CGFloat kHeaderAttributedStringLineSpacing = 2; +// Minimum height for the header view. +constexpr CGFloat kHeaderViewMinHeight = 44; + // Horizontal spacing between views used in // `AppendHorizontalConstraintsForViews`. constexpr CGFloat kHorizontalSpacing = 16; +// Height of the grey separator. +constexpr CGFloat kSeparatorHeight = 1; + // Vertical spacing between views. Used when the Keyboard Accessory Upgrade // feature is disabled. constexpr CGFloat kVerticalSpacing = 8; @@ -36,8 +42,9 @@ // cell and the chip groups. constexpr CGFloat kGenericVerticalSpacingBetweenViews = 16; -// Vertical spacing between two chip buttons. -constexpr CGFloat kVerticalSpacingBetweenChips = 4; +// Small vertical spacing between views. Used to visually group chips together +// and as vertical padding for the cell's header. +constexpr CGFloat kSmallVerticalSpacingBetweenViews = 4; // Vertical spacing between two labeled chip buttons. constexpr CGFloat kVerticalSpacingBetweenLabeledChips = 8; @@ -56,8 +63,9 @@ return kGenericVerticalSpacingBetweenViews; case ManualFillCellView::ElementType::kLabeledChipButton: return kVerticalSpacingBetweenLabeledChips; + case ManualFillCellView::ElementType::kSeparator: case ManualFillCellView::ElementType::kOtherChipButton: - return kVerticalSpacingBetweenChips; + return kSmallVerticalSpacingBetweenViews; } } @@ -285,37 +293,70 @@ return attributed_title; } -UIView* CreateGraySeparatorForContainer(UIView* container) { - UIView* grayLine = [[UIView alloc] init]; - grayLine.backgroundColor = [UIColor colorNamed:kSeparatorColor]; - grayLine.translatesAutoresizingMaskIntoConstraints = NO; - [container addSubview:grayLine]; +UIStackView* CreateHeaderView(UIView* icon, UILabel* label) { + UIStackView* header_view = + [[UIStackView alloc] initWithArrangedSubviews:@[ icon, label ]]; + header_view.translatesAutoresizingMaskIntoConstraints = NO; + header_view.spacing = UIStackViewSpacingUseSystem; // Spacing of 8px. + header_view.alignment = UIStackViewAlignmentCenter; - id<LayoutGuideProvider> safeArea = container.safeAreaLayoutGuide; - [NSLayoutConstraint activateConstraints:@[ - // Vertical constraints. - [grayLine.bottomAnchor constraintEqualToAnchor:container.bottomAnchor], - [grayLine.heightAnchor constraintEqualToConstant:1], - // Horizontal constraints. - [grayLine.leadingAnchor constraintEqualToAnchor:safeArea.leadingAnchor - constant:kCellMargin], - [safeArea.trailingAnchor constraintEqualToAnchor:grayLine.trailingAnchor - constant:kCellMargin], - ]]; + if (IsKeyboardAccessoryUpgradeEnabled()) { + [NSLayoutConstraint activateConstraints:@[ + [header_view.heightAnchor + constraintGreaterThanOrEqualToConstant:kHeaderViewMinHeight], + ]]; + } - return grayLine; + return header_view; } -UILayoutGuide* AddLayoutGuideToContentView(UIView* content_view) { +UIView* CreateGraySeparatorForContainer(UIView* container) { + UIView* gray_line = [[UIView alloc] init]; + gray_line.backgroundColor = [UIColor colorNamed:kSeparatorColor]; + gray_line.translatesAutoresizingMaskIntoConstraints = NO; + [container addSubview:gray_line]; + + id<LayoutGuideProvider> safe_area = container.safeAreaLayoutGuide; + if (IsKeyboardAccessoryUpgradeEnabled()) { + [NSLayoutConstraint activateConstraints:@[ + // Vertical constraints. + [gray_line.heightAnchor constraintEqualToConstant:kSeparatorHeight], + // Horizontal constraints. + [gray_line.leadingAnchor constraintEqualToAnchor:safe_area.leadingAnchor + constant:kCellMargin], + [safe_area.trailingAnchor + constraintEqualToAnchor:gray_line.trailingAnchor], + ]]; + } else { + [NSLayoutConstraint activateConstraints:@[ + // Vertical constraints. + [gray_line.bottomAnchor constraintEqualToAnchor:container.bottomAnchor], + [gray_line.heightAnchor constraintEqualToConstant:kSeparatorHeight], + // Horizontal constraints. + [gray_line.leadingAnchor constraintEqualToAnchor:safe_area.leadingAnchor + constant:kCellMargin], + [safe_area.trailingAnchor constraintEqualToAnchor:gray_line.trailingAnchor + constant:kCellMargin], + ]]; + } + + return gray_line; +} + +UILayoutGuide* AddLayoutGuideToContentView(UIView* content_view, + BOOL cell_has_header) { UILayoutGuide* layout_guide = [[UILayoutGuide alloc] init]; [content_view addLayoutGuide:layout_guide]; id<LayoutGuideProvider> safe_area = content_view.safeAreaLayoutGuide; + CGFloat top_margin = cell_has_header && IsKeyboardAccessoryUpgradeEnabled() + ? kSmallVerticalSpacingBetweenViews + : kCellMargin; CGFloat bottom_margin = IsKeyboardAccessoryUpgradeEnabled() ? kCellMargin : kCellBottomMargin; [NSLayoutConstraint activateConstraints:@[ [layout_guide.topAnchor constraintEqualToAnchor:content_view.topAnchor - constant:kCellMargin], + constant:top_margin], [layout_guide.bottomAnchor constraintEqualToAnchor:content_view.bottomAnchor constant:-bottom_margin], [layout_guide.leadingAnchor constraintEqualToAnchor:safe_area.leadingAnchor
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_cell.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_cell.mm index b5b1ac8a..b1ff627 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_cell.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_cell.mm
@@ -114,6 +114,9 @@ // The constraints for the visible favicon. @property(nonatomic, strong) NSArray<NSLayoutConstraint*>* faviconContraints; +// The view displayed at the top the cell containing the favicon and site name. +@property(nonatomic, strong) UIView* headerView; + // The favicon for the credential. Of type FaviconView when the Keyboard // Accessory Upgrade is disabled, and FaviconContainerView when enabled. @property(nonatomic, strong) UIView* faviconView; @@ -191,11 +194,16 @@ if (IsKeyboardAccessoryUpgradeEnabled()) { self.siteNameLabel.numberOfLines = 0; } - AddViewToVerticalLeadViews(self.siteNameLabel, - ManualFillCellView::ElementType::kOther, - verticalLeadViews); self.siteNameLabel.hidden = NO; self.faviconView.hidden = NO; + AddViewToVerticalLeadViews(self.headerView, + ManualFillCellView::ElementType::kOther, + verticalLeadViews); + if (IsKeyboardAccessoryUpgradeEnabled()) { + AddViewToVerticalLeadViews(self.grayLine, + ManualFillCellView::ElementType::kSeparator, + verticalLeadViews); + } } // Holds the chip buttons related to the credential that are vertical leads. @@ -262,7 +270,8 @@ // Creates and sets up the view hierarchy. - (void)createViewHierarchy { - self.layoutGuide = AddLayoutGuideToContentView(self.contentView); + self.layoutGuide = + AddLayoutGuideToContentView(self.contentView, /*cell_has_header=*/YES); self.selectionStyle = UITableViewCellSelectionStyleNone; @@ -283,23 +292,13 @@ ]; self.siteNameLabel = CreateLabel(); - self.siteNameLabel.translatesAutoresizingMaskIntoConstraints = NO; - self.siteNameLabel.adjustsFontForContentSizeCategory = YES; - [self.contentView addSubview:self.siteNameLabel]; - - UIStackView* stackView = [[UIStackView alloc] - initWithArrangedSubviews:@[ self.faviconView, self.siteNameLabel ]]; - stackView.translatesAutoresizingMaskIntoConstraints = NO; - stackView.spacing = UIStackViewSpacingUseSystem; - stackView.alignment = UIStackViewAlignmentCenter; - - [self.contentView addSubview:stackView]; + self.headerView = CreateHeaderView(self.faviconView, self.siteNameLabel); + [self.contentView addSubview:self.headerView]; + AppendHorizontalConstraintsForViews(staticConstraints, @[ self.headerView ], + self.layoutGuide); self.grayLine = CreateGraySeparatorForContainer(self.contentView); - AppendHorizontalConstraintsForViews(staticConstraints, @[ stackView ], - self.layoutGuide); - self.usernameButton = CreateChipWithSelectorAndTarget( @selector(userDidTapUsernameButton:), self); [self.contentView addSubview:self.usernameButton];
diff --git a/ios/components/credential_provider_extension/password_spec_fetcher.mm b/ios/components/credential_provider_extension/password_spec_fetcher.mm index 5c4979bd..f7d3eef 100644 --- a/ios/components/credential_provider_extension/password_spec_fetcher.mm +++ b/ios/components/credential_provider_extension/password_spec_fetcher.mm
@@ -4,6 +4,8 @@ #import "ios/components/credential_provider_extension/password_spec_fetcher.h" +#import <string_view> + #import "base/base64.h" #import "components/autofill/core/browser/proto/password_requirements.pb.h" @@ -110,8 +112,8 @@ // Parse the proto and execute completion. std::string decoded; - const base::StringPiece encoded_bytes(static_cast<const char*>([data bytes]), - [data length]); + const std::string_view encoded_bytes(static_cast<const char*>([data bytes]), + [data length]); if (base::Base64Decode(encoded_bytes, &decoded)) { DomainSuggestions suggestions; suggestions.ParseFromString(decoded);
diff --git a/ios/third_party/earl_grey2/src b/ios/third_party/earl_grey2/src index a09fa0c..26acfe3 160000 --- a/ios/third_party/earl_grey2/src +++ b/ios/third_party/earl_grey2/src
@@ -1 +1 @@ -Subproject commit a09fa0c5cf18578d1985f3abffb599ecdc6fd514 +Subproject commit 26acfe36928095395dfcb6ff3d0578550bd868ac
diff --git a/ios/web/content/BUILD.gn b/ios/web/content/BUILD.gn index 6c22d4b7c..671d08f 100644 --- a/ios/web/content/BUILD.gn +++ b/ios/web/content/BUILD.gn
@@ -40,6 +40,7 @@ ":send_webkit_message_js", "//base", "//build:blink_buildflags", + "//components/embedder_support/ios:web_contents_delegate", "//components/js_injection/browser", "//content/public/browser", "//ios/web/annotations",
diff --git a/ios/web/content/DEPS b/ios/web/content/DEPS index 0c9a24c..bc8eceb 100644 --- a/ios/web/content/DEPS +++ b/ios/web/content/DEPS
@@ -5,6 +5,7 @@ ] specific_include_rules = { "content_web_state\.mm": [ + "+components/embedder_support/ios/delegate/color_chooser/color_chooser_ios.h", "+third_party/blink/public/mojom/favicon/favicon_url.mojom.h", "+skia/ext/skia_utils_ios.h", ],
diff --git a/ios/web/content/web_state/content_web_state.h b/ios/web/content/web_state/content_web_state.h index 340aa9d..c6156455 100644 --- a/ios/web/content/web_state/content_web_state.h +++ b/ios/web/content/web_state/content_web_state.h
@@ -200,6 +200,11 @@ int GetVirtualKeyboardHeight(content::WebContents* web_contents) override; bool OnlyExpandTopControlsAtPageTop() override; void SetTopControlsGestureScrollInProgress(bool in_progress) override; + std::unique_ptr<content::ColorChooser> OpenColorChooser( + content::WebContents* web_contents, + SkColor color, + const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions) + override; private: // Helper method to register notification observers.
diff --git a/ios/web/content/web_state/content_web_state.mm b/ios/web/content/web_state/content_web_state.mm index a49e97d4..0558d77 100644 --- a/ios/web/content/web_state/content_web_state.mm +++ b/ios/web/content/web_state/content_web_state.mm
@@ -6,6 +6,7 @@ #import "base/apple/foundation_util.h" #import "base/strings/utf_string_conversions.h" +#import "components/embedder_support/ios/delegate/color_chooser/color_chooser_ios.h" #import "content/public/browser/navigation_entry.h" #import "content/public/browser/web_contents.h" #import "ios/web/content/content_browser_context.h" @@ -740,4 +741,12 @@ keyboard_height_ = 0; } +std::unique_ptr<content::ColorChooser> ContentWebState::OpenColorChooser( + content::WebContents* web_contents, + SkColor color, + const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions) { + return std::make_unique<web_contents_delegate_ios::ColorChooserIOS>( + web_contents, color, suggestions); +} + } // namespace web
diff --git a/ios_internal b/ios_internal index 8af50d3..4e9a9e1 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit 8af50d3b84698254f56ba6ffd69171a2abce3e12 +Subproject commit 4e9a9e1ff027107175ef685b140354acc5bfc1a9
diff --git a/media/gpu/test/BUILD.gn b/media/gpu/test/BUILD.gn index be069b4..25a62934 100644 --- a/media/gpu/test/BUILD.gn +++ b/media/gpu/test/BUILD.gn
@@ -67,6 +67,7 @@ "//media/gpu:buildflags", "//media/gpu:common", "//testing/gtest", + "//ui/gl:test_support", ] }
diff --git a/media/gpu/test/video_encode_accelerator_tests.cc b/media/gpu/test/video_encode_accelerator_tests.cc index b74949e..0116a97 100644 --- a/media/gpu/test/video_encode_accelerator_tests.cc +++ b/media/gpu/test/video_encode_accelerator_tests.cc
@@ -26,11 +26,14 @@ #include "media/gpu/test/video_encoder/video_encoder_client.h" #include "media/gpu/test/video_encoder/video_encoder_test_environment.h" #include "media/gpu/test/video_frame_file_writer.h" -#include "media/gpu/test/video_frame_helpers.h" #include "media/gpu/test/video_frame_validator.h" #include "media/gpu/test/video_test_environment.h" #include "media/gpu/test/video_test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/gl/gl_surface.h" +#include "ui/gl/init/gl_factory.h" +#include "ui/gl/test/gl_surface_test_support.h" +#include "ui/gl/test/gl_test_support.h" namespace media { namespace test { @@ -966,5 +969,9 @@ media::test::g_env = static_cast<media::test::VideoEncoderTestEnvironment*>( testing::AddGlobalTestEnvironment(test_environment)); + raw_ptr<gl::GLDisplay> display = + gl::GLTestSupport::InitializeGL(std::nullopt); + gl::init::CreateOffscreenGLSurface(display, gfx::Size()); + return RUN_ALL_TESTS(); }
diff --git a/services/on_device_model/BUILD.gn b/services/on_device_model/BUILD.gn index b6da248..63280d2 100644 --- a/services/on_device_model/BUILD.gn +++ b/services/on_device_model/BUILD.gn
@@ -56,7 +56,7 @@ if (is_linux || is_chromeos) { deps += [ "//gpu/config", - "//third_party/dawn/src/dawn:cpp", + "//third_party/dawn/include/dawn:cpp_headers", "//third_party/dawn/src/dawn:proc", "//third_party/dawn/src/dawn/native", ]
diff --git a/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom b/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom index b8792901..52dc686 100644 --- a/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom +++ b/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom
@@ -20,7 +20,9 @@ import "services/viz/public/mojom/compositing/surface_id.mojom"; import "services/viz/public/mojom/compositing/surface_info.mojom"; import "services/viz/public/mojom/hit_test/aggregated_hit_test_region.mojom"; +import "services/viz/public/mojom/compositing/copy_output_result.mojom"; import "services/viz/public/mojom/compositing/video_detector_observer.mojom"; +import "third_party/blink/public/mojom/tokens/tokens.mojom"; // Initialization parameters for a RootCompositorFrameSink. struct RootCompositorFrameSinkParams { @@ -246,4 +248,15 @@ [EnableIf=is_android] VerifyThreadIdsDoNotBelongToHost(array<int32> thread_ids) => (bool passed_verification); + + // Allows the GPU process to send the result of a screenshot back to the host + // process. The host stores the screenshot to the destination specified by + // `destination_token`. + // + // This is used to copy a screenshot after same-document navigation committed + // in the renderer process. + OnScreenshotCaptured( + blink.mojom.SameDocNavigationScreenshotDestinationToken destination_token, + CopyOutputResult copy_output_result + ); };
diff --git a/skia/BUILD.gn b/skia/BUILD.gn index 16d475dc..ee2049b 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn
@@ -840,7 +840,6 @@ public += skia_graphite_dawn_public public_deps = [ "//third_party/dawn/include/dawn:cpp_headers", - "//third_party/dawn/src/dawn:cpp", "//third_party/dawn/src/dawn:proc", ] }
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index a85482c..d54abfc 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -598,8 +598,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "android_webview_junit_tests", - "test_id_prefix": "ninja://android_webview/test:android_webview_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://android_webview/test:android_webview_junit_tests/" }, { "merge": { @@ -616,8 +615,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "base_junit_tests", - "test_id_prefix": "ninja://base:base_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://base:base_junit_tests/" }, { "merge": { @@ -634,8 +632,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "build_junit_tests", - "test_id_prefix": "ninja://build/android:build_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://build/android:build_junit_tests/" }, { "merge": { @@ -652,8 +649,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "chrome_java_test_pagecontroller_junit_tests", - "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_junit_tests/" }, { "merge": { @@ -670,8 +666,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "chrome_junit_tests", - "test_id_prefix": "ninja://chrome/android:chrome_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android:chrome_junit_tests/" }, { "merge": { @@ -688,8 +683,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "components_junit_tests", - "test_id_prefix": "ninja://components:components_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components:components_junit_tests/" }, { "merge": { @@ -706,8 +700,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "content_junit_tests", - "test_id_prefix": "ninja://content/public/android:content_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://content/public/android:content_junit_tests/" }, { "merge": { @@ -724,8 +717,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "device_junit_tests", - "test_id_prefix": "ninja://device:device_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://device:device_junit_tests/" }, { "merge": { @@ -742,8 +734,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "junit_unit_tests", - "test_id_prefix": "ninja://testing/android/junit:junit_unit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://testing/android/junit:junit_unit_tests/" }, { "merge": { @@ -760,8 +751,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "keyboard_accessory_junit_tests", - "test_id_prefix": "ninja://chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests/" }, { "merge": { @@ -778,8 +768,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "media_base_junit_tests", - "test_id_prefix": "ninja://media/base/android:media_base_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://media/base/android:media_base_junit_tests/" }, { "merge": { @@ -796,8 +785,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "module_installer_junit_tests", - "test_id_prefix": "ninja://components/module_installer/android:module_installer_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components/module_installer/android:module_installer_junit_tests/" }, { "merge": { @@ -814,8 +802,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "net_junit_tests", - "test_id_prefix": "ninja://net/android:net_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://net/android:net_junit_tests/" }, { "merge": { @@ -832,8 +819,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "paint_preview_junit_tests", - "test_id_prefix": "ninja://components/paint_preview/player/android:paint_preview_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components/paint_preview/player/android:paint_preview_junit_tests/" }, { "merge": { @@ -850,8 +836,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "password_check_junit_tests", - "test_id_prefix": "ninja://chrome/browser/password_check/android:password_check_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/password_check/android:password_check_junit_tests/" }, { "merge": { @@ -868,8 +853,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "password_manager_junit_tests", - "test_id_prefix": "ninja://chrome/browser/password_manager/android:password_manager_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/password_manager/android:password_manager_junit_tests/" }, { "merge": { @@ -886,8 +870,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "services_junit_tests", - "test_id_prefix": "ninja://services:services_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://services:services_junit_tests/" }, { "merge": { @@ -904,8 +887,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "touch_to_fill_junit_tests", - "test_id_prefix": "ninja://chrome/browser/touch_to_fill/password_manager/android:touch_to_fill_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/touch_to_fill/password_manager/android:touch_to_fill_junit_tests/" }, { "merge": { @@ -922,8 +904,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "ui_junit_tests", - "test_id_prefix": "ninja://ui:ui_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://ui:ui_junit_tests/" }, { "merge": { @@ -940,8 +921,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_client_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/libs/client:webapk_client_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/libs/client:webapk_client_junit_tests/" }, { "merge": { @@ -958,8 +938,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_shell_apk_h2o_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_h2o_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_h2o_junit_tests/" }, { "merge": { @@ -976,8 +955,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_shell_apk_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_junit_tests/" } ] }, @@ -19807,8 +19785,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "android_webview_junit_tests", - "test_id_prefix": "ninja://android_webview/test:android_webview_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://android_webview/test:android_webview_junit_tests/" }, { "merge": { @@ -19829,8 +19806,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "base_junit_tests", - "test_id_prefix": "ninja://base:base_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://base:base_junit_tests/" }, { "merge": { @@ -19851,8 +19827,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "build_junit_tests", - "test_id_prefix": "ninja://build/android:build_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://build/android:build_junit_tests/" }, { "merge": { @@ -19873,8 +19848,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "chrome_java_test_pagecontroller_junit_tests", - "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_junit_tests/" }, { "merge": { @@ -19895,8 +19869,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "chrome_junit_tests", - "test_id_prefix": "ninja://chrome/android:chrome_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android:chrome_junit_tests/" }, { "merge": { @@ -19917,8 +19890,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "components_junit_tests", - "test_id_prefix": "ninja://components:components_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components:components_junit_tests/" }, { "merge": { @@ -19939,8 +19911,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "content_junit_tests", - "test_id_prefix": "ninja://content/public/android:content_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://content/public/android:content_junit_tests/" }, { "merge": { @@ -19961,8 +19932,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "device_junit_tests", - "test_id_prefix": "ninja://device:device_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://device:device_junit_tests/" }, { "merge": { @@ -19983,8 +19953,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "junit_unit_tests", - "test_id_prefix": "ninja://testing/android/junit:junit_unit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://testing/android/junit:junit_unit_tests/" }, { "merge": { @@ -20005,8 +19974,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "keyboard_accessory_junit_tests", - "test_id_prefix": "ninja://chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests/" }, { "merge": { @@ -20027,8 +19995,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "media_base_junit_tests", - "test_id_prefix": "ninja://media/base/android:media_base_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://media/base/android:media_base_junit_tests/" }, { "merge": { @@ -20049,8 +20016,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "module_installer_junit_tests", - "test_id_prefix": "ninja://components/module_installer/android:module_installer_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components/module_installer/android:module_installer_junit_tests/" }, { "merge": { @@ -20071,8 +20037,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "net_junit_tests", - "test_id_prefix": "ninja://net/android:net_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://net/android:net_junit_tests/" }, { "merge": { @@ -20093,8 +20058,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "paint_preview_junit_tests", - "test_id_prefix": "ninja://components/paint_preview/player/android:paint_preview_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components/paint_preview/player/android:paint_preview_junit_tests/" }, { "merge": { @@ -20115,8 +20079,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "password_check_junit_tests", - "test_id_prefix": "ninja://chrome/browser/password_check/android:password_check_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/password_check/android:password_check_junit_tests/" }, { "merge": { @@ -20137,8 +20100,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "password_manager_junit_tests", - "test_id_prefix": "ninja://chrome/browser/password_manager/android:password_manager_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/password_manager/android:password_manager_junit_tests/" }, { "merge": { @@ -20159,8 +20121,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "services_junit_tests", - "test_id_prefix": "ninja://services:services_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://services:services_junit_tests/" }, { "merge": { @@ -20181,8 +20142,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "touch_to_fill_junit_tests", - "test_id_prefix": "ninja://chrome/browser/touch_to_fill/password_manager/android:touch_to_fill_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/touch_to_fill/password_manager/android:touch_to_fill_junit_tests/" }, { "merge": { @@ -20203,8 +20163,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "ui_junit_tests", - "test_id_prefix": "ninja://ui:ui_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://ui:ui_junit_tests/" }, { "merge": { @@ -20225,8 +20184,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_client_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/libs/client:webapk_client_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/libs/client:webapk_client_junit_tests/" }, { "merge": { @@ -20247,8 +20205,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_shell_apk_h2o_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_h2o_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_h2o_junit_tests/" }, { "merge": { @@ -20269,8 +20226,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_shell_apk_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_junit_tests/" } ] }, @@ -28195,8 +28151,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "android_webview_junit_tests", - "test_id_prefix": "ninja://android_webview/test:android_webview_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://android_webview/test:android_webview_junit_tests/" }, { "args": [ @@ -28221,8 +28176,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "base_junit_tests", - "test_id_prefix": "ninja://base:base_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://base:base_junit_tests/" }, { "args": [ @@ -28247,8 +28201,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "build_junit_tests", - "test_id_prefix": "ninja://build/android:build_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://build/android:build_junit_tests/" }, { "args": [ @@ -28273,8 +28226,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "chrome_java_test_pagecontroller_junit_tests", - "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_junit_tests/" }, { "args": [ @@ -28299,8 +28251,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "chrome_junit_tests", - "test_id_prefix": "ninja://chrome/android:chrome_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android:chrome_junit_tests/" }, { "args": [ @@ -28325,8 +28276,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "components_junit_tests", - "test_id_prefix": "ninja://components:components_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components:components_junit_tests/" }, { "args": [ @@ -28394,8 +28344,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "content_junit_tests", - "test_id_prefix": "ninja://content/public/android:content_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://content/public/android:content_junit_tests/" }, { "args": [ @@ -28420,8 +28369,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "device_junit_tests", - "test_id_prefix": "ninja://device:device_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://device:device_junit_tests/" }, { "args": [ @@ -28446,8 +28394,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "junit_unit_tests", - "test_id_prefix": "ninja://testing/android/junit:junit_unit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://testing/android/junit:junit_unit_tests/" }, { "args": [ @@ -28472,8 +28419,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "keyboard_accessory_junit_tests", - "test_id_prefix": "ninja://chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests/" }, { "args": [ @@ -28498,8 +28444,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "media_base_junit_tests", - "test_id_prefix": "ninja://media/base/android:media_base_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://media/base/android:media_base_junit_tests/" }, { "args": [ @@ -28524,8 +28469,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "module_installer_junit_tests", - "test_id_prefix": "ninja://components/module_installer/android:module_installer_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components/module_installer/android:module_installer_junit_tests/" }, { "args": [ @@ -28591,8 +28535,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "net_junit_tests", - "test_id_prefix": "ninja://net/android:net_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://net/android:net_junit_tests/" }, { "args": [ @@ -28617,8 +28560,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "paint_preview_junit_tests", - "test_id_prefix": "ninja://components/paint_preview/player/android:paint_preview_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components/paint_preview/player/android:paint_preview_junit_tests/" }, { "args": [ @@ -28643,8 +28585,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "password_check_junit_tests", - "test_id_prefix": "ninja://chrome/browser/password_check/android:password_check_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/password_check/android:password_check_junit_tests/" }, { "args": [ @@ -28669,8 +28610,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "password_manager_junit_tests", - "test_id_prefix": "ninja://chrome/browser/password_manager/android:password_manager_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/password_manager/android:password_manager_junit_tests/" }, { "args": [ @@ -28695,8 +28635,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "services_junit_tests", - "test_id_prefix": "ninja://services:services_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://services:services_junit_tests/" }, { "args": [ @@ -28855,8 +28794,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "touch_to_fill_junit_tests", - "test_id_prefix": "ninja://chrome/browser/touch_to_fill/password_manager/android:touch_to_fill_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/touch_to_fill/password_manager/android:touch_to_fill_junit_tests/" }, { "args": [ @@ -28881,8 +28819,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "ui_junit_tests", - "test_id_prefix": "ninja://ui:ui_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://ui:ui_junit_tests/" }, { "args": [ @@ -28907,8 +28844,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_client_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/libs/client:webapk_client_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/libs/client:webapk_client_junit_tests/" }, { "args": [ @@ -28933,8 +28869,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_shell_apk_h2o_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_h2o_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_h2o_junit_tests/" }, { "args": [ @@ -28959,8 +28894,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_shell_apk_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_junit_tests/" } ], "scripts": [
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index ac89f65..9ab3ee3 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -339,8 +339,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "android_webview_junit_tests", - "test_id_prefix": "ninja://android_webview/test:android_webview_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://android_webview/test:android_webview_junit_tests/" }, { "isolate_profile_data": true, @@ -362,8 +361,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "base_junit_tests", - "test_id_prefix": "ninja://base:base_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://base:base_junit_tests/" }, { "isolate_profile_data": true, @@ -385,8 +383,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "build_junit_tests", - "test_id_prefix": "ninja://build/android:build_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://build/android:build_junit_tests/" }, { "isolate_profile_data": true, @@ -408,8 +405,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "chrome_java_test_pagecontroller_junit_tests", - "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_junit_tests/" }, { "isolate_profile_data": true, @@ -431,8 +427,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "chrome_junit_tests", - "test_id_prefix": "ninja://chrome/android:chrome_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android:chrome_junit_tests/" }, { "isolate_profile_data": true, @@ -454,8 +449,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "components_junit_tests", - "test_id_prefix": "ninja://components:components_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components:components_junit_tests/" }, { "isolate_profile_data": true, @@ -477,8 +471,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "content_junit_tests", - "test_id_prefix": "ninja://content/public/android:content_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://content/public/android:content_junit_tests/" }, { "isolate_profile_data": true, @@ -500,8 +493,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "device_junit_tests", - "test_id_prefix": "ninja://device:device_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://device:device_junit_tests/" }, { "isolate_profile_data": true, @@ -523,8 +515,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "junit_unit_tests", - "test_id_prefix": "ninja://testing/android/junit:junit_unit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://testing/android/junit:junit_unit_tests/" }, { "isolate_profile_data": true, @@ -546,8 +537,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "keyboard_accessory_junit_tests", - "test_id_prefix": "ninja://chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests/" }, { "isolate_profile_data": true, @@ -569,8 +559,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "media_base_junit_tests", - "test_id_prefix": "ninja://media/base/android:media_base_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://media/base/android:media_base_junit_tests/" }, { "isolate_profile_data": true, @@ -592,8 +581,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "module_installer_junit_tests", - "test_id_prefix": "ninja://components/module_installer/android:module_installer_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components/module_installer/android:module_installer_junit_tests/" }, { "isolate_profile_data": true, @@ -615,8 +603,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "net_junit_tests", - "test_id_prefix": "ninja://net/android:net_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://net/android:net_junit_tests/" }, { "isolate_profile_data": true, @@ -638,8 +625,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "paint_preview_junit_tests", - "test_id_prefix": "ninja://components/paint_preview/player/android:paint_preview_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components/paint_preview/player/android:paint_preview_junit_tests/" }, { "isolate_profile_data": true, @@ -661,8 +647,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "password_check_junit_tests", - "test_id_prefix": "ninja://chrome/browser/password_check/android:password_check_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/password_check/android:password_check_junit_tests/" }, { "isolate_profile_data": true, @@ -684,8 +669,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "password_manager_junit_tests", - "test_id_prefix": "ninja://chrome/browser/password_manager/android:password_manager_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/password_manager/android:password_manager_junit_tests/" }, { "isolate_profile_data": true, @@ -707,8 +691,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "services_junit_tests", - "test_id_prefix": "ninja://services:services_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://services:services_junit_tests/" }, { "isolate_profile_data": true, @@ -730,8 +713,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "touch_to_fill_junit_tests", - "test_id_prefix": "ninja://chrome/browser/touch_to_fill/password_manager/android:touch_to_fill_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/touch_to_fill/password_manager/android:touch_to_fill_junit_tests/" }, { "isolate_profile_data": true, @@ -753,8 +735,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "ui_junit_tests", - "test_id_prefix": "ninja://ui:ui_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://ui:ui_junit_tests/" }, { "isolate_profile_data": true, @@ -776,8 +757,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_client_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/libs/client:webapk_client_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/libs/client:webapk_client_junit_tests/" }, { "isolate_profile_data": true, @@ -799,8 +779,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_shell_apk_h2o_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_h2o_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_h2o_junit_tests/" }, { "isolate_profile_data": true, @@ -822,8 +801,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_shell_apk_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_junit_tests/" } ] }, @@ -6697,8 +6675,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "android_webview_junit_tests", - "test_id_prefix": "ninja://android_webview/test:android_webview_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://android_webview/test:android_webview_junit_tests/" }, { "args": [ @@ -6723,8 +6700,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "base_junit_tests", - "test_id_prefix": "ninja://base:base_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://base:base_junit_tests/" }, { "args": [ @@ -6749,8 +6725,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "build_junit_tests", - "test_id_prefix": "ninja://build/android:build_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://build/android:build_junit_tests/" }, { "args": [ @@ -6775,8 +6750,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "chrome_java_test_pagecontroller_junit_tests", - "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_junit_tests/" }, { "args": [ @@ -6801,8 +6775,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "chrome_junit_tests", - "test_id_prefix": "ninja://chrome/android:chrome_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android:chrome_junit_tests/" }, { "args": [ @@ -6827,8 +6800,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "components_junit_tests", - "test_id_prefix": "ninja://components:components_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components:components_junit_tests/" }, { "args": [ @@ -6896,8 +6868,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "content_junit_tests", - "test_id_prefix": "ninja://content/public/android:content_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://content/public/android:content_junit_tests/" }, { "args": [ @@ -6922,8 +6893,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "device_junit_tests", - "test_id_prefix": "ninja://device:device_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://device:device_junit_tests/" }, { "args": [ @@ -6948,8 +6918,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "junit_unit_tests", - "test_id_prefix": "ninja://testing/android/junit:junit_unit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://testing/android/junit:junit_unit_tests/" }, { "args": [ @@ -6974,8 +6943,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "keyboard_accessory_junit_tests", - "test_id_prefix": "ninja://chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests/" }, { "args": [ @@ -7000,8 +6968,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "media_base_junit_tests", - "test_id_prefix": "ninja://media/base/android:media_base_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://media/base/android:media_base_junit_tests/" }, { "args": [ @@ -7026,8 +6993,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "module_installer_junit_tests", - "test_id_prefix": "ninja://components/module_installer/android:module_installer_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components/module_installer/android:module_installer_junit_tests/" }, { "args": [ @@ -7093,8 +7059,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "net_junit_tests", - "test_id_prefix": "ninja://net/android:net_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://net/android:net_junit_tests/" }, { "args": [ @@ -7119,8 +7084,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "paint_preview_junit_tests", - "test_id_prefix": "ninja://components/paint_preview/player/android:paint_preview_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://components/paint_preview/player/android:paint_preview_junit_tests/" }, { "args": [ @@ -7145,8 +7109,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "password_check_junit_tests", - "test_id_prefix": "ninja://chrome/browser/password_check/android:password_check_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/password_check/android:password_check_junit_tests/" }, { "args": [ @@ -7171,8 +7134,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "password_manager_junit_tests", - "test_id_prefix": "ninja://chrome/browser/password_manager/android:password_manager_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/password_manager/android:password_manager_junit_tests/" }, { "args": [ @@ -7197,8 +7159,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "services_junit_tests", - "test_id_prefix": "ninja://services:services_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://services:services_junit_tests/" }, { "args": [ @@ -7357,8 +7318,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "touch_to_fill_junit_tests", - "test_id_prefix": "ninja://chrome/browser/touch_to_fill/password_manager/android:touch_to_fill_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/browser/touch_to_fill/password_manager/android:touch_to_fill_junit_tests/" }, { "args": [ @@ -7383,8 +7343,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "ui_junit_tests", - "test_id_prefix": "ninja://ui:ui_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://ui:ui_junit_tests/" }, { "args": [ @@ -7409,8 +7368,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_client_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/libs/client:webapk_client_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/libs/client:webapk_client_junit_tests/" }, { "args": [ @@ -7435,8 +7393,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_shell_apk_h2o_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_h2o_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_h2o_junit_tests/" }, { "args": [ @@ -7461,8 +7418,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "webapk_shell_apk_junit_tests", - "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_junit_tests/", - "use_isolated_scripts_api": true + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_junit_tests/" } ], "scripts": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index e0588a6..c6f7c67 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -47891,21 +47891,13 @@ "test_id_prefix": "ninja://:chrome_wpt_tests/" }, { - "args": [ - "--test-type", - "testharness", - "reftest", - "crashtest", - "print-reftest", - "--additional-driver-flag=--headless=old" - ], "merge": { "args": [ "--verbose" ], "script": "//third_party/blink/tools/merge_web_test_results.py" }, - "name": "chrome_wpt_tests_old_headless", + "name": "headless_shell_wpt_tests", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -47915,10 +47907,11 @@ "dimensions": { "os": "Ubuntu-22.04" }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 10 }, - "test": "chrome_wpt_tests", - "test_id_prefix": "ninja://:chrome_wpt_tests/" + "test": "headless_shell_wpt", + "test_id_prefix": "ninja://:headless_shell_wpt/" } ] },
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index e7685cd..77d5e27 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -905,6 +905,14 @@ "label": "//headless:headless_browsertests", "type": "console_test_launcher", }, + "headless_shell_wpt": { + "label": "//:headless_shell_wpt", + "type": "generated_script", + "args": [ + "--results-directory", + "${ISOLATED_OUTDIR}", + ], + }, "headless_unittests": { "label": "//headless:headless_unittests", "type": "console_test_launcher",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 725c435..2f2279e 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -1041,7 +1041,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'base_junit_tests': { 'mixins': [ @@ -1056,7 +1055,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'build_junit_tests': { 'mixins': [ @@ -1071,7 +1069,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'chrome_java_test_pagecontroller_junit_tests': { 'mixins': [ @@ -1086,7 +1083,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'chrome_junit_tests': { 'mixins': [ @@ -1101,7 +1097,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'components_junit_tests': { 'mixins': [ @@ -1116,7 +1111,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'content_junit_tests': { 'mixins': [ @@ -1131,7 +1125,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'device_junit_tests': { 'mixins': [ @@ -1146,7 +1139,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'junit_unit_tests': { 'mixins': [ @@ -1161,7 +1153,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'keyboard_accessory_junit_tests': { 'mixins': [ @@ -1176,7 +1167,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'media_base_junit_tests': { 'mixins': [ @@ -1191,7 +1181,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'module_installer_junit_tests': { 'mixins': [ @@ -1206,7 +1195,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'net_junit_tests': { 'mixins': [ @@ -1221,7 +1209,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'paint_preview_junit_tests': { 'mixins': [ @@ -1236,7 +1223,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'password_check_junit_tests': { 'mixins': [ @@ -1251,7 +1237,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'password_manager_junit_tests': { 'mixins': [ @@ -1266,7 +1251,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'services_junit_tests': { 'mixins': [ @@ -1281,7 +1265,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'touch_to_fill_junit_tests': { 'mixins': [ @@ -1296,7 +1279,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'ui_junit_tests': { 'mixins': [ @@ -1311,7 +1293,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'webapk_client_junit_tests': { 'mixins': [ @@ -1326,7 +1307,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'webapk_shell_apk_h2o_junit_tests': { 'mixins': [ @@ -1341,7 +1321,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, 'webapk_shell_apk_junit_tests': { 'mixins': [ @@ -1356,7 +1335,6 @@ 'walleye', 'pie_fleet', ], - 'use_isolated_scripts_api': True, }, }, @@ -1649,33 +1627,6 @@ }, }, - 'chromium_wpt_tests_old_headless_isolated_scripts': { - 'chrome_wpt_tests_old_headless': { - 'test': 'chrome_wpt_tests', - 'results_handler': 'layout tests', - 'mixins': [ - 'has_native_resultdb_integration', - ], - 'args': [ - '--test-type', - 'testharness', - 'reftest', - 'crashtest', - 'print-reftest', - '--additional-driver-flag=--headless=old', - ], - 'swarming': { - 'shards': 1, - }, - 'merge': { - 'script': '//third_party/blink/tools/merge_web_test_results.py', - 'args': [ - '--verbose', - ], - }, - }, - }, - 'clang_tot_gtests': { 'base_unittests': {}, }, @@ -4118,6 +4069,25 @@ 'headless_unittests': {}, }, + 'headless_shell_wpt_tests_isolated_scripts': { + 'headless_shell_wpt_tests': { + 'test': 'headless_shell_wpt', + 'results_handler': 'layout tests', + 'mixins': [ + 'has_native_resultdb_integration', + ], + 'swarming': { + 'shards': 10, + }, + 'merge': { + 'script': '//third_party/blink/tools/merge_web_test_results.py', + 'args': [ + '--verbose', + ], + }, + }, + }, + 'ios_blink_tests': { 'absl_hardening_tests': {}, 'angle_unittests': { @@ -6042,7 +6012,7 @@ 'chrome_wpt_tests_three_modes': [ 'chromium_wpt_tests_headful_isolated_scripts', 'chromium_wpt_tests_isolated_scripts', - 'chromium_wpt_tests_old_headless_isolated_scripts', + 'headless_shell_wpt_tests_isolated_scripts', ], 'chromeos_device_no_gtests': [
diff --git a/testing/libfuzzer/fuzzers/BUILD.gn b/testing/libfuzzer/fuzzers/BUILD.gn index 494dcf5..4d653bf 100644 --- a/testing/libfuzzer/fuzzers/BUILD.gn +++ b/testing/libfuzzer/fuzzers/BUILD.gn
@@ -513,7 +513,7 @@ if (use_dawn) { deps += [ - "//third_party/dawn/src/dawn:cpp", + "//third_party/dawn/include/dawn:cpp_headers", "//third_party/dawn/src/dawn:proc", "//third_party/dawn/src/dawn/native", ]
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 248f520..43446172 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -5272,21 +5272,6 @@ ] } ], - "CreateNewTabInitializeRenderer": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled_Nonstable_20230609", - "enable_features": [ - "CreateNewTabInitializeRenderer" - ] - } - ] - } - ], "CreateNotificationsAcceptedClientSafeBrowsingReports": [ { "platforms": [ @@ -5366,21 +5351,6 @@ ] } ], - "CrosDeviceActiveClientChurnObservationNewDeviceMetadata": [ - { - "platforms": [ - "chromeos" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "DeviceActiveClientChurnObservationNewDeviceMetadata" - ] - } - ] - } - ], "CrosLazyLoginWebUI": [ { "platforms": [ @@ -16481,22 +16451,6 @@ "SafeBrowsingHashPrefixRealTimeLookups": [ { "platforms": [ - "ios" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "SafeBrowsingHashPrefixRealTimeLookupsRelayUrl": "https://google-ohttp-relay-safebrowsing.fastly-edge.com/" - }, - "enable_features": [ - "SafeBrowsingHashPrefixRealTimeLookups" - ] - } - ] - }, - { - "platforms": [ "android" ], "experiments": [ @@ -18421,7 +18375,8 @@ "SkiaGraphite": [ { "platforms": [ - "mac" + "mac", + "windows" ], "experiments": [ {
diff --git a/third_party/angle b/third_party/angle index 313c73c..d71b8ee 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 313c73c3f6a056a049c03c4f928ab5d83f17a77a +Subproject commit d71b8ee0f0e26b14a8fa642460df2635c2d7db2f
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_object_builder.cc b/third_party/blink/renderer/bindings/core/v8/v8_object_builder.cc index 73279ca5..c3dc0e7 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_object_builder.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_object_builder.cc
@@ -36,6 +36,16 @@ return *this; } +V8ObjectBuilder& V8ObjectBuilder::AddNumberOrNull(const StringView& name, + std::optional<double> value) { + if (value.has_value()) { + AddInternal(name, v8::Number::New(script_state_->GetIsolate(), *value)); + } else { + AddInternal(name, v8::Null(script_state_->GetIsolate())); + } + return *this; +} + V8ObjectBuilder& V8ObjectBuilder::AddInteger(const StringView& name, uint64_t value) { AddInternal(name,
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_object_builder.h b/third_party/blink/renderer/bindings/core/v8/v8_object_builder.h index 06f469c..6a75f186 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_object_builder.h +++ b/third_party/blink/renderer/bindings/core/v8/v8_object_builder.h
@@ -29,6 +29,8 @@ V8ObjectBuilder& AddNull(const StringView& name); V8ObjectBuilder& AddBoolean(const StringView& name, bool value); V8ObjectBuilder& AddNumber(const StringView& name, double value); + V8ObjectBuilder& AddNumberOrNull(const StringView& name, + std::optional<double> value); V8ObjectBuilder& AddInteger(const StringView& name, uint64_t value); V8ObjectBuilder& AddString(const StringView& name, const StringView& value); V8ObjectBuilder& AddStringOrNull(const StringView& name,
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc b/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc index 8b64483..0d8f584 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc
@@ -161,7 +161,7 @@ resource->SetSerializedCachedMetadata(serialized_metadata); } StringUTF8Adaptor code_utf8(code.value()); - resource->AppendData(code_utf8.data(), code_utf8.size()); + resource->AppendData(code_utf8); resource->FinishForTest(); return resource;
diff --git a/third_party/blink/renderer/core/html/image_document.cc b/third_party/blink/renderer/core/html/image_document.cc index e392e02..a213c1db 100644 --- a/third_party/blink/renderer/core/html/image_document.cc +++ b/third_party/blink/renderer/core/html/image_document.cc
@@ -26,6 +26,8 @@ #include <limits> +#include "base/compiler_specific.h" +#include "base/containers/span.h" #include "third_party/blink/public/platform/web_content_settings_client.h" #include "third_party/blink/renderer/core/css/css_color.h" #include "third_party/blink/renderer/core/dom/events/native_event_listener.h" @@ -165,8 +167,12 @@ CHECK_LE(length, std::numeric_limits<unsigned>::max()); // If decoding has already failed, there's no point in sending additional // data to the ImageResource. - if (image_resource_->GetStatus() != ResourceStatus::kDecodeError) - image_resource_->AppendData(data, length); + if (image_resource_->GetStatus() != ResourceStatus::kDecodeError) { + image_resource_->AppendData( + // SAFETY: The caller must ensure `data` points to `length` bytes. + // TODO(crbug.com/40284755): Spanify this method. + UNSAFE_BUFFERS(base::span(data, length))); + } if (!IsDetached()) GetDocument()->ImageUpdated();
diff --git a/third_party/blink/renderer/core/layout/inline/inline_node_test.cc b/third_party/blink/renderer/core/layout/inline/inline_node_test.cc index fe18fcfd..c620f4b 100644 --- a/third_party/blink/renderer/core/layout/inline/inline_node_test.cc +++ b/third_party/blink/renderer/core/layout/inline/inline_node_test.cc
@@ -520,10 +520,13 @@ {"Hello <img>.", {50, 80}, "", "img { width: 1em; }"}, {"Hello <img>.", {50, 120}, "", "img { width: 5em; }"}, {"Hello <img>.", {60, 130}, "", "img { width: 6em; }"}, - // `text-indent. + // `text-indent`. {"6 12345 12", {60, 150}, "text-indent: 5em"}, {"6 1234567 12", {70, 170}, "text-indent: 5em"}, - // Negative `text-indent. + // `text-indent` with hyphenations. + // The "hy-" with the indent should be longest. + {"hyphenation a", {60, 160}, "hyphens: auto; text-indent: 3em", "", "en"}, + // Negative `text-indent`. {"43210123 1234 12", {40, 110}, "text-indent: -5em"}, {"4321012345 1234 12", {50, 130}, "text-indent: -5em"}, {"432 012 1", {30, 40}, "text-indent: -5em"},
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource.cc b/third_party/blink/renderer/core/loader/resource/image_resource.cc index cf594f1..b630b71a3 100644 --- a/third_party/blink/renderer/core/loader/resource/image_resource.cc +++ b/third_party/blink/renderer/core/loader/resource/image_resource.cc
@@ -28,6 +28,7 @@ #include <memory> #include <utility> +#include "base/compiler_specific.h" #include "base/metrics/histogram_macros.h" #include "base/numerics/safe_conversions.h" #include "base/task/single_thread_task_runner.h" @@ -332,12 +333,13 @@ return GetContent()->ResourceBuffer(); } -void ImageResource::AppendData(const char* data, size_t length) { - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(length); +void ImageResource::AppendData(base::span<const char> data) { + v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(data.size()); if (multipart_parser_) { - multipart_parser_->AppendData(data, base::checked_cast<wtf_size_t>(length)); + multipart_parser_->AppendData(data.data(), + base::checked_cast<wtf_size_t>(data.size())); } else { - Resource::AppendData(data, length); + Resource::AppendData(data); // Update the image immediately if needed. // @@ -514,7 +516,11 @@ void ImageResource::MultipartDataReceived(const char* bytes, size_t size) { DCHECK(multipart_parser_); - Resource::AppendData(bytes, size); + Resource::AppendData( + // SAFETY: The caller must ensure `bytes` points to `size` elements. + // TODO(crbug.com/40284755): Make this method take a span to capture the + // invariant. + UNSAFE_BUFFERS(base::span(bytes, size))); } bool ImageResource::IsAccessAllowed(
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource.h b/third_party/blink/renderer/core/loader/resource/image_resource.h index 26e534e69..d47f91c 100644 --- a/third_party/blink/renderer/core/loader/resource/image_resource.h +++ b/third_party/blink/renderer/core/loader/resource/image_resource.h
@@ -85,7 +85,7 @@ scoped_refptr<const SharedBuffer> ResourceBuffer() const override; void NotifyStartLoad() override; void ResponseReceived(const ResourceResponse&) override; - void AppendData(const char*, size_t) override; + void AppendData(base::span<const char>) override; void Finish(base::TimeTicks finish_time, base::SingleThreadTaskRunner*) override; void FinishAsError(const ResourceError&,
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_test.cc b/third_party/blink/renderer/core/loader/resource/image_resource_test.cc index be4eba4..0abe271 100644 --- a/third_party/blink/renderer/core/loader/resource/image_resource_test.cc +++ b/third_party/blink/renderer/core/loader/resource/image_resource_test.cc
@@ -31,6 +31,8 @@ #include "third_party/blink/renderer/core/loader/resource/image_resource.h" #include <memory> +#include <string_view> + #include "base/task/single_thread_task_runner.h" #include "base/test/metrics/histogram_tester.h" #include "testing/gmock/include/gmock/gmock.h" @@ -178,13 +180,13 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xd9}; -constexpr char kSvgImage[] = +constexpr std::string_view kSvgImage = "<svg width=\"200\" height=\"200\" xmlns=\"http://www.w3.org/2000/svg\" " "xmlns:xlink=\"http://www.w3.org/1999/xlink\">" "<rect x=\"0\" y=\"0\" width=\"100px\" height=\"100px\" fill=\"red\"/>" "</svg>"; -constexpr char kSvgImage2[] = +constexpr std::string_view kSvgImage2 = "<svg width=\"300\" height=\"300\" xmlns=\"http://www.w3.org/2000/svg\" " "xmlns:xlink=\"http://www.w3.org/1999/xlink\">" "<rect x=\"0\" y=\"0\" width=\"200px\" height=\"200px\" fill=\"green\"/>" @@ -196,7 +198,7 @@ return test::CoreTestDataPath("cancelTest.html"); } -constexpr char kSvgImageWithSubresource[] = +constexpr std::string_view kSvgImageWithSubresource = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"198\" height=\"100\">" "<style>" " <![CDATA[@font-face{font-family:\"test\"; " @@ -208,14 +210,13 @@ void ReceiveResponse(ImageResource* image_resource, const KURL& url, const char* mime_type, - const char* data, - size_t data_size) { + base::span<const char> data) { ResourceResponse resource_response(url); resource_response.SetMimeType(AtomicString(mime_type)); resource_response.SetHttpStatusCode(200); image_resource->NotifyStartLoad(); image_resource->ResponseReceived(resource_response); - image_resource->AppendData(data, data_size); + image_resource->AppendData(data); image_resource->FinishForTest(); } @@ -268,10 +269,10 @@ EXPECT_EQ("multipart/x-mixed-replace", image_resource->GetResponse().MimeType()); - const char kFirstPart[] = + const std::string_view kFirstPart = "--boundary\n" "Content-Type: image/svg+xml\n\n"; - image_resource->AppendData(kFirstPart, strlen(kFirstPart)); + image_resource->AppendData(kFirstPart); // Send the response for the first real part. No image or data buffer is // created. EXPECT_FALSE(image_resource->ResourceBuffer()); @@ -280,12 +281,12 @@ EXPECT_FALSE(observer->ImageNotifyFinishedCalled()); EXPECT_EQ("image/svg+xml", image_resource->GetResponse().MimeType()); - const char kSecondPart[] = + const std::string_view kSecondPart = "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'><rect " "width='1' height='1' fill='green'/></svg>\n"; // The first bytes arrive. The data buffer is created, but no image is // created. - image_resource->AppendData(kSecondPart, strlen(kSecondPart)); + image_resource->AppendData(kSecondPart); EXPECT_TRUE(image_resource->ResourceBuffer()); EXPECT_FALSE(image_resource->GetContent()->HasImage()); EXPECT_EQ(0, observer->ImageChangedCount()); @@ -298,10 +299,10 @@ EXPECT_EQ(0, observer2->ImageChangedCount()); EXPECT_FALSE(observer2->ImageNotifyFinishedCalled()); - const char kThirdPart[] = "--boundary"; - image_resource->AppendData(kThirdPart, strlen(kThirdPart)); + const std::string_view kThirdPart = "--boundary"; + image_resource->AppendData(kThirdPart); ASSERT_TRUE(image_resource->ResourceBuffer()); - EXPECT_EQ(strlen(kSecondPart) - 1, image_resource->ResourceBuffer()->size()); + EXPECT_EQ(kSecondPart.size() - 1, image_resource->ResourceBuffer()->size()); // This part finishes. The image is created, callbacks are sent, and the data // buffer is cleared. @@ -351,13 +352,12 @@ /*cached_metadata=*/std::nullopt); EXPECT_FALSE(image_resource->GetContent()->HasImage()); - const char kBoundary[] = "--boundary\n"; - const char kContentType[] = "Content-Type: image/jpeg\n\n"; - image_resource->AppendData(kBoundary, strlen(kBoundary)); - image_resource->AppendData(kContentType, strlen(kContentType)); - image_resource->AppendData(reinterpret_cast<const char*>(kJpegImage), - sizeof(kJpegImage)); - image_resource->AppendData(kBoundary, strlen(kBoundary)); + const std::string_view kBoundary = "--boundary\n"; + const std::string_view kContentType = "Content-Type: image/jpeg\n\n"; + image_resource->AppendData(kBoundary); + image_resource->AppendData(kContentType); + image_resource->AppendData(base::as_chars(base::span(kJpegImage))); + image_resource->AppendData(kBoundary); image_resource->Loader()->DidFinishLoading(base::TimeTicks(), 0, 0, 0); EXPECT_TRUE(image_resource->GetContent()->HasImage()); EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage())); @@ -438,8 +438,7 @@ resource_response.SetMimeType(AtomicString("image/jpeg")); resource_response.SetExpectedContentLength(sizeof(kJpegImage)); image_resource->ResponseReceived(resource_response); - image_resource->AppendData(reinterpret_cast<const char*>(kJpegImage), - sizeof(kJpegImage)); + image_resource->AppendData(base::as_chars(base::span(kJpegImage))); ASSERT_TRUE(image_resource->GetContent()->HasImage()); EXPECT_EQ(ResourceStatus::kPending, image_resource->GetStatus()); @@ -469,8 +468,7 @@ resource_response.SetMimeType(AtomicString("image/jpeg")); resource_response.SetExpectedContentLength(sizeof(kJpegImage)); image_resource->ResponseReceived(resource_response); - image_resource->AppendData(reinterpret_cast<const char*>(kJpegImage), - sizeof(kJpegImage)); + image_resource->AppendData(base::as_chars(base::span(kJpegImage))); image_resource->FinishForTest(); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -507,8 +505,7 @@ resource_response.SetMimeType(AtomicString("image/jpeg")); resource_response.SetExpectedContentLength(sizeof(kJpegImage)); image_resource->ResponseReceived(resource_response); - image_resource->AppendData(reinterpret_cast<const char*>(kJpegImage), - sizeof(kJpegImage)); + image_resource->AppendData(base::as_chars(base::span(kJpegImage))); image_resource->FinishForTest(); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -524,8 +521,7 @@ auto* observer = MakeGarbageCollected<MockImageResourceObserver>( image_resource->GetContent()); - ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage, - strlen(kSvgImage)); + ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -542,7 +538,7 @@ image_resource->GetContent()); ReceiveResponse(image_resource, url, "image/svg+xml", - kSvgImageWithSubresource, strlen(kSvgImageWithSubresource)); + kSvgImageWithSubresource); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -587,8 +583,7 @@ image_resource->GetContent()); ReceiveResponse(image_resource, url, "image/jpeg", - reinterpret_cast<const char*>(kJpegImage), - sizeof(kJpegImage)); + base::as_chars(base::span(kJpegImage))); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -623,8 +618,7 @@ auto* observer = MakeGarbageCollected<MockImageResourceObserver>( image_resource->GetContent()); - ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage, - strlen(kSvgImage)); + ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -657,8 +651,7 @@ image_resource->GetContent()); ReceiveResponse(image_resource, url, "image/jpeg", - reinterpret_cast<const char*>(kJpegImage), - sizeof(kJpegImage)); + base::as_chars(base::span(kJpegImage))); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -672,8 +665,7 @@ image_resource->SetRevalidatingRequest(ResourceRequest(url)); ReceiveResponse(image_resource, url, "image/jpeg", - reinterpret_cast<const char*>(kJpegImage2), - sizeof(kJpegImage2)); + base::as_chars(base::span(kJpegImage2))); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -692,8 +684,7 @@ image_resource->GetContent()); ReceiveResponse(image_resource, url, "image/jpeg", - reinterpret_cast<const char*>(kJpegImage), - sizeof(kJpegImage)); + base::as_chars(base::span(kJpegImage))); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -706,8 +697,7 @@ image_resource->GetContent()->GetImage()->height()); image_resource->SetRevalidatingRequest(ResourceRequest(url)); - ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage, - strlen(kSvgImage)); + ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -725,8 +715,7 @@ auto* observer = MakeGarbageCollected<MockImageResourceObserver>( image_resource->GetContent()); - ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage, - strlen(kSvgImage)); + ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -739,8 +728,7 @@ image_resource->SetRevalidatingRequest(ResourceRequest(url)); ReceiveResponse(image_resource, url, "image/jpeg", - reinterpret_cast<const char*>(kJpegImage), - sizeof(kJpegImage)); + base::as_chars(base::span(kJpegImage))); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -759,8 +747,7 @@ auto* observer = MakeGarbageCollected<MockImageResourceObserver>( image_resource->GetContent()); - ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage, - strlen(kSvgImage)); + ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -772,8 +759,7 @@ EXPECT_EQ(200, image_resource->GetContent()->GetImage()->height()); image_resource->SetRevalidatingRequest(ResourceRequest(url)); - ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage2, - strlen(kSvgImage2)); + ReceiveResponse(image_resource, url, "image/svg+xml", kSvgImage2); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -792,8 +778,7 @@ ImageResource* image_resource = ImageResource::CreateForTest(url); ReceiveResponse(image_resource, url, "image/jpeg", - reinterpret_cast<const char*>(kJpegImage), - sizeof(kJpegImage)); + base::as_chars(base::span(kJpegImage))); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); @@ -981,9 +966,9 @@ // image to be created (since the size is known). This was determined by // appending one byte at a time (with flushes) until the image was decoded. size_t meaningful_image_size = 280; - image_resource->AppendData(reinterpret_cast<const char*>(kJpegImage2), - meaningful_image_size); - size_t bytes_sent = meaningful_image_size; + base::span<const char> remaining = base::as_chars(base::span(kJpegImage2)); + image_resource->AppendData(remaining.first(meaningful_image_size)); + remaining = remaining.subspan(meaningful_image_size); EXPECT_FALSE(image_resource->ErrorOccurred()); EXPECT_TRUE(image_resource->GetContent()->HasImage()); @@ -1006,14 +991,13 @@ // increases. for (int i = 0; i < 5; ++i) { SCOPED_TRACE(i); - image_resource->AppendData( - reinterpret_cast<const char*>(kJpegImage2) + bytes_sent, 1); + image_resource->AppendData(remaining.first(1u)); + remaining = remaining.subspan(1u); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); EXPECT_EQ(flush_count, observer->ImageChangedCount()); - ++bytes_sent; platform->RunForPeriodSeconds(0.2001); } } @@ -1027,9 +1011,7 @@ EXPECT_EQ(4, observer->ImageChangedCount()); // Append the rest of the data and finish (which causes another flush). - image_resource->AppendData( - reinterpret_cast<const char*>(kJpegImage2) + bytes_sent, - sizeof(kJpegImage2) - bytes_sent); + image_resource->AppendData(remaining); image_resource->FinishForTest(); EXPECT_FALSE(image_resource->ErrorOccurred()); @@ -1049,8 +1031,7 @@ // Image loaded. ReceiveResponse(image_resource, NullURL(), "image/jpeg", - reinterpret_cast<const char*>(kJpegImage), - sizeof(kJpegImage)); + base::as_chars(base::span(kJpegImage))); EXPECT_EQ(obs->ImageChangedCount(), 2); EXPECT_EQ(obs->Defer(), ImageResourceObserver::CanDeferInvalidation::kNo); @@ -1096,20 +1077,17 @@ // Test lossy WebP image. ImageResource* image_resource = ImageResource::CreateForTest(test_url); - image_resource->AppendData(reinterpret_cast<const char*>(kLossyWebPImage), - sizeof(kLossyWebPImage)); + image_resource->AppendData(base::as_chars(base::span(kLossyWebPImage))); EXPECT_EQ(1, image_resource->GetContent()->GetCompressionFormat()); // Test lossless WebP image. image_resource = ImageResource::CreateForTest(test_url); - image_resource->AppendData(reinterpret_cast<const char*>(kLosslessWebPImage), - sizeof(kLosslessWebPImage)); + image_resource->AppendData(base::as_chars(base::span(kLosslessWebPImage))); EXPECT_EQ(2, image_resource->GetContent()->GetCompressionFormat()); // Test extended WebP image. image_resource = ImageResource::CreateForTest(test_url); - image_resource->AppendData(reinterpret_cast<const char*>(kExtendedWebPImage), - sizeof(kExtendedWebPImage)); + image_resource->AppendData(base::as_chars(base::span(kExtendedWebPImage))); EXPECT_EQ(1, image_resource->GetContent()->GetCompressionFormat()); }
diff --git a/third_party/blink/renderer/core/loader/resource/script_resource_test.cc b/third_party/blink/renderer/core/loader/resource/script_resource_test.cc index 3c1a0dc..efa80044 100644 --- a/third_party/blink/renderer/core/loader/resource/script_resource_test.cc +++ b/third_party/blink/renderer/core/loader/resource/script_resource_test.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/core/loader/resource/script_resource.h" +#include <string_view> + #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler.h" @@ -25,8 +27,8 @@ response.SetHttpStatusCode(200); resource->ResponseReceived(response); - constexpr char kData[5] = "abcd"; - resource->AppendData(kData, strlen(kData)); + constexpr std::string_view kData = "abcd"; + resource->AppendData(kData); resource->FinishForTest(); auto* original_handler = resource->CacheHandler(); @@ -51,8 +53,8 @@ response.SetHttpStatusCode(200); resource->ResponseReceived(response); - constexpr char kData[5] = "abcd"; - resource->AppendData(kData, strlen(kData)); + constexpr std::string_view kData = "abcd"; + resource->AppendData(kData); resource->FinishForTest(); auto* original_handler = resource->CacheHandler(); @@ -79,8 +81,8 @@ response.SetHttpStatusCode(200); resource->ResponseReceived(response); - constexpr char kData[5] = "abcd"; - resource->AppendData(kData, strlen(kData)); + constexpr std::string_view kData = "abcd"; + resource->AppendData(kData); resource->FinishForTest(); auto* original_handler = resource->CacheHandler(); @@ -115,8 +117,8 @@ response.SetHttpStatusCode(200); resource->ResponseReceived(response); - constexpr char kData[5] = "abcd"; - resource->AppendData(kData, strlen(kData)); + constexpr std::string_view kData = "abcd"; + resource->AppendData(kData); resource->FinishForTest(); auto* handler = resource->CacheHandler(); @@ -140,8 +142,8 @@ response.SetHttpStatusCode(200); resource->ResponseReceived(response); - constexpr char kData[5] = "abcd"; - resource->AppendData(kData, strlen(kData)); + constexpr std::string_view kData = "abcd"; + resource->AppendData(kData); resource->FinishForTest(); auto* handler = resource->CacheHandler(); @@ -159,8 +161,8 @@ response.SetShouldUseSourceHashForJSCodeCache(true); resource->ResponseReceived(response); - constexpr char kData[5] = "abcd"; - resource->AppendData(kData, strlen(kData)); + constexpr std::string_view kData = "abcd"; + resource->AppendData(kData); resource->FinishForTest(); auto* handler = resource->CacheHandler();
diff --git a/third_party/blink/renderer/modules/geolocation/BUILD.gn b/third_party/blink/renderer/modules/geolocation/BUILD.gn index 2c152d2..853b6231 100644 --- a/third_party/blink/renderer/modules/geolocation/BUILD.gn +++ b/third_party/blink/renderer/modules/geolocation/BUILD.gn
@@ -16,6 +16,7 @@ "geolocation_position_error.h", "geolocation_watchers.cc", "geolocation_watchers.h", + "geoposition.cc", "geoposition.h", ] }
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation.cc b/third_party/blink/renderer/modules/geolocation/geolocation.cc index 1051a55..fd27590b 100644 --- a/third_party/blink/renderer/modules/geolocation/geolocation.cc +++ b/third_party/blink/renderer/modules/geolocation/geolocation.cc
@@ -27,6 +27,8 @@ #include "third_party/blink/renderer/modules/geolocation/geolocation.h" +#include <optional> + #include "base/task/single_thread_task_runner.h" #include "services/device/public/mojom/geoposition.mojom-blink.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" @@ -61,10 +63,16 @@ auto* coordinates = MakeGarbageCollected<GeolocationCoordinates>( position.latitude, position.longitude, // Lowest point on land is at approximately -400 meters. - position.altitude > -10000., position.altitude, position.accuracy, - position.altitude_accuracy >= 0., position.altitude_accuracy, - position.heading >= 0. && position.heading <= 360., position.heading, - position.speed >= 0., position.speed); + position.altitude > -10000. ? std::make_optional(position.altitude) + : std::nullopt, + position.accuracy, + position.altitude_accuracy >= 0. + ? std::make_optional(position.altitude_accuracy) + : std::nullopt, + position.heading >= 0. && position.heading <= 360. + ? std::make_optional(position.heading) + : std::nullopt, + position.speed >= 0. ? std::optional(position.speed) : std::nullopt); return MakeGarbageCollected<Geoposition>( coordinates, ConvertTimeToEpochTimeStamp(position.timestamp)); }
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc index 1c1d38fa..f8d085f 100644 --- a/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc +++ b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc
@@ -25,30 +25,20 @@ #include "third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h" + namespace blink { -std::optional<double> GeolocationCoordinates::altitude() const { - if (can_provide_altitude_) - return altitude_; - return std::nullopt; -} - -std::optional<double> GeolocationCoordinates::altitudeAccuracy() const { - if (can_provide_altitude_accuracy_) - return altitude_accuracy_; - return std::nullopt; -} - -std::optional<double> GeolocationCoordinates::heading() const { - if (can_provide_heading_) - return heading_; - return std::nullopt; -} - -std::optional<double> GeolocationCoordinates::speed() const { - if (can_provide_speed_) - return speed_; - return std::nullopt; +ScriptValue GeolocationCoordinates::toJSON(ScriptState* script_state) const { + V8ObjectBuilder builder(script_state); + builder.AddNumber("accuracy", accuracy_); + builder.AddNumber("latitude", latitude_); + builder.AddNumber("longitude", longitude_); + builder.AddNumberOrNull("altitude", altitude_); + builder.AddNumberOrNull("altitudeAccuracy", altitude_accuracy_); + builder.AddNumberOrNull("heading", heading_); + builder.AddNumberOrNull("speed", speed_); + return builder.GetScriptValue(); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h index d205bbc..c62ae3d 100644 --- a/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h +++ b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h
@@ -28,6 +28,7 @@ #include <optional> +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/modules/event_modules.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -39,48 +40,36 @@ public: GeolocationCoordinates(double latitude, double longitude, - bool provides_altitude, - double altitude, + std::optional<double> altitude, double accuracy, - bool provides_altitude_accuracy, - double altitude_accuracy, - bool provides_heading, - double heading, - bool provides_speed, - double speed) + std::optional<double> altitude_accuracy, + std::optional<double> heading, + std::optional<double> speed) : latitude_(latitude), longitude_(longitude), altitude_(altitude), accuracy_(accuracy), altitude_accuracy_(altitude_accuracy), heading_(heading), - speed_(speed), - can_provide_altitude_(provides_altitude), - can_provide_altitude_accuracy_(provides_altitude_accuracy), - can_provide_heading_(provides_heading), - can_provide_speed_(provides_speed) {} + speed_(speed) {} double latitude() const { return latitude_; } double longitude() const { return longitude_; } - std::optional<double> altitude() const; + std::optional<double> altitude() const { return altitude_; } double accuracy() const { return accuracy_; } - std::optional<double> altitudeAccuracy() const; - std::optional<double> heading() const; - std::optional<double> speed() const; + std::optional<double> altitudeAccuracy() const { return altitude_accuracy_; } + std::optional<double> heading() const { return heading_; } + std::optional<double> speed() const { return speed_; } + ScriptValue toJSON(ScriptState* script_state) const; private: double latitude_; double longitude_; - double altitude_; + std::optional<double> altitude_; double accuracy_; - double altitude_accuracy_; - double heading_; - double speed_; - - bool can_provide_altitude_; - bool can_provide_altitude_accuracy_; - bool can_provide_heading_; - bool can_provide_speed_; + std::optional<double> altitude_accuracy_; + std::optional<double> heading_; + std::optional<double> speed_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.idl b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.idl index f2916d2b..3d48bf73 100644 --- a/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.idl +++ b/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.idl
@@ -33,4 +33,5 @@ readonly attribute double? altitudeAccuracy; readonly attribute double? heading; readonly attribute double? speed; + [CallWith=ScriptState] object toJSON(); };
diff --git a/third_party/blink/renderer/modules/geolocation/geolocation_position.idl b/third_party/blink/renderer/modules/geolocation/geolocation_position.idl index e6daf9b9..9a07d71 100644 --- a/third_party/blink/renderer/modules/geolocation/geolocation_position.idl +++ b/third_party/blink/renderer/modules/geolocation/geolocation_position.idl
@@ -31,4 +31,5 @@ ] interface GeolocationPosition { readonly attribute GeolocationCoordinates coords; readonly attribute EpochTimeStamp timestamp; + [CallWith=ScriptState] object toJSON(); };
diff --git a/third_party/blink/renderer/modules/geolocation/geoposition.cc b/third_party/blink/renderer/modules/geolocation/geoposition.cc new file mode 100644 index 0000000..2c1488a --- /dev/null +++ b/third_party/blink/renderer/modules/geolocation/geoposition.cc
@@ -0,0 +1,18 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/geolocation/geoposition.h" + +#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h" + +namespace blink { + +ScriptValue Geoposition::toJSON(ScriptState* script_state) const { + V8ObjectBuilder builder(script_state); + builder.AddInteger("timestamp", timestamp_); + builder.AddV8Value("coords", coordinates_->toJSON(script_state).V8Value()); + return builder.GetScriptValue(); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/geolocation/geoposition.h b/third_party/blink/renderer/modules/geolocation/geoposition.h index 1e723e7a..c468372 100644 --- a/third_party/blink/renderer/modules/geolocation/geoposition.h +++ b/third_party/blink/renderer/modules/geolocation/geoposition.h
@@ -26,6 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOPOSITION_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOPOSITION_H_ +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/core/timing/epoch_time_stamp.h" #include "third_party/blink/renderer/modules/event_modules.h" #include "third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h" @@ -50,6 +51,7 @@ EpochTimeStamp timestamp() const { return timestamp_; } GeolocationCoordinates* coords() const { return coordinates_.Get(); } + ScriptValue toJSON(ScriptState* script_state) const; private: Member<GeolocationCoordinates> coordinates_;
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto b/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto index 331c211..70f0cec5 100644 --- a/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto +++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto
@@ -200,6 +200,18 @@ optional AacFormat format = 1; } +enum OpusSignal { + AUTO = 0; + MUSIC = 1; + VOICE = 2; +} + +enum OpusApplication { + VOIP = 0; + AUDIO = 1; + LOWDELAY = 2; +} + message OpusEncoderConfig { optional uint64 frame_duration = 1; @@ -210,6 +222,10 @@ optional bool useinbandfec = 4; optional bool usedtx = 5; + + optional OpusSignal signal = 6; + + optional OpusApplication application = 7; } message ConfigureAudioEncoder {
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/audio_encoder/encode_opus.textproto b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/audio_encoder/encode_opus.textproto index 69a1488..affd29e 100644 --- a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/audio_encoder/encode_opus.textproto +++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/audio_encoder/encode_opus.textproto
@@ -19,7 +19,9 @@ complexity: 9, packetlossperc: 20, useinbandfec: true, - usedtx: true + usedtx: true, + signal: 'voice', + application: 'voip', } } },
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc index cf727f0..168b5f7 100644 --- a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc +++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
@@ -180,6 +180,12 @@ if (proto.opus().has_usedtx()) { opus->setUsedtx(proto.opus().usedtx()); } + if (proto.opus().has_signal()) { + opus->setSignal(ToOpusSignal(proto.opus().signal())); + } + if (proto.opus().has_application()) { + opus->setApplication(ToOpusApplication(proto.opus().application())); + } } return config; @@ -270,6 +276,28 @@ } } +String ToOpusSignal(wc_fuzzer::OpusSignal opus_signal) { + switch (opus_signal) { + case wc_fuzzer::AUTO: + return "auto"; + case wc_fuzzer::MUSIC: + return "music"; + case wc_fuzzer::VOICE: + return "voice"; + } +} + +String ToOpusApplication(wc_fuzzer::OpusApplication opus_application) { + switch (opus_application) { + case wc_fuzzer::VOIP: + return "voip"; + case wc_fuzzer::AUDIO: + return "audio"; + case wc_fuzzer::LOWDELAY: + return "lowdelay"; + } +} + String ToChunkType(wc_fuzzer::EncodedChunkType type) { switch (type) { case wc_fuzzer::EncodedChunkType::KEY:
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h index d608a73..75758c6 100644 --- a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h +++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h
@@ -112,6 +112,10 @@ String ToBitrateMode(wc_fuzzer::BitrateMode bitrate_mode); +String ToOpusSignal(wc_fuzzer::OpusSignal opus_signal); + +String ToOpusApplication(wc_fuzzer::OpusApplication opus_application); + String ToAccelerationType( wc_fuzzer::ConfigureVideoEncoder_EncoderAccelerationPreference type);
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc b/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc index 43a43f1..8519ea9 100644 --- a/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc
@@ -30,6 +30,8 @@ #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" +#include <string_view> + #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "testing/gtest/include/gtest/gtest.h" @@ -65,8 +67,8 @@ const ResourceLoaderOptions& options) : Resource(request, ResourceType::kMock, options) {} - void AppendData(const char* data, size_t len) override { - Resource::AppendData(data, len); + void AppendData(base::span<const char> data) override { + Resource::AppendData(data); SetDecodedSize(this->size()); } @@ -212,14 +214,14 @@ MemoryCache::Get()->Remove(dummy_resource); EXPECT_EQ(0u, MemoryCache::Get()->size()); - const char kData[6] = "abcde"; + std::string_view kData = "abcde"; FetchParameters params1 = FetchParameters::CreateForTest( ResourceRequest("data:image/jpeg,resource1")); Resource* resource1 = FakeDecodedResource::Fetch(params1, fetcher, nullptr); MemoryCache::Get()->Remove(resource1); if (!identifier1.empty()) resource1->SetCacheIdentifier(identifier1); - resource1->AppendData(kData, 3u); + resource1->AppendData(kData.substr(0u, 3u)); resource1->FinishForTest(); FetchParameters params2 = FetchParameters::CreateForTest( ResourceRequest("data:image/jpeg,resource2")); @@ -229,7 +231,7 @@ MemoryCache::Get()->Remove(resource2); if (!identifier2.empty()) resource2->SetCacheIdentifier(identifier2); - resource2->AppendData(kData, 4u); + resource2->AppendData(kData.substr(0u, 4u)); resource2->FinishForTest(); platform->test_task_runner()->PostTask( @@ -268,7 +270,7 @@ const String& identifier1, const String& identifier2) { MemoryCache::Get()->SetCapacity(0); - const char kData[6] = "abcde"; + const std::string_view kData = "abcde"; Persistent<MockResourceClient> client1 = MakeGarbageCollected<MockResourceClient>(); Persistent<MockResourceClient> client2 = @@ -279,8 +281,8 @@ FetchParameters params2 = FetchParameters::CreateForTest(ResourceRequest("data:image/jpeg,bar")); Resource* resource2 = FakeDecodedResource::Fetch(params2, fetcher, client2); - resource1->AppendData(kData, 4u); - resource2->AppendData(kData, 4u); + resource1->AppendData(kData.substr(0u, 4u)); + resource2->AppendData(kData.substr(0u, 4u)); MemoryCache::Get()->SetCapacity(0); // Remove and re-Add the resources, with proper cache identifiers.
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc index cb9d8f7..3323b463 100644 --- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc +++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
@@ -99,11 +99,11 @@ const ResourceLoaderOptions& options) : Resource(resource_request, type, options) {} -void RawResource::AppendData(const char* data, size_t length) { +void RawResource::AppendData(base::span<const char> data) { if (GetResourceRequest().UseStreamOnResponse()) return; - Resource::AppendData(data, length); + Resource::AppendData(data); } class RawResource::PreloadBytesConsumerClient final
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.h b/third_party/blink/renderer/platform/loader/fetch/raw_resource.h index b251a06..96940b4 100644 --- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.h +++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
@@ -102,7 +102,7 @@ // Resource implementation void DidAddClient(ResourceClient*) override; - void AppendData(const char*, size_t) override; + void AppendData(base::span<const char>) override; bool ShouldIgnoreHTTPStatusCodeErrors() const override { return true; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.cc b/third_party/blink/renderer/platform/loader/fetch/resource.cc index d914ec6..fc6b8b22 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -250,18 +250,18 @@ } } -void Resource::AppendData(const char* data, size_t length) { - TRACE_EVENT1("blink", "Resource::appendData", "length", length); +void Resource::AppendData(base::span<const char> data) { + TRACE_EVENT1("blink", "Resource::appendData", "length", data.size()); DCHECK(!IsCacheValidator()); DCHECK(!ErrorOccurred()); if (options_.data_buffering_policy == kBufferData) { if (data_) - data_->Append(data, length); + data_->Append(data); else - data_ = SharedBuffer::Create(data, length); + data_ = SharedBuffer::Create(data); SetEncodedSize(data_->size()); } - NotifyDataReceived(base::span(data, length)); + NotifyDataReceived(data); } void Resource::NotifyDataReceived(base::span<const char> data) {
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.h b/third_party/blink/renderer/platform/loader/fetch/resource.h index 836b49b..aedda1a 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -159,7 +159,7 @@ void Trace(Visitor*) const override; virtual WTF::TextEncoding Encoding() const { return WTF::TextEncoding(); } - virtual void AppendData(const char*, size_t); + virtual void AppendData(base::span<const char>); virtual void FinishAsError(const ResourceError&, base::SingleThreadTaskRunner*);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 675df831..fe2411e4 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -33,6 +33,8 @@ #include <optional> #include <utility> +#include "base/compiler_specific.h" +#include "base/containers/span.h" #include "base/feature_list.h" #include "base/functional/bind.h" #include "base/memory/weak_ptr.h" @@ -1046,7 +1048,11 @@ observer->DidReceiveData(resource_->InspectorId(), base::make_span(data, length)); } - resource_->AppendData(data, length); + resource_->AppendData( + // SAFETY: `data` must point to `length` elements. + // TODO(crbug.com/40284755): Make this method take a span to capture it in + // the type system. + UNSAFE_BUFFERS(base::span(data, length))); // This value should not be exposed for opaque responses. if (resource_->response_.WasFetchedViaServiceWorker() &&
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_test.cc index 4c81f39..ec5384b 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_test.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource.h" +#include <string_view> + #include "base/test/task_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" @@ -110,8 +112,8 @@ ResourceResponse response(url); response.SetHttpStatusCode(200); resource->ResponseReceived(response); - const char kData[5] = "abcd"; - resource->AppendData(kData, 4); + const std::string_view kData = "abcd"; + resource->AppendData(kData); resource->FinishForTest(); MemoryCache::Get()->Add(resource); @@ -132,7 +134,7 @@ EXPECT_FALSE(resource->ResourceBuffer()); EXPECT_EQ(resource, MemoryCache::Get()->ResourceForURL(url)); - resource->AppendData(kData, 4); + resource->AppendData(kData); EXPECT_FALSE(client->NotifyFinishedCalled()); @@ -152,8 +154,8 @@ ResourceResponse response(url); response.SetHttpStatusCode(200); resource->ResponseReceived(response); - const char kData[5] = "abcd"; - resource->AppendData(kData, 4); + const std::string_view kData = "abcd"; + resource->AppendData(kData); resource->FinishForTest(); MemoryCache::Get()->Add(resource); @@ -318,8 +320,8 @@ ResourceResponse response(url); response.SetHttpStatusCode(200); resource->ResponseReceived(response); - const char kData[5] = "abcd"; - resource->AppendData(kData, 4); + const std::string_view kData = "abcd"; + resource->AppendData(kData); resource->FinishForTest(); MemoryCache::Get()->Add(resource); @@ -357,8 +359,8 @@ revalidating_response.SetHttpStatusCode(200); resource->ResponseReceived(revalidating_response); - const char kData2[4] = "xyz"; - resource->AppendData(kData2, 3); + const std::string_view kData2 = "xyz"; + resource->AppendData(kData2); resource->FinishForTest(); EXPECT_FALSE(resource->IsCacheValidator()); EXPECT_FALSE(resource->HasSuccessfulRevalidation());
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 1e99bc4..c023047 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1780,6 +1780,7 @@ // Protected Audience ad auction config. name: "FledgeDeprecatedRenderURLReplacements", public: true, + status: "test", }, { name: "FledgeDirectFromSellerSignalsHeaderAdSlot", @@ -2863,7 +2864,7 @@ { name: "PagePopup", // Android does not have support for PagePopup - status: {"Android": "", "default": "stable"}, + status: {"Android": "", "iOS": "", "default": "stable"}, }, { name: "PageRevealEvent",
diff --git a/third_party/blink/renderer/platform/wtf/shared_buffer.cc b/third_party/blink/renderer/platform/wtf/shared_buffer.cc index 6168f1cc..cbebda93 100644 --- a/third_party/blink/renderer/platform/wtf/shared_buffer.cc +++ b/third_party/blink/renderer/platform/wtf/shared_buffer.cc
@@ -28,10 +28,12 @@ #include <memory> +#include "base/compiler_specific.h" #include "base/numerics/safe_conversions.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/text/unicode.h" #include "third_party/blink/renderer/platform/wtf/text/utf8.h" +#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" namespace WTF { @@ -101,12 +103,14 @@ SharedBuffer::SharedBuffer(wtf_size_t size) : size_(size), buffer_(size) {} -SharedBuffer::SharedBuffer(const char* data, wtf_size_t size) : size_(size) { - buffer_.Append(data, size); +SharedBuffer::SharedBuffer(base::span<const char> data) + : size_(base::checked_cast<wtf_size_t>(data.size())) { + // TODO(crbug.com/40284755): Spanify `Vector::Append`. + buffer_.Append(data.data(), base::checked_cast<wtf_size_t>(data.size())); } -SharedBuffer::SharedBuffer(const unsigned char* data, wtf_size_t size) - : SharedBuffer(reinterpret_cast<const char*>(data), size) {} +SharedBuffer::SharedBuffer(base::span<const unsigned char> data) + : SharedBuffer(base::as_chars(data)) {} SharedBuffer::~SharedBuffer() = default; @@ -124,32 +128,37 @@ void SharedBuffer::Append(const SharedBuffer& data) { for (const auto& span : data) - Append(span.data(), span.size()); + Append(span); } -void SharedBuffer::AppendInternal(const char* data, size_t length) { - if (!length) - return; - - DCHECK_GE(size_, buffer_.size()); - size_t position_in_segment = OffsetInSegment(size_ - buffer_.size()); - size_ += length; - - if (size_ <= kSegmentSize) { - // No need to use segments for small resource data. - buffer_.Append(data, static_cast<wtf_size_t>(length)); +void SharedBuffer::Append(base::span<const char> data) { + if (data.empty()) { return; } - while (length > 0) { + DCHECK_GE(size_, buffer_.size()); + size_t position_in_segment = OffsetInSegment(size_ - buffer_.size()); + size_ += data.size(); + + if (size_ <= kSegmentSize) { + // No need to use segments for small resource data. + buffer_.Append(data.data(), static_cast<wtf_size_t>(data.size())); + return; + } + + while (!data.empty()) { if (!position_in_segment) segments_.push_back(CreateSegment()); - size_t bytes_to_copy = std::min(length, kSegmentSize - position_in_segment); - memcpy(segments_.back().get() + position_in_segment, data, bytes_to_copy); + size_t bytes_to_copy = + std::min(data.size(), kSegmentSize - position_in_segment); + auto [to_copy, rest] = data.split_at(bytes_to_copy); + // SAFETY: Every segment has size `kSegmentSize`. + UNSAFE_BUFFERS(base::span(segments_.back().get(), kSegmentSize)) + .subspan(position_in_segment, bytes_to_copy) + .copy_from(to_copy); - data += bytes_to_copy; - length -= bytes_to_copy; + data = rest; position_in_segment = 0; } }
diff --git a/third_party/blink/renderer/platform/wtf/shared_buffer.h b/third_party/blink/renderer/platform/wtf/shared_buffer.h index 2095c46..88709f9 100644 --- a/third_party/blink/renderer/platform/wtf/shared_buffer.h +++ b/third_party/blink/renderer/platform/wtf/shared_buffer.h
@@ -31,6 +31,7 @@ #include <vector> #include "base/check_op.h" +#include "base/compiler_specific.h" #include "base/containers/span.h" #include "base/numerics/safe_conversions.h" #include "base/ranges/algorithm.h" @@ -99,6 +100,15 @@ return base::AdoptRef(new SharedBuffer); } + static scoped_refptr<SharedBuffer> Create(base::span<const char> data) { + return base::AdoptRef(new SharedBuffer(data)); + } + + static scoped_refptr<SharedBuffer> Create( + base::span<const unsigned char> data) { + return base::AdoptRef(new SharedBuffer(data)); + } + HAS_STRICTLY_TYPED_ARG static scoped_refptr<SharedBuffer> Create(STRICTLY_TYPED_ARG(size)) { ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(size_t); @@ -110,16 +120,20 @@ static scoped_refptr<SharedBuffer> Create(const char* data, STRICTLY_TYPED_ARG(size)) { ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(size_t); - return base::AdoptRef( - new SharedBuffer(data, base::checked_cast<wtf_size_t>(size))); + return Create( + // SAFETY: The caller must ensure `data` points to `size` elements. + // TODO(crbug.com/40284755): Remove this in favor of the span versions. + UNSAFE_BUFFERS(base::span(data, size))); } HAS_STRICTLY_TYPED_ARG static scoped_refptr<SharedBuffer> Create(const unsigned char* data, STRICTLY_TYPED_ARG(size)) { ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(size_t); - return base::AdoptRef( - new SharedBuffer(data, base::checked_cast<wtf_size_t>(size))); + return Create( + // SAFETY: The caller must ensure `data` points to `size` elements. + // TODO(crbug.com/40284755): Remove this in favor of the span versions. + UNSAFE_BUFFERS(base::span(data, size))); } static scoped_refptr<SharedBuffer> AdoptVector(Vector<char>&); @@ -136,17 +150,29 @@ void Append(const SharedBuffer&); + // TODO(crbug.com/40284755): Remove the pointer-based methods in favor of span + // ones. HAS_STRICTLY_TYPED_ARG void Append(const char* data, STRICTLY_TYPED_ARG(size)) { ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(size_t); - AppendInternal(data, size); + Append( + // SAFETY: The caller must ensure `data` points to `size` elements. + // TODO(crbug.com/40284755): Remove this in favor of the span versions. + UNSAFE_BUFFERS(base::span(data, size))); } HAS_STRICTLY_TYPED_ARG void Append(const unsigned char* data, STRICTLY_TYPED_ARG(size)) { ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(size_t); - AppendInternal(reinterpret_cast<const char*>(data), size); + Append( + // SAFETY: The caller must ensure `data` points to `size` elements. + // TODO(crbug.com/40284755): Remove this in favor of the span versions. + UNSAFE_BUFFERS(base::span(data, size))); } - void Append(const Vector<char>& data) { Append(data.data(), data.size()); } + + void Append(base::span<const char> data); + void Append(base::span<const unsigned char> data) { + Append(base::as_chars(data)); + } void Clear(); @@ -209,13 +235,12 @@ SharedBuffer(); explicit SharedBuffer(wtf_size_t); - SharedBuffer(const char*, wtf_size_t); - SharedBuffer(const unsigned char*, wtf_size_t); + explicit SharedBuffer(base::span<const char>); + explicit SharedBuffer(base::span<const unsigned char>); // See SharedBuffer::data(). void MergeSegmentsIntoBuffer(); - void AppendInternal(const char* data, size_t); bool GetBytesInternal(void* dest, size_t) const; Iterator GetIteratorAtInternal(size_t position) const; size_t GetLastSegmentSize() const {
diff --git a/third_party/blink/tools/blinkpy/wpt_tests/product.py b/third_party/blink/tools/blinkpy/wpt_tests/product.py index 6e585bef..44e2552 100644 --- a/third_party/blink/tools/blinkpy/wpt_tests/product.py +++ b/third_party/blink/tools/blinkpy/wpt_tests/product.py
@@ -37,7 +37,9 @@ respective classes. """ product_registry = {} - product_classes = [Chrome, ContentShell, ChromeiOS, ChromeAndroid, WebView] + product_classes = [ + Chrome, HeadlessShell, ContentShell, ChromeiOS, ChromeAndroid, WebView + ] for product_cls in product_classes: names = [product_cls.name] + product_cls.aliases product_registry.update((name, product_cls) for name in names) @@ -112,6 +114,10 @@ } +class HeadlessShell(Chrome): + name = 'headless_shell' + + class ContentShell(Product): name = 'content_shell'
diff --git a/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py b/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py index fa17900..d97a332f 100644 --- a/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py +++ b/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py
@@ -170,7 +170,7 @@ else: port = host.port_factory.get(port_name, options) - if options.product == 'chrome': + if options.product in ['chrome', 'headless_shell']: port.set_option_default('driver_name', port.CHROME_NAME) product = make_product(port, options) return WPTAdapter(product, port, options, tests) @@ -233,7 +233,8 @@ mozlog.commandline.log_formatters[name][1], ) - runner_options = parser.parse_args(['--product', self.product.name]) + product_name = 'chrome' if self.product.name == 'headless_shell' else self.product.name + runner_options = parser.parse_args(['--product', product_name]) runner_options.include = [] runner_options.exclude = [] @@ -326,6 +327,8 @@ 'MAP *.test 127.0.0.1, MAP *.test. 127.0.0.1', *self.port.additional_driver_flags(), ]) + if self.options.product == 'headless_shell': + runner_options.binary_args.append('--headless=old') # Implicitly pass `--enable-blink-features=MojoJS,MojoJSTest` to Chrome. runner_options.mojojs_path = self.port.generated_sources_directory()
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 20190b7..80a27013 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1592,6 +1592,23 @@ "expires": "Sep 1, 2024" }, { + "prefix": "fledge-deprecated-render-url-replacements", + "platforms": ["Linux", "Mac", "Win"], + "owners": ["ybourouphael@google.com", "behamilton@google.com", "mmenke@chromium.org", "pauljensen@chromium.org"], + "bases": [ + "external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window.js", + "external/wpt/fledge/tentative/auction-config-passed-to-worklets.https.window.js", + "external/wpt/fledge/tentative/auction-config.https.window.js", + "external/wpt/fledge/tentative/component-ads.https.window.js", + "external/wpt/fledge/tentative/component-auction.https.window.js" + ], + "args": [ + "--enable-features=InterestGroupStorage,PrivacySandboxAdsAPIsOverride,FencedFrames:implementation_type/mparch,FledgeConsiderKAnonymity", + "--disable-features=CookieDeprecationFacilitatedTesting" + ], + "expires": "Sep 1, 2024" + }, + { "prefix": "automatic-lazy-frame-loading", "platforms": ["Linux", "Mac", "Win"], "bases": [
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 480a8daf..9c2f85ce 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -282734,6 +282734,32 @@ {} ] ], + "paint-context-007.svg": [ + "50360a302e3a3d2ca74b465122d322a25abf743a", + [ + null, + [ + [ + "/svg/painting/reftests/paint-context-007-ref.svg", + "==" + ] + ], + {} + ] + ], + "paint-context-008.svg": [ + "83308f09b1fc95d538ee078ff9acbf7e7def307e", + [ + null, + [ + [ + "/svg/painting/reftests/paint-context-008-ref.svg", + "==" + ] + ], + {} + ] + ], "paint-order-001.svg": [ "c8d60bd5bf68d0dc5f56fb360acdd2bac5aa1aa2", [ @@ -346467,7 +346493,7 @@ [] ], "file-names.md": [ - "96296c4ff69934a77581a50c5cf7299feadbb838", + "5336bfb528cec59ea3ce1fe78540470980969d0c", [] ], "general-guidelines.md": [ @@ -346549,7 +346575,7 @@ [] ], "testdriver.md": [ - "73af3bb3c8dd72fc283cdc9440fbe05bd768d1d3", + "fcf0199badc12e8cca1d017d266db4abe02544ad", [] ], "testharness-api.md": [ @@ -384394,7 +384420,7 @@ [] ], "testdriver.js": [ - "20140b2fc0a0b7c5bb32089b4e8283ffbb6e2a01", + "2d1a89690cc25f87e7d2762c3f5081081a902f7a", [] ], "testdriver.js.headers": [ @@ -390895,6 +390921,14 @@ "6aa42374c512b528868c55d0339eb4deedf09d69", [] ], + "paint-context-007-ref.svg": [ + "0328272c6aa0907e226cbbbc2008358bee43ef7b", + [] + ], + "paint-context-008-ref.svg": [ + "49d4f8947b003302a76888e6beea385a4019f404", + [] + ], "paint-order-001-ref.svg": [ "7822a80b942fee54a87106d7def13429454cc26e", [] @@ -504996,10 +505030,12 @@ ] ], "setting-null-config-navigates-to-about-blank.https.html": [ - "2595fd64c922b1e16220628fe1fa87fdf7c74f5f", + "c8322dab1996ccabc5ee980fd63bc52c57df9d05", [ null, - {} + { + "timeout": "long" + } ] ], "shared-workers.https.html": [
diff --git a/third_party/blink/web_tests/external/wpt/docs/writing-tests/file-names.md b/third_party/blink/web_tests/external/wpt/docs/writing-tests/file-names.md index 96296c4..5336bfb 100644 --- a/third_party/blink/web_tests/external/wpt/docs/writing-tests/file-names.md +++ b/third_party/blink/web_tests/external/wpt/docs/writing-tests/file-names.md
@@ -11,10 +11,10 @@ ### Test Type -These flags must be the last element in the filename before the -extension e.g. `foo-manual.html` will indicate a manual test, but -`foo-manual-other.html` will not. Unlike test features, test types -are mutually exclusive. +These flags are preceded by a `-` and followed by a `.`, and must be the +last such element in the filename, e.g. `foo-manual.html` will indicate +a manual test, but `foo-manual-other.html` will not. Unlike test features, +test types are mutually exclusive. `-manual` @@ -26,8 +26,8 @@ ### Test Features -These flags are preceded by a `.` in the filename, and must -themselves precede any test type flag, but are otherwise unordered. +These flags are preceded and followed by a `.` in the filename, and must themselves +go after any test type flag, but are otherwise unordered. `.https`
diff --git a/third_party/blink/web_tests/external/wpt/docs/writing-tests/testdriver.md b/third_party/blink/web_tests/external/wpt/docs/writing-tests/testdriver.md index 73af3bb..fcf0199 100644 --- a/third_party/blink/web_tests/external/wpt/docs/writing-tests/testdriver.md +++ b/third_party/blink/web_tests/external/wpt/docs/writing-tests/testdriver.md
@@ -119,6 +119,12 @@ .. js:autofunction:: test_driver.get_virtual_sensor_information ``` +### Device Posture ### +```eval_rst +.. js:autofunction:: test_driver.set_device_posture +.. js:autofunction:: test_driver.clear_device_posture +``` + ### Using test_driver in other browsing contexts ### Testdriver can be used in browsing contexts (i.e. windows or frames)
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config-passed-to-worklets.https.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config-passed-to-worklets.https.window.js index 9b12d07..7780957 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config-passed-to-worklets.https.window.js +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config-passed-to-worklets.https.window.js
@@ -81,6 +81,18 @@ }); makeTest({ + name: 'AuctionConfig.deprecatedRenderURLReplacements with brackets.', + fieldName: 'deprecatedRenderURLReplacements', + fieldValue: {'${EXAMPLE_MACRO}': 'SSP'}, +}); + +makeTest({ + name: 'AuctionConfig.deprecatedRenderURLReplacements with percents.', + fieldName: 'deprecatedRenderURLReplacements', + fieldValue: {'%%EXAMPLE_MACRO%%': 'SSP'}, +}); + +makeTest({ name: 'AuctionConfig.seller is URL.', fieldName: 'seller', fieldValue: OTHER_ORIGIN1,
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config-passed-to-worklets.https.window_1-5-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config-passed-to-worklets.https.window_1-5-expected.txt new file mode 100644 index 0000000..f77f9c25 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config-passed-to-worklets.https.window_1-5-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +[FAIL] AuctionConfig.deprecatedRenderURLReplacements with brackets. + assert_true: Auction unexpectedly had no winner expected true got false +[FAIL] AuctionConfig.deprecatedRenderURLReplacements with percents. + assert_true: Auction unexpectedly had no winner expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config.https.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config.https.window.js index 5fa4fa2..28ed147 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config.https.window.js +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config.https.window.js
@@ -12,7 +12,8 @@ // META: variant=?31-35 // META: variant=?36-40 // META: variant=?40-45 -// META: variant=?46-last +// META: variant=?45-50 +// META: variant=?50-last "use strict;" @@ -110,6 +111,62 @@ } makeTest({ + name: 'deprecatedRenderURLReplacements without end bracket is invalid.', + expect: EXPECT_PROMISE_ERROR, + expectPromiseError: EXPECT_EXCEPTION(TypeError), + auctionConfigOverrides: {deprecatedRenderURLReplacements: {'${No_End_Bracket': 'SSP'}} +}); + +makeTest({ + name: 'deprecatedRenderURLReplacements without percents and brackets.', + expect: EXPECT_PROMISE_ERROR, + expectPromiseError: EXPECT_EXCEPTION(TypeError), + auctionConfigOverrides: {deprecatedRenderURLReplacements: {'No_Wrapper': 'SSP'}} +}); + +makeTest({ + name: 'deprecatedRenderURLReplacements without dollar sign.', + expect: EXPECT_PROMISE_ERROR, + expectPromiseError: EXPECT_EXCEPTION(TypeError), + auctionConfigOverrides: {deprecatedRenderURLReplacements: {'{No_Dollar_Sign}': 'SSP'}} +}); + +makeTest({ + name: 'deprecatedRenderURLReplacements without start bracket is invalid.', + expect: EXPECT_PROMISE_ERROR, + expectPromiseError: EXPECT_EXCEPTION(TypeError), + auctionConfigOverrides: {deprecatedRenderURLReplacements: {'$No_Start_Bracket}': 'SSP'}} +}); + +makeTest({ + name: 'deprecatedRenderURLReplacements mix and match is invalid.', + expect: EXPECT_PROMISE_ERROR, + expectPromiseError: EXPECT_EXCEPTION(TypeError), + auctionConfigOverrides: {deprecatedRenderURLReplacements: {'${Bracket_And_Percent%%': 'SSP'}} +}); + +makeTest({ + name: 'deprecatedRenderURLReplacements missing start percent is invalid.', + expect: EXPECT_PROMISE_ERROR, + expectPromiseError: EXPECT_EXCEPTION(TypeError), + auctionConfigOverrides: {deprecatedRenderURLReplacements: {'%Missing_Start_Percents%%': 'SSP'}} +}); + +makeTest({ + name: 'deprecatedRenderURLReplacements single percents is invalid.', + expect: EXPECT_PROMISE_ERROR, + expectPromiseError: EXPECT_EXCEPTION(TypeError), + auctionConfigOverrides: {deprecatedRenderURLReplacements: {'%Single_Percents%': 'SSP'}} +}); + +makeTest({ + name: 'deprecatedRenderURLReplacements without end percents is invalid.', + expect: EXPECT_PROMISE_ERROR, + expectPromiseError: EXPECT_EXCEPTION(TypeError), + auctionConfigOverrides: {deprecatedRenderURLReplacements: {'%%No_End_Percents': 'SSP'}} +}); + +makeTest({ name: 'no buyers => no winners', expect: EXPECT_NO_WINNER, auctionConfigOverrides: {interestGroupBuyers: []},
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config.https.window_1-5-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config.https.window_1-5-expected.txt new file mode 100644 index 0000000..4cc16150 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config.https.window_1-5-expected.txt
@@ -0,0 +1,13 @@ +This is a testharness.js-based test. +[FAIL] deprecatedRenderURLReplacements without end bracket is invalid. + assert_true: did not get expected error type: [object FencedFrameConfig] expected true got false +[FAIL] deprecatedRenderURLReplacements without percents and brackets. + assert_true: did not get expected error type: [object FencedFrameConfig] expected true got false +[FAIL] deprecatedRenderURLReplacements without dollar sign. + assert_true: did not get expected error type: [object FencedFrameConfig] expected true got false +[FAIL] deprecatedRenderURLReplacements without start bracket is invalid. + assert_true: did not get expected error type: [object FencedFrameConfig] expected true got false +[FAIL] deprecatedRenderURLReplacements mix and match is invalid. + assert_true: did not get expected error type: [object FencedFrameConfig] expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config.https.window_6-10-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config.https.window_6-10-expected.txt new file mode 100644 index 0000000..f3d6faf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/auction-config.https.window_6-10-expected.txt
@@ -0,0 +1,9 @@ +This is a testharness.js-based test. +[FAIL] deprecatedRenderURLReplacements missing start percent is invalid. + assert_true: did not get expected error type: [object FencedFrameConfig] expected true got false +[FAIL] deprecatedRenderURLReplacements single percents is invalid. + assert_true: did not get expected error type: [object FencedFrameConfig] expected true got false +[FAIL] deprecatedRenderURLReplacements without end percents is invalid. + assert_true: did not get expected error type: [object FencedFrameConfig] expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/component-ads.https.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/component-ads.https.window.js index 6b22585..8493025 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/component-ads.https.window.js +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/component-ads.https.window.js
@@ -44,13 +44,25 @@ // // If "adMetadata" is true, metadata is added to each component ad. Only integer metadata // is used, relying on renderURL tests to cover other types of renderURL metadata. +// +// If "deprecatedRenderURLReplacements" is passed, the matches and replacements will be +// used in the trackingURLs and the object will be passed into the auctionConfig, to +// replace matching macros within the renderURLs. async function runComponentAdLoadingTest(test, uuid, numComponentAdsInInterestGroup, - componentAdsInBid, componentAdsToLoad, - adMetadata = false) { + componentAdsInBid, componentAdsToLoad, + adMetadata = false, deprecatedRenderURLReplacements = null) { let interestGroupAdComponents = []; + // These are used within the URLs for deprecatedRenderURLReplacement tests. + const renderURLReplacementsStrings = createStringBeforeAndAfterReplacements(deprecatedRenderURLReplacements); + const beforeReplacementsString= renderURLReplacementsStrings.beforeReplacements; + const afterReplacementsString = renderURLReplacementsStrings.afterReplacements; + for (let i = 0; i < numComponentAdsInInterestGroup; ++i) { - const componentRenderURL = createComponentAdRenderURL(uuid, i); - let adComponent = {renderURL: componentRenderURL}; + let componentRenderURL = createComponentAdRenderURL(uuid, i); + if (deprecatedRenderURLReplacements !== null) { + componentRenderURL = createTrackerURL(window.location.origin, uuid, 'track_get', beforeReplacementsString); + } + let adComponent = { renderURL: componentRenderURL }; if (adMetadata) adComponent.metadata = i; interestGroupAdComponents.push(adComponent); @@ -74,7 +86,7 @@ eventData: status, destination: ["buyer"]});`); - let bid = {bid:1, render: renderURL}; + let bid = {bid:1, render:renderURL}; if (componentAdsInBid) { bid.adComponents = []; for (let index of componentAdsInBid) { @@ -89,8 +101,13 @@ // to "expectedTrackerURLs". if (componentAdsToLoad && bid.adComponents) { for (let index of componentAdsToLoad) { + let expectedURL = createComponentAdTrackerURL(uuid, componentAdsInBid[index]); + if (deprecatedRenderURLReplacements != null) { + expectedURL = createTrackerURL(window.location.origin, uuid, 'track_get', + afterReplacementsString); + } if (index < componentAdsInBid.length) - expectedTrackerURLs.push(createComponentAdTrackerURL(uuid, componentAdsInBid[index])); + expectedTrackerURLs.push(expectedURL); } } @@ -127,11 +144,13 @@ test, uuid, {decisionLogicURL: createDecisionScriptURL( uuid, - { scoreAd: + { scoreAd: `if (JSON.stringify(browserSignals.adComponents) !== '${JSON.stringify(bid.adComponents)}') { throw "Unexpected adComponents: " + JSON.stringify(browserSignals.adComponents); - }`})}); + }`}), + deprecatedRenderURLReplacements: deprecatedRenderURLReplacements + }); } await waitForObservedRequests(uuid, expectedTrackerURLs); @@ -447,3 +466,27 @@ }, 'Reports not sent from component ad.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + await runComponentAdLoadingTest(test, uuid, /*numComponentAdsInInterestGroup=*/1, + /*componentAdsInBid=*/[0], /*componentAdsToLoad=*/[0], false, { '%%EXAMPLE-MACRO%%': 'SSP' }); +}, 'component ad with render url replacements with percents.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + await runComponentAdLoadingTest(test, uuid, /*numComponentAdsInInterestGroup=*/1, + /*componentAdsInBid=*/[0], /*componentAdsToLoad=*/[0], false, { '${EXAMPLE-MACRO}': 'SSP' }); +}, 'component ad with render url replacements with brackets.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + await runComponentAdLoadingTest(test, uuid, /*numComponentAdsInInterestGroup=*/1, + /*componentAdsInBid=*/[0], /*componentAdsToLoad=*/[0], false, { '${EXAMPLE-MACRO-1}': 'SSP-1', '%%EXAMPLE-MACRO-2%%': 'SSP-2' }); +}, 'component ad with render url replacements with multiple replacements.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + await runComponentAdLoadingTest(test, uuid, /*numComponentAdsInInterestGroup=*/3, + /*componentAdsInBid=*/[0,1,2], /*componentAdsToLoad=*/[0,1,2], false, { '${EXAMPLE-MACRO-1}': 'SSP-1', '%%EXAMPLE-MACRO-2%%': 'SSP-2' }); +}, 'component ad with render url replacements with multiple replacements, and multiple component ads.');
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/component-ads.https.window_16-last-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/component-ads.https.window_16-last-expected.txt new file mode 100644 index 0000000..bb41d8c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/component-ads.https.window_16-last-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +[FAIL] component ad with render url replacements with percents. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%EXAMPLE-MACRO%%/" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP/", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_post&id=bidder_beacon_1, body: ok"] +[FAIL] component ad with render url replacements with brackets. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${EXAMPLE-MACRO}/" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP/", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_post&id=bidder_beacon_1, body: ok"] +[FAIL] component ad with render url replacements with multiple replacements. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${EXAMPLE-MACRO-1}/%%EXAMPLE-MACRO-2%%/" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP-1/SSP-2/", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_post&id=bidder_beacon_1, body: ok"] +[FAIL] component ad with render url replacements with multiple replacements, and multiple component ads. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${EXAMPLE-MACRO-1}/%%EXAMPLE-MACRO-2%%/" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP-1/SSP-2/", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP-1/SSP-2/", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP-1/SSP-2/", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_post&id=bidder_beacon_1, body: ok"] +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/component-auction.https.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/component-auction.https.window.js index 015c20a5..bf804e6 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/component-auction.https.window.js +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/component-auction.https.window.js
@@ -11,18 +11,21 @@ "use strict"; // Creates an AuctionConfig with a single component auction. -function createComponentAuctionConfig(uuid) { +function createComponentAuctionConfig(uuid, auctionConfigOverrides = {}, + deprecatedRenderURLReplacements = {}) { let componentAuctionConfig = { seller: window.location.origin, decisionLogicURL: createDecisionScriptURL(uuid), - interestGroupBuyers: [window.location.origin] + interestGroupBuyers: [window.location.origin], + deprecatedRenderURLReplacements: deprecatedRenderURLReplacements }; return { seller: window.location.origin, decisionLogicURL: createDecisionScriptURL(uuid), interestGroupBuyers: [], - componentAuctions: [componentAuctionConfig] + componentAuctions: [componentAuctionConfig], + ...auctionConfigOverrides }; } @@ -717,3 +720,118 @@ uuid, [bidderReportURL1, seller1ReportURL, bidderReportURL2, seller2ReportURL]); }, `Component auction prevWinsMs and numBids updating in one component seller's auction, read in another's.`); + + +const makeDeprecatedRenderURLReplacementTest = ({ + name, + deprecatedRenderURLReplacements, +}) => { + subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + + let bidderReportURL = createBidderReportURL(uuid); + let componentSellerReportURL = createSellerReportURL(uuid, /*id=*/"component"); + let topLevelSellerReportURL = createSellerReportURL(uuid, /*id=*/"top"); + + // These are used within the URLs for deprecatedRenderURLReplacement tests. + const renderURLReplacementsStrings = createStringBeforeAndAfterReplacements(deprecatedRenderURLReplacements); + const beforeReplacementsString = renderURLReplacementsStrings.beforeReplacements; + const afterReplacementsString = renderURLReplacementsStrings.afterReplacements; + const renderURLBeforeReplacements = createTrackerURL(window.location.origin, uuid, 'track_get', beforeReplacementsString); + const renderURLAfterReplacements = createTrackerURL(window.location.origin, uuid, 'track_get', afterReplacementsString); + + await joinInterestGroup( + test, uuid, + { + ads: [{ renderURL: renderURLBeforeReplacements }], + biddingLogicURL: createBiddingScriptURL( + { + allowComponentAuction: true, + bid: 5, + reportWin: + `if (browserSignals.bid !== 5) + throw "Unexpected bid: " + browserSignals.bid; + sendReportTo("${bidderReportURL}");` + }) + }); + + let auctionConfig = createComponentAuctionConfig(uuid, {}, deprecatedRenderURLReplacements); + + auctionConfig.componentAuctions[0].decisionLogicURL = + createDecisionScriptURL( + uuid, + { + scoreAd: + `if (bid !== 5) + throw "Unexpected component bid: " + bid`, + reportResult: + `if (browserSignals.bid !== 5) + throw "Unexpected component bid: " + browserSignals.bid; + if (browserSignals.modifiedBid !== undefined) + throw "Unexpected component modifiedBid: " + browserSignals.modifiedBid; + sendReportTo("${componentSellerReportURL}");` + }); + + auctionConfig.decisionLogicURL = + createDecisionScriptURL( + uuid, + { + scoreAd: + `if (bid !== 5) + throw "Unexpected top-level bid: " + bid`, + reportResult: + `if (browserSignals.bid !== 5) + throw "Unexpected top-level bid: " + browserSignals.bid; + if (browserSignals.modifiedBid !== undefined) + throw "Unexpected top-level modifiedBid: " + browserSignals.modifiedBid; + sendReportTo("${topLevelSellerReportURL}");` + }); + + await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfig); + await waitForObservedRequests( + uuid, + [bidderReportURL, componentSellerReportURL, topLevelSellerReportURL, renderURLAfterReplacements]); + }, name); +}; + +makeDeprecatedRenderURLReplacementTest({ + name: 'Replacements with brackets.', + deprecatedRenderURLReplacements: { '${EXAMPLE-MACRO}': 'SSP' } +}); + +makeDeprecatedRenderURLReplacementTest({ + name: 'Replacements with percents.', + deprecatedRenderURLReplacements: { '%%EXAMPLE-MACRO%%': 'SSP' } +}); + +makeDeprecatedRenderURLReplacementTest({ + name: 'Replacements with multiple replacements.', + deprecatedRenderURLReplacements: { '${EXAMPLE-MACRO1}': 'SSP1', '%%EXAMPLE-MACRO2%%': 'SSP2' } +}); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + let deprecatedRenderURLReplacements = { '${EXAMPLE-MACRO1}': 'SSP1', '%%EXAMPLE-MACRO2%%': 'SSP2' }; + const renderURLReplacementsStrings = createStringBeforeAndAfterReplacements(deprecatedRenderURLReplacements); + let beforeReplacementsString = renderURLReplacementsStrings.beforeReplacements; + + await joinInterestGroup( + test, uuid, + { + ads: [{ renderURL: createTrackerURL(window.location.origin, uuid, 'track_get', beforeReplacementsString) }], + biddingLogicURL: createBiddingScriptURL({allowComponentAuction: true}) + }); + let auctionConfigOverride = {deprecatedRenderURLReplacements: deprecatedRenderURLReplacements } + let auctionConfig = createComponentAuctionConfig(uuid,/*auctionConfigOverride=*/auctionConfigOverride, + /*deprecatedRenderURLReplacements=*/deprecatedRenderURLReplacements); + + auctionConfig.componentAuctions[0].decisionLogicURL = createDecisionScriptURL(uuid); + + try { + await runBasicFledgeAuction(test, uuid, auctionConfig); + } catch (exception) { + assert_true(exception instanceof TypeError, "did not get expected error: " + exception); + return; + } + throw 'Exception unexpectedly not thrown.' +}, "deprecatedRenderURLReplacements cause error if passed in top level auction and component auction.");
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/component-auction.https.window_16-last-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/component-auction.https.window_16-last-expected.txt new file mode 100644 index 0000000..afdb5ea --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/component-auction.https.window_16-last-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +[FAIL] Replacements with brackets. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${EXAMPLE-MACRO}/" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP/", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_component", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_top"] +[FAIL] Replacements with percents. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%EXAMPLE-MACRO%%/" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP/", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_component", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_top"] +[FAIL] Replacements with multiple replacements. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${EXAMPLE-MACRO1}/%%EXAMPLE-MACRO2%%/" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP1/SSP2/", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_component", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_top"] +[FAIL] deprecatedRenderURLReplacements cause error if passed in top level auction and component auction. + promise_test: Unhandled rejection with value: "Exception unexpectedly not thrown." +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window.js new file mode 100644 index 0000000..4f8bc1c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window.js
@@ -0,0 +1,196 @@ +// META: script=/resources/testdriver.js +// META: script=/common/utils.js +// META: script=resources/fledge-util.sub.js +// META: script=/common/subset-tests.js +// META: timeout=long +// META: variant=?1-5 +// META: variant=?6-10 +// META: variant=?11-15 +// META: variant=?16-last + + +"use strict;" + +// This test ensures proper handling of deprecatedRenderURLReplacements within auctionConfigOverrides. +// It validates that these replacements are correctly applied to the winning bid's renderURL by +// injecting a URL with matching macros into an interest group and ensuring that a new url with +// the replacements in it, is tracked and observed. +const makeTest = ({ + // Test name + name, + // Overrides to the interest group. + interestGroupOverrides = {}, + // Overrides to the auction config. + auctionConfigOverrides = {}, + // This is what goes into the renderURL and is expected to be replaced. + beforeReplacements, + // This is what's expected when 'beforeReplacements' is replaced. + afterReplacements, +}) => { + subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + let urlBeforeReplacements = createTrackerURL(window.location.origin, uuid, 'track_get', beforeReplacements); + let urlAfterReplacements = createTrackerURL(window.location.origin, uuid, 'track_get', afterReplacements); + interestGroupOverrides.ads = [{ renderURL: urlBeforeReplacements }]; + await joinInterestGroup(test, uuid, interestGroupOverrides); + + await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfigOverrides); + await waitForObservedRequests( + uuid, + [urlAfterReplacements, createSellerReportURL(uuid), createBidderReportURL(uuid)]); + }, name); +}; + +makeTest({ + name: 'Replacements with brackets.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '${EXAMPLE-MACRO}': 'SSP' } + }, + beforeReplacements: "${EXAMPLE-MACRO}", + afterReplacements: 'SSP', + +}); + +makeTest({ + name: 'Replacements with percents.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '%%EXAMPLE-MACRO%%': 'SSP' } + }, + beforeReplacements: "%%EXAMPLE-MACRO%%", + afterReplacements: 'SSP', +}); + +makeTest({ + name: 'Multiple replacements within a URL.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '${EXAMPLE-MACRO1}': 'SSP1', '%%EXAMPLE-MACRO2%%': 'SSP2' } + }, + beforeReplacements: "${EXAMPLE-MACRO1}/%%EXAMPLE-MACRO2%%", + afterReplacements: 'SSP1/SSP2', +}); + +makeTest({ + name: 'Recursive and reduce size with brackets.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '${1}': '1' } + }, + beforeReplacements: "${${${1}}}", + afterReplacements: "${${1}}" +}); + +makeTest({ + name: 'Recursive and increase size with brackets.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '${1}': '${${1}}' } + }, + beforeReplacements: "${1}", + afterReplacements: "${${1}}" +}); + +makeTest({ + name: 'Replacements use a single pass with brackets.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '${1}': '${2}', '${2}': '${1}' } + }, + beforeReplacements: "${1}${2}", + afterReplacements: "${2}${1}" +}); + +makeTest({ + name: 'Multiple instances of same substitution string with brackets.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '${1}': '${2}' } + }, + beforeReplacements: "{${1}${1}}", + afterReplacements: "{${2}${2}}" +}); + +makeTest({ + name: 'Mismatched replacement with brackets.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '${2}': '${1}' } + }, + beforeReplacements: "${1}", + afterReplacements: "${1}" +}); + +makeTest({ + name: 'Recursive and reduce size with percents.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '%%1%%': '1' } + }, + beforeReplacements: "%%%%1%%%%", + afterReplacements: "%%1%%" +}); + +makeTest({ + name: 'Recursive and increase size with percents.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '%%1%%': '%%%%1%%%%' } + }, + beforeReplacements: "%%1%%", + afterReplacements: "%%%%1%%%%" +}); + +makeTest({ + name: 'Replacements use a single pass with percents.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '%%1%%': '%%2%%', '%%2%%': '%%1%%' } + }, + beforeReplacements: "%%1%%%%2%%", + afterReplacements: "%%2%%%%1%%" +}); + +makeTest({ + name: 'Multiple instances of same substitution string with percents.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '%%1%%': '%%2%%' } + }, + beforeReplacements: "%%1%%%%1%%", + afterReplacements: "%%2%%%%2%%" +}); + +makeTest({ + name: 'Mismatched replacement with percents.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '%%2%%': '%%1%%' } + }, + beforeReplacements: "%%1%%", + afterReplacements: "%%1%%" +}); + +makeTest({ + name: 'Case sensativity.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '%%foo%%': '%%bar%%' } + }, + beforeReplacements: "%%FOO%%%%foo%%", + afterReplacements: "%%FOO%%%%bar%%" +}); + +makeTest({ + name: 'Super macro, a macro with a macro inside it basically, with percents.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '%%%%foo%%%%': 'foo' } + }, + beforeReplacements: "%%%%foo%%%%", + afterReplacements: "foo" +}); + +makeTest({ + name: 'Super macro, with brackets.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '${${foo}}': 'foo' } + }, + beforeReplacements: "${${foo}}", + afterReplacements: "foo" +}); + +makeTest({ + name: 'Super macro, with both.', + auctionConfigOverrides: { + deprecatedRenderURLReplacements: { '${%%foo%%}': 'foo', '%%${bar}%%':'bar' } + }, + beforeReplacements: "${%%foo%%}%%${bar}%%", + afterReplacements: "foobar" +});
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_1-5-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_1-5-expected.txt new file mode 100644 index 0000000..7f0d1628 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_1-5-expected.txt
@@ -0,0 +1,13 @@ +This is a testharness.js-based test. +[FAIL] Replacements with brackets. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${EXAMPLE-MACRO}" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +[FAIL] Replacements with percents. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%EXAMPLE-MACRO%%" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +[FAIL] Multiple replacements within a URL. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${EXAMPLE-MACRO1}/%%EXAMPLE-MACRO2%%" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=SSP1/SSP2", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +[FAIL] Recursive and reduce size with brackets. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${${${1}}}" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${${1}}", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +[FAIL] Recursive and increase size with brackets. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${1}" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${${1}}", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_11-15-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_11-15-expected.txt new file mode 100644 index 0000000..661d001 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_11-15-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +[FAIL] Replacements use a single pass with percents. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%1%%%%2%%" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%2%%%%1%%", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +[FAIL] Multiple instances of same substitution string with percents. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%1%%%%1%%" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%2%%%%2%%", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +[FAIL] Case sensativity. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%FOO%%%%foo%%" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%FOO%%%%bar%%", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +[FAIL] Super macro, a macro with a macro inside it basically, with percents. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%%%foo%%%%" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=foo", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_16-last-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_16-last-expected.txt new file mode 100644 index 0000000..ccdfedec --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_16-last-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +[FAIL] Super macro, with brackets. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${${foo}}" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=foo", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +[FAIL] Super macro, with both. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${%%foo%%}%%${bar}%%" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=foobar", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_6-10-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_6-10-expected.txt new file mode 100644 index 0000000..8462c72 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_6-10-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +[FAIL] Replacements use a single pass with brackets. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${1}${2}" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=${2}${1}", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +[FAIL] Multiple instances of same substitution string with brackets. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id={${1}${1}}" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id={${2}${2}}"] +[FAIL] Recursive and reduce size with percents. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%%%1%%%%" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%1%%", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +[FAIL] Recursive and increase size with percents. + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%1%%" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=%%%%1%%%%", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1", "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=seller_report_1"] +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/kanon-status-below-threshold.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/kanon-status-below-threshold.https.window-expected.txt index 89e64d0..e27cfa4 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/kanon-status-below-threshold.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/kanon-status-below-threshold.https.window-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] Check kAnonStatus is "belowThreshold" when FledgeConsiderKAnonymityis enabled and FledgeEnforceKAnonymity is disabled - assert_array_equals: expected property 0 to be "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1" but got "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_error" (expected array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1"] got ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_error"]) + assert_in_array: value "https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_error" not in array ["https://web-platform.test:8444/fledge/tentative/resources/request-tracker.py?uuid=<uuid>&dispatch=track_get&id=bidder_report_1"] Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.sub.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.sub.js index 32162e93..a7d0f63 100644 --- a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.sub.js +++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.sub.js
@@ -151,19 +151,21 @@ trackedRequests = trackedRequests.filter(filter); } - // If expected number of requests have been observed, compare with list of - // all expected requests and exit. - if (trackedRequests.length >= expectedRequests.length) { - assert_array_equals(trackedRequests, expectedRequests); - break; - } - // If fewer than total number of expected requests have been observed, // compare what's been received so far, to have a greater chance to fail // rather than hang on error. for (const trackedRequest of trackedRequests) { assert_in_array(trackedRequest, expectedRequests); } + + // If expected number of requests have been observed, compare with list of + // all expected requests and exit. This check was previously before the for loop, + // but was swapped in order to avoid flakiness with failing tests and their + // respective *-expected.txt. + if (trackedRequests.length >= expectedRequests.length) { + assert_array_equals(trackedRequests, expectedRequests); + break; + } } } @@ -839,3 +841,21 @@ fetchAdditionalBids: fetchAdditionalBids }; }(); + + +// DeprecatedRenderURLReplacements helper function. +// Returns an object containing sample strings both before and after the +// replacements in 'replacements' have been applied by +// deprecatedRenderURLReplacements. All substitution strings will appear +// only once in the output strings. +function createStringBeforeAndAfterReplacements(deprecatedRenderURLReplacements) { + let beforeReplacements = ''; + let afterReplacements = ''; + if(deprecatedRenderURLReplacements){ + for (const [match, replacement] of Object.entries(deprecatedRenderURLReplacements)) { + beforeReplacements += match + "/"; + afterReplacements += replacement + "/"; + } + } + return { beforeReplacements, afterReplacements }; +}
diff --git a/third_party/blink/web_tests/external/wpt/focus/cross-origin-ancestor-activeelement-after-child-lose-focus.sub.html b/third_party/blink/web_tests/external/wpt/focus/cross-origin-ancestor-activeelement-after-child-lose-focus.sub.html index 35844bc9..1b84b43f 100644 --- a/third_party/blink/web_tests/external/wpt/focus/cross-origin-ancestor-activeelement-after-child-lose-focus.sub.html +++ b/third_party/blink/web_tests/external/wpt/focus/cross-origin-ancestor-activeelement-after-child-lose-focus.sub.html
@@ -20,36 +20,32 @@ const innerIFrame = outerIFrame.contentDocument.createElement("iframe"); - window.onmessage = function() { + window.onmessage = function(event) { + if (event.data != "ready") { + return; + } + + // We receive an message when the innerIFrame is ready and its input is focused. + // outerIframe is the ancestor of inner iframe, so the activeElement of + // it should be the inner iframe. + assert_equals(outerIFrame.contentDocument.activeElement, innerIFrame, + "The activeElement of the outer iframe should be the inner iframe"); + + // Now we focus the input in the top level + document.querySelector("input").focus(); + // Wait for a bit to let whatever the code that might change the focus to run window.requestAnimationFrame(function() { window.requestAnimationFrame(function() { window.requestAnimationFrame(function() { - - // We receive an message when the innerIFrame is ready and its input is focused. - // outerIframe is the ancestor of inner iframe, so the activeElement of - // it should be the inner iframe. - assert_equals(outerIFrame.contentDocument.activeElement, innerIFrame, - "The activeElement of the outer iframe should be the inner iframe"); - - // Now we focus the input in the top level - document.querySelector("input").focus(); - - // Wait for a bit to let whatever the code that might change the focus to run - window.requestAnimationFrame(function() { - window.requestAnimationFrame(function() { - window.requestAnimationFrame(function() { - // Since inner iframe lost its focus, the activeElement of outer iframe - // should be cleared as well, hence <body> should be focused. - assert_equals(outerIFrame.contentDocument.activeElement, outerIFrame.contentDocument.body, - "The activeElement of the outer iframe should be reverted back to <body>"); - assert_equals(document.activeElement, document.querySelector("input"), - "The activeElement of the top-level document should the input"); - done(); - }); - }); - }); - }); + // Since inner iframe lost its focus, the activeElement of outer iframe + // should be cleared as well, hence <body> should be focused. + assert_equals(outerIFrame.contentDocument.activeElement, outerIFrame.contentDocument.body, + "The activeElement of the outer iframe should be reverted back to <body>"); + assert_equals(document.activeElement, document.querySelector("input"), + "The activeElement of the top-level document should the input"); + done(); + }) }); }); }
diff --git a/third_party/blink/web_tests/external/wpt/focus/support/cross-origin-ancestor-activeelement-after-child-lose-focus-helper.html b/third_party/blink/web_tests/external/wpt/focus/support/cross-origin-ancestor-activeelement-after-child-lose-focus-helper.html index 83d39d5..fe966145 100644 --- a/third_party/blink/web_tests/external/wpt/focus/support/cross-origin-ancestor-activeelement-after-child-lose-focus-helper.html +++ b/third_party/blink/web_tests/external/wpt/focus/support/cross-origin-ancestor-activeelement-after-child-lose-focus-helper.html
@@ -2,8 +2,10 @@ <body> <input /> <script> - document.querySelector("input").focus(); - window.parent.parent.postMessage("ready", '*'); + window.onload = function() { + document.querySelector("input").focus(); + window.parent.parent.postMessage("ready", '*'); + } </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/resources/testdriver.js b/third_party/blink/web_tests/external/wpt/resources/testdriver.js index 20140b2..2d1a8969 100644 --- a/third_party/blink/web_tests/external/wpt/resources/testdriver.js +++ b/third_party/blink/web_tests/external/wpt/resources/testdriver.js
@@ -1023,6 +1023,49 @@ */ get_virtual_sensor_information: function(sensor_type, context=null) { return window.test_driver_internal.get_virtual_sensor_information(sensor_type, context); + }, + + /** + * Overrides device posture set by hardware. + * + * Matches the `Set device posture + * <https://w3c.github.io/device-posture/#set-device-posture>`_ + * WebDriver command. + * + * @param {String} posture - A `DevicePostureType + * <https://w3c.github.io/device-posture/#dom-deviceposturetype>`_ + * either "continuous" or "folded". + * @param {WindowProxy} [context=null] - Browsing context in which to + * run the call, or null for the + * current browsing context. + * + * @returns {Promise} Fulfilled when device posture is set. + * Rejected in case the WebDriver command errors out + * (including if a device posture of the given type + * does not exist). + */ + set_device_posture: function(posture, context=null) { + return window.test_driver_internal.set_device_posture(posture, context); + }, + + /** + * Removes device posture override and returns device posture control + * back to hardware. + * + * Matches the `Clear device posture + * <https://w3c.github.io/device-posture/#clear-device-posture>`_ + * WebDriver command. + * + * @param {WindowProxy} [context=null] - Browsing context in which to + * run the call, or null for the + * current browsing context. + * + * @returns {Promise} Fulfilled after the device posture override has + * been removed. Rejected in case the WebDriver + * command errors out. + */ + clear_device_posture: function(context=null) { + return window.test_driver_internal.clear_device_posture(context); } }; @@ -1203,6 +1246,14 @@ async get_virtual_sensor_information(sensor_type, context=null) { throw new Error("get_virtual_sensor_information() is not implemented by testdriver-vendor.js"); + }, + + async set_device_posture(posture, context=null) { + throw new Error("set_device_posture() is not implemented by testdriver-vendor.js"); + }, + + async clear_device_posture(context=null) { + throw new Error("clear_device_posture() is not implemented by testdriver-vendor.js"); } }; })();
diff --git a/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/README.md b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/README.md new file mode 100644 index 0000000..fb0975f --- /dev/null +++ b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/README.md
@@ -0,0 +1,5 @@ +This directory is to test deprecatedRenderURLReplacements within Protected Audience with FLEDGE (https://github.com/WICG/turtledove/blob/main/FLEDGE.md) on. + +If the `CookieDeprecationFacilitatedTesting` flag is on, we turn off `deprecatedRenderURLReplacements`. + +This virtual test is needed to disable `CookieDeprecationFacilitatedTesting` but allow for FLEDGE to be enabled. This way we will properly be able to test `deprecatedRenderURLReplacements`. \ No newline at end of file
diff --git a/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/auction-config-passed-to-worklets.https.window_1-5-expected.txt b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/auction-config-passed-to-worklets.https.window_1-5-expected.txt new file mode 100644 index 0000000..d2490db --- /dev/null +++ b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/auction-config-passed-to-worklets.https.window_1-5-expected.txt
@@ -0,0 +1,3 @@ +This is a testharness.js-based test. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/auction-config.https.window_1-5-expected.txt b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/auction-config.https.window_1-5-expected.txt new file mode 100644 index 0000000..d2490db --- /dev/null +++ b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/auction-config.https.window_1-5-expected.txt
@@ -0,0 +1,3 @@ +This is a testharness.js-based test. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/auction-config.https.window_6-10-expected.txt b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/auction-config.https.window_6-10-expected.txt new file mode 100644 index 0000000..d2490db --- /dev/null +++ b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/auction-config.https.window_6-10-expected.txt
@@ -0,0 +1,3 @@ +This is a testharness.js-based test. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/component-ads.https.window_16-last-expected.txt b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/component-ads.https.window_16-last-expected.txt new file mode 100644 index 0000000..d2490db --- /dev/null +++ b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/component-ads.https.window_16-last-expected.txt
@@ -0,0 +1,3 @@ +This is a testharness.js-based test. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/component-auction.https.window_16-last-expected.txt b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/component-auction.https.window_16-last-expected.txt new file mode 100644 index 0000000..d2490db --- /dev/null +++ b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/component-auction.https.window_16-last-expected.txt
@@ -0,0 +1,3 @@ +This is a testharness.js-based test. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_1-5-expected.txt b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_1-5-expected.txt new file mode 100644 index 0000000..d2490db --- /dev/null +++ b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_1-5-expected.txt
@@ -0,0 +1,3 @@ +This is a testharness.js-based test. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_11-15-expected.txt b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_11-15-expected.txt new file mode 100644 index 0000000..d2490db --- /dev/null +++ b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_11-15-expected.txt
@@ -0,0 +1,3 @@ +This is a testharness.js-based test. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_16-last-expected.txt b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_16-last-expected.txt new file mode 100644 index 0000000..d2490db --- /dev/null +++ b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_16-last-expected.txt
@@ -0,0 +1,3 @@ +This is a testharness.js-based test. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_6-10-expected.txt b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_6-10-expected.txt new file mode 100644 index 0000000..d2490db --- /dev/null +++ b/third_party/blink/web_tests/virtual/fledge-deprecated-render-url-replacements/external/wpt/fledge/tentative/deprecated-render-url-replacements.https.window_6-10-expected.txt
@@ -0,0 +1,3 @@ +This is a testharness.js-based test. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index bcc52e4b..18ab9a7 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -2936,11 +2936,13 @@ getter longitude getter speed method constructor + method toJSON interface GeolocationPosition attribute @@toStringTag getter coords getter timestamp method constructor + method toJSON interface GeolocationPositionError attribute @@toStringTag attribute PERMISSION_DENIED
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index 3397c6d..83481d7d 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -3450,11 +3450,13 @@ getter longitude getter speed method constructor + method toJSON interface GeolocationPosition attribute @@toStringTag getter coords getter timestamp method constructor + method toJSON interface GeolocationPositionError attribute @@toStringTag attribute PERMISSION_DENIED
diff --git a/third_party/blink/web_tests/wpt_internal/geolocation-api/json.https.html b/third_party/blink/web_tests/wpt_internal/geolocation-api/json.https.html new file mode 100644 index 0000000..67711f33 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/geolocation-api/json.https.html
@@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/testharness-adapter.js"></script> +</head> +<body> +<script type="module"> +import {GeolocationMock} from './resources/geolocation-mock.js'; + +async_test((t) => { + const mockCoords = {accuracy: 100, + latitude: 51.478, + longitude: -0.166, + altitude: null, + altitudeAccuracy: null, + heading: null, + speed: null}; + + const mock = new GeolocationMock(); + mock.setGeolocationPermission(true); + mock.setGeolocationPosition(mockCoords.latitude, + mockCoords.longitude, + mockCoords.accuracy); + + navigator.geolocation.getCurrentPosition(t.step_func_done((position) => { + assert_object_equals(position.coords.toJSON(), mockCoords); + + const timestamp = position.timestamp; + const expectedPosition = {timestamp, coords: mockCoords}; + assert_object_equals(position.toJSON(), expectedPosition); + }), t.step_func_done((e) => { + assert_unreached('Error callback invoked unexpectedly'); + })); +}, "Tests toJSON() on GeolocationPosition and GeolocationCoordinates."); +</script> +</body> +</html>
diff --git a/third_party/catapult b/third_party/catapult index 7d44c80..e939ac7 160000 --- a/third_party/catapult +++ b/third_party/catapult
@@ -1 +1 @@ -Subproject commit 7d44c8067842719b399fb10f625e573e29cb723b +Subproject commit e939ac77bb9471acc10f49e82cfe65790068c3d1
diff --git a/third_party/chromite b/third_party/chromite index edee6b1..8af9063 160000 --- a/third_party/chromite +++ b/third_party/chromite
@@ -1 +1 @@ -Subproject commit edee6b1f898f39a0e19e99d28be674a1aaa546a3 +Subproject commit 8af906338f6c07813067abf296170c8a4f46c538
diff --git a/third_party/depot_tools b/third_party/depot_tools index ed3d513..af97284 160000 --- a/third_party/depot_tools +++ b/third_party/depot_tools
@@ -1 +1 @@ -Subproject commit ed3d513241532dbea8e324ec9e1fe767bd75bddf +Subproject commit af97284b58afb6bdb7dd2b353bc651c718ce5bb4
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal index 904930d..84f6810 160000 --- a/third_party/devtools-frontend-internal +++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@ -Subproject commit 904930d0bf12b7030892a118a2d2a6817dde61a3 +Subproject commit 84f68106afc210db30fb1efa8f76425cb067e82b
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 7c7726e..42135e49 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-13-2-113-gd091bca54 -Revision: d091bca546fa15928db36c8447e126ee43ddb5f4 +Version: VER-2-13-2-114-g12adfc212 +Revision: 12adfc212bd2f7560e1e175e66458124f9bd554b CPEPrefix: cpe:/a:freetype:freetype:2.13.2 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses"
diff --git a/third_party/freetype/src b/third_party/freetype/src index d091bca..12adfc2 160000 --- a/third_party/freetype/src +++ b/third_party/freetype/src
@@ -1 +1 @@ -Subproject commit d091bca546fa15928db36c8447e126ee43ddb5f4 +Subproject commit 12adfc212bd2f7560e1e175e66458124f9bd554b
diff --git a/third_party/openscreen/src b/third_party/openscreen/src index 624f91b..dcd61df 160000 --- a/third_party/openscreen/src +++ b/third_party/openscreen/src
@@ -1 +1 @@ -Subproject commit 624f91b189a5a6fd35b1d3c43c60678c1f111dff +Subproject commit dcd61dfe0e1e6c27d6d48fd4a29a9117e7d4b666
diff --git a/third_party/perfetto b/third_party/perfetto index f6656e9..234fd02 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit f6656e9828f5a5a5358d0782bd4d5cdecdc652f5 +Subproject commit 234fd02711c642ec5211da272283db8fd8d91af4
diff --git a/third_party/skia b/third_party/skia index 2790777..a3a0165 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit 2790777048d3f00384f68be8081f3a3db615746c +Subproject commit a3a016537a8c512df42b50522e78710b320c0faf
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps index 01c82a0..6066c0d 160000 --- a/third_party/vulkan-deps +++ b/third_party/vulkan-deps
@@ -1 +1 @@ -Subproject commit 01c82a000dcec3cc0452ef2faee80167fd788b79 +Subproject commit 6066c0d57a8bd7d68060336c7b01eeb9a1271589
diff --git a/third_party/webgpu-cts/src b/third_party/webgpu-cts/src index 11eade5..0da8f2f 160000 --- a/third_party/webgpu-cts/src +++ b/third_party/webgpu-cts/src
@@ -1 +1 @@ -Subproject commit 11eade521a44d63af95cc72cfbbfa6c6becf972f +Subproject commit 0da8f2f1189d05814b5bbfd770f362928f2fb829
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt index 141cba8..2ecce13 100644 --- a/third_party/webgpu-cts/ts_sources.txt +++ b/third_party/webgpu-cts/ts_sources.txt
@@ -824,6 +824,12 @@ src/webgpu/shader/validation/expression/call/builtin/unpack4xI8.spec.ts src/webgpu/shader/validation/expression/call/builtin/unpack4xU8.spec.ts src/webgpu/shader/validation/expression/call/builtin/workgroupUniformLoad.spec.ts +src/webgpu/shader/validation/expression/matrix/add_sub.spec.ts +src/webgpu/shader/validation/expression/matrix/and_or_xor.spec.ts +src/webgpu/shader/validation/expression/matrix/bitwise_shift.spec.ts +src/webgpu/shader/validation/expression/matrix/comparison.spec.ts +src/webgpu/shader/validation/expression/matrix/div_rem.spec.ts +src/webgpu/shader/validation/expression/matrix/mul.spec.ts src/webgpu/shader/validation/expression/unary/address_of_and_indirection.spec.ts src/webgpu/shader/validation/expression/unary/arithmetic_negation.spec.ts src/webgpu/shader/validation/expression/unary/bitwise_complement.spec.ts @@ -879,6 +885,7 @@ src/webgpu/shader/validation/shader_io/locations.spec.ts src/webgpu/shader/validation/shader_io/size.spec.ts src/webgpu/shader/validation/shader_io/workgroup_size.spec.ts +src/webgpu/shader/validation/statement/break_if.spec.ts src/webgpu/shader/validation/statement/for.spec.ts src/webgpu/shader/validation/statement/if.spec.ts src/webgpu/shader/validation/statement/increment_decrement.spec.ts
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 4abf9551..e559d5f 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -2700,18 +2700,6 @@ <int value="3" label="Dismissed"/> </enum> -<enum name="CampaignButtonId"> - <int value="0" label="Primary button"/> - <int value="1" label="Secondary button"/> -</enum> - -<enum name="CampaignSlot"> - <int value="0" label="Demo Mode App"/> - <int value="1" label="Demo Mode Free Play Apps"/> - <int value="2" label="Nudge"/> - <int value="3" label="Notification"/> -</enum> - <enum name="CanaryCheckLookupResult"> <int value="0" label="Success"/> <int value="1" label="Failure"/>
diff --git a/tools/metrics/histograms/histograms_xml_files.gni b/tools/metrics/histograms/histograms_xml_files.gni index 2ab6cf7..dcc7c03 100644 --- a/tools/metrics/histograms/histograms_xml_files.gni +++ b/tools/metrics/histograms/histograms_xml_files.gni
@@ -14,6 +14,8 @@ "//tools/metrics/histograms/metadata/ash/histograms.xml", "//tools/metrics/histograms/metadata/ash_clipboard/enums.xml", "//tools/metrics/histograms/metadata/ash_clipboard/histograms.xml", + "//tools/metrics/histograms/metadata/ash_growth/enums.xml", + "//tools/metrics/histograms/metadata/ash_growth/histograms.xml", "//tools/metrics/histograms/metadata/ash_user_education/enums.xml", "//tools/metrics/histograms/metadata/ash_user_education/histograms.xml", "//tools/metrics/histograms/metadata/assistant/histograms.xml",
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index 265ff55..fa6649aa 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -2146,7 +2146,7 @@ </histogram> <histogram name="Android.Messages.Error.FullyVisibleNotInformed" - enum="MessageIdentifier" expires_after="2024-05-19"> + enum="MessageIdentifier" expires_after="2024-09-29"> <owner>lazzzis@chromium.org</owner> <owner>src/components/messages/OWNERS</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index ed59586..20db0bd 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -202,12 +202,6 @@ install should be very quick and always succeed."/> </variants> -<variants name="CampaignButtonId"> - <variant name="0" summary="Primary"/> - <variant name="1" summary="Secondary"/> - <variant name="2" summary="Others"/> -</variants> - <variants name="DisplayModes"> <!-- Should be kept in sync with variants AppDisplayModes in tools/metrics/histograms/metadata/apps/histograms.xml. @@ -4193,105 +4187,6 @@ </token> </histogram> -<histogram name="Ash.Growth.CampaignsComponent.DownloadDurationInOobe" - units="ms" expires_after="2024-10-17"> - <owner>llin@google.com</owner> - <owner>cros-growth@google.com</owner> - <summary> - The amount of time in ms that the Campaigns Manager takes to download the - campaigns component from Omaha. Recorded when a component loading complete - in the OOBE flow. This metric is splitted from - Ash.Growth.CampaignsComponent.DownloadDuration in M124. - </summary> -</histogram> - -<histogram name="Ash.Growth.CampaignsComponent.DownloadDurationSessionStart" - units="ms" expires_after="2024-10-17"> - <owner>llin@google.com</owner> - <owner>cros-growth@google.com</owner> - <summary> - The amount of time in ms that the Campaigns Manager takes to download the - campaigns component from Omaha. Recorded when a component loading complete - at session start. This metric is splitted from - Ash.Growth.CampaignsComponent.DownloadDuration in M124. - </summary> -</histogram> - -<histogram name="Ash.Growth.CampaignsComponent.ParseDuration" units="ms" - expires_after="2024-10-17"> - <owner>llin@google.com</owner> - <owner>cros-growth@google.com</owner> - <summary> - The amount of time in ms that the Campaigns Manager takes to read and parsed - (as JSON) from disk. Recorded when a component is loaded into Campaign - Matcher. - </summary> -</histogram> - -<histogram name="Ash.Growth.CampaignsManager.Error" - enum="CampaignsManagerError" expires_after="2024-10-17"> - <owner>llin@google.com</owner> - <owner>cros-growth@google.com</owner> - <summary> - Tracks unexpected error while loading and matching campaigns, recorded each - time an unexpected error occurs. - </summary> -</histogram> - -<histogram name="Ash.Growth.CampaignsManager.GetCampaignBySlot" - enum="CampaignSlot" expires_after="2024-10-17"> - <owner>llin@google.com</owner> - <owner>cros-growth@google.com</owner> - <summary> - Tracks the slot of the fetched campaign, recorded each time a campaign is - fetched. - </summary> -</histogram> - -<histogram name="Ash.Growth.CampaignsManager.MatchDuration" units="ms" - expires_after="2024-10-17"> - <owner>llin@google.com</owner> - <owner>cros-growth@google.com</owner> - <summary> - The amount of time in ms that the Campaigns Manager takes to match a - campaign based on the targeting criteria. Recorded when fetching a campaign - for a particular slot completed. - </summary> -</histogram> - -<histogram name="Ash.Growth.Ui.ButtonPressed.Button{ButtonId}.Campaigns500" - units="int" expires_after="2025-03-01"> - <owner>wutao@chromium.org</owner> - <owner>cros-growth@google.com</owner> - <summary> - Recorded when the button of {ButtonId} in the UI is pressed. The bucket is - indexed by the campaign_id. The campaign_id recorded in this histogram - should be less than 500. - </summary> - <token key="ButtonId" variants="CampaignButtonId"/> -</histogram> - -<histogram name="Ash.Growth.Ui.Dismissed.Campaigns500" units="int" - expires_after="2025-03-01"> - <owner>wutao@chromium.org</owner> - <owner>cros-growth@google.com</owner> - <summary> - Recorded when the UI is dismissed. The bucket is indexed by the campaign_id. - The campaign_id recorded in this histogram should be less than 500. - </summary> -</histogram> - -<histogram name="Ash.Growth.Ui.Impression.Campaigns500" units="int" - expires_after="2025-03-01"> - <owner>wutao@chromium.org</owner> - <owner>cros-growth@google.com</owner> - <summary> - Recorded when it is ready to log a UI impression. Normally this is called - right after a call to show the UI. The bucket is indexed by the campaign_id. - The campaign_id recorded in this histogram should be less than 500. - </summary> -</histogram> - <histogram name="Ash.Homescreen.AnimationSmoothness" units="%" expires_after="2024-09-01"> <owner>sammiequon@chromium.org</owner> @@ -5401,8 +5296,8 @@ <summary> Tracks the time from when a specific educational nudge is shown to when it's interacted with. Starts measuring time when the nudge is shown and records - the Nudge catalog name in one of the time buckets available if the user - performs the nudge's suggested action. + the Nudge catalog name in one of the `TimeRange` buckets if the user + performs the nudge's suggested action. These buckets are all exclusive. </summary> <token key="TimeRange"> <variant name="Within1h"/>
diff --git a/tools/metrics/histograms/metadata/ash_growth/enums.xml b/tools/metrics/histograms/metadata/ash_growth/enums.xml new file mode 100644 index 0000000..a14f543c --- /dev/null +++ b/tools/metrics/histograms/metadata/ash_growth/enums.xml
@@ -0,0 +1,38 @@ +<!-- +Copyright 2024 The Chromium Authors +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> + +<!-- + +This file describes the enumerations referenced by entries in histograms.xml for +this directory. Some enums may instead be listed in the central enums.xml file +at src/tools/metrics/histograms/enums.xml when multiple files use them. + +For best practices on writing enumerations descriptions, see +https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#Enum-Histograms + +Please follow the instructions in the OWNERS file in this directory to find a +reviewer. If no OWNERS file exists, please consider signing up at +go/reviewing-metrics (Googlers only), as all subdirectories are expected to +have an OWNERS file. As a last resort you can send the CL to +chromium-metrics-reviews@google.com. +--> + +<histogram-configuration> + +<!-- Enum types --> + +<enums> + +<enum name="CampaignSlot"> + <int value="0" label="Demo Mode App"/> + <int value="1" label="Demo Mode Free Play Apps"/> + <int value="2" label="Nudge"/> + <int value="3" label="Notification"/> +</enum> + +</enums> + +</histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/ash_growth/histograms.xml b/tools/metrics/histograms/metadata/ash_growth/histograms.xml new file mode 100644 index 0000000..df2740c --- /dev/null +++ b/tools/metrics/histograms/metadata/ash_growth/histograms.xml
@@ -0,0 +1,131 @@ +<!-- +Copyright 2024 The Chromium Authors +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> + +<!-- +This file is used to generate a comprehensive list of Ash histograms +along with a detailed description for each histogram. + +For best practices on writing histogram descriptions, see +https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md + +Please follow the instructions in the OWNERS file in this directory to find a +reviewer. If no OWNERS file exists, please consider signing up at +go/reviewing-metrics (Googlers only), as all subdirectories are expected to +have an OWNERS file. As a last resort you can send the CL to +chromium-metrics-reviews@google.com. +--> + +<histogram-configuration> + +<histograms> + +<variants name="CampaignButtonId"> + <variant name="0" summary="Primary"/> + <variant name="1" summary="Secondary"/> + <variant name="2" summary="Others"/> +</variants> + +<histogram name="Ash.Growth.CampaignsComponent.DownloadDurationInOobe" + units="ms" expires_after="2024-10-17"> + <owner>llin@google.com</owner> + <owner>cros-growth@google.com</owner> + <summary> + Records the time (in ms) the Campaigns Manager takes to download the + campaigns component from Omaha during OOBE flow. Recorded when loading the + campaigns component in OOBE flow has completed. This metric was split from + Ash.Growth.CampaignsComponent.DownloadDuration in M124. + </summary> +</histogram> + +<histogram name="Ash.Growth.CampaignsComponent.DownloadDurationSessionStart" + units="ms" expires_after="2024-10-17"> + <owner>llin@google.com</owner> + <owner>cros-growth@google.com</owner> + <summary> + Records the time (in ms) the Campaigns Manager takes to download the + campaigns component from Omaha during session start. Recorded when loading + the campaigns component at session start has completed. This metric was + split from Ash.Growth.CampaignsComponent.DownloadDuration in M124. + </summary> +</histogram> + +<histogram name="Ash.Growth.CampaignsComponent.ParseDuration" units="ms" + expires_after="2024-10-17"> + <owner>llin@google.com</owner> + <owner>cros-growth@google.com</owner> + <summary> + Records the time (in ms) the Campaigns Manager takes to read and parsed (as + JSON) from disk. Recorded when a component is loaded into Campaign Matcher. + </summary> +</histogram> + +<histogram name="Ash.Growth.CampaignsManager.Error" + enum="CampaignsManagerError" expires_after="2024-10-17"> + <owner>llin@google.com</owner> + <owner>cros-growth@google.com</owner> + <summary> + Tracks unexpected error while loading and matching campaigns. Recorded each + time an unexpected error occurs. + </summary> +</histogram> + +<histogram name="Ash.Growth.CampaignsManager.GetCampaignBySlot" + enum="CampaignSlot" expires_after="2024-10-17"> + <owner>llin@google.com</owner> + <owner>cros-growth@google.com</owner> + <summary> + Tracks the slot of the fetched campaign. Recorded each time a campaign is + fetched. + </summary> +</histogram> + +<histogram name="Ash.Growth.CampaignsManager.MatchDuration" units="ms" + expires_after="2024-10-17"> + <owner>llin@google.com</owner> + <owner>cros-growth@google.com</owner> + <summary> + Records the time (in ms) the Campaigns Manager takes to match a campaign + based on the targeting criteria. Recorded when fetching a campaign for a + particular slot completed. + </summary> +</histogram> + +<histogram name="Ash.Growth.Ui.ButtonPressed.Button{ButtonId}.Campaigns500" + units="int" expires_after="2025-03-01"> + <owner>wutao@chromium.org</owner> + <owner>cros-growth@google.com</owner> + <summary> + Recorded when the button of {ButtonId} in the UI is pressed. The bucket is + indexed by the campaign_id. The campaign_id recorded in this histogram + should be less than 500. + </summary> + <token key="ButtonId" variants="CampaignButtonId"/> +</histogram> + +<histogram name="Ash.Growth.Ui.Dismissed.Campaigns500" units="int" + expires_after="2025-03-01"> + <owner>wutao@chromium.org</owner> + <owner>cros-growth@google.com</owner> + <summary> + Recorded when the UI is dismissed. The bucket is indexed by the campaign_id. + The campaign_id recorded in this histogram should be less than 500. + </summary> +</histogram> + +<histogram name="Ash.Growth.Ui.Impression.Campaigns500" units="int" + expires_after="2025-03-01"> + <owner>wutao@chromium.org</owner> + <owner>cros-growth@google.com</owner> + <summary> + Recorded when it is ready to log a UI impression. Normally this is called + right after a call to show the UI. The bucket is indexed by the campaign_id. + The campaign_id recorded in this histogram should be less than 500. + </summary> +</histogram> + +</histograms> + +</histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml index e4509caf..fef8d42 100644 --- a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml +++ b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
@@ -226,9 +226,9 @@ <variant name="IPH_iOSDefaultBrowserVideoPromoTrigger" summary="(obsolete) notifying that the conditions to show the default browser video promo have been met."/> - <variant name="IPH_iOSDockingPromoFeature" + <variant name="IPH_iOSDockingPromo" summary="Showing the Docking Promo on iOS"/> - <variant name="IPH_iOSDockingPromoRemindMeLaterFeature" + <variant name="IPH_iOSDockingPromoRemindMeLater" summary="Showing the Docking Promo (Remind Me Later version) on iOS"/> <variant name="IPH_iOSHistoryOnOverflowMenuFeature" summary="history item on the overflow menu on iOS"/>
diff --git a/tools/metrics/histograms/metadata/history/enums.xml b/tools/metrics/histograms/metadata/history/enums.xml index ca4f6a1..2cfd12a 100644 --- a/tools/metrics/histograms/metadata/history/enums.xml +++ b/tools/metrics/histograms/metadata/history/enums.xml
@@ -153,6 +153,13 @@ <int value="5" label="Journeys"/> </enum> +<enum name="HistoryResultType"> + <int value="0" + label="Traditional history search result (reverse chronological list)"/> + <int value="1" label="Grouped history search result"/> + <int value="2" label="Embeddings search result"/> +</enum> + <enum name="OtherSessionsActions"> <int value="0" label="Menu initialized"/> <int value="1" label="Menu shown (deprecated)"/>
diff --git a/tools/metrics/histograms/metadata/history/histograms.xml b/tools/metrics/histograms/metadata/history/histograms.xml index 9a2d243..523dc57 100644 --- a/tools/metrics/histograms/metadata/history/histograms.xml +++ b/tools/metrics/histograms/metadata/history/histograms.xml
@@ -2024,6 +2024,49 @@ </summary> </histogram> +<histogram name="History.SearchResultClicked.Index{HistoryResultType}" + units="index" expires_after="2025-04-15"> + <owner>tommycli@chromium.org</owner> + <owner>orinj@chromium.org</owner> + <summary> + Logs the zero-based index of the result clicked. + + For Embeddings and Traditional history types, this logs the index of the + visit with respect to visits of the same type only. For example, the first + matching Traditional visit has index 0, even though it's displayed below all + Embeddings matches. + + For Grouped history, this logs the index of the visit WITHIN its containing + cluster. This is to match the History.Clusters.UIActions UMAs. + + This does not log anything shown directly in the omnibox suggest surface. + + This UMA is further sliced into per-type slices, and the sum of those + histograms equals the unsliced histogram. The maximum index is 99, and + clicks above that are clamped to that maximum. + </summary> + <token key="HistoryResultType"> + <variant name="" summary="Clicks of all types, unsliced"/> + <variant name=".Embeddings" summary="Embeddings search result"/> + <variant name=".Grouped" + summary="Grouped history search result (index within cluster)"/> + <variant name=".Traditional" + summary="Traditional history search result (reverse chronological + list)"/> + </token> +</histogram> + +<histogram name="History.SearchResultClicked.Type" enum="HistoryResultType" + expires_after="2025-04-15"> + <owner>tommycli@chromium.org</owner> + <owner>orinj@chromium.org</owner> + <summary> + Logs the type of the History result clicked from History UI surfaces. Note, + this does NOT include any results clicked from the omnibox suggest surface, + even if they are History or @history site search suggestions. + </summary> +</histogram> + <histogram name="History.TopSites.QueryFromHistoryTime" units="ms" expires_after="2024-09-15"> <owner>mahmadi@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/settings/histograms.xml b/tools/metrics/histograms/metadata/settings/histograms.xml index 6cb41ef1..b840548e 100644 --- a/tools/metrics/histograms/metadata/settings/histograms.xml +++ b/tools/metrics/histograms/metadata/settings/histograms.xml
@@ -104,6 +104,17 @@ </summary> </histogram> +<histogram name="Settings.FingerprintingProtection.Enabled" + enum="BooleanEnabled" expires_after="2024-12-01"> + <owner>fmacintosh@google.com</owner> + <owner>koilos@google.com</owner> + <summary> + Records the state of the pref that represents whether the user has chosen to + enable Fingerprinting Protection via the Tracking Protection settings page. + Logged on profile startup. + </summary> +</histogram> + <histogram name="Settings.FirstPartySets.State" enum="FirstPartySetsState" expires_after="2024-09-29"> <owner>alimariam@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/sync/enums.xml b/tools/metrics/histograms/metadata/sync/enums.xml index 3a55a76..bb365100 100644 --- a/tools/metrics/histograms/metadata/sync/enums.xml +++ b/tools/metrics/histograms/metadata/sync/enums.xml
@@ -240,6 +240,7 @@ <int value="69" label="AutofillPaymentCardBenefits"/> <int value="70" label="(obsolete) CloseTabs"/> <int value="71" label="ShowTabGroupsInBookmarkBar"/> + <int value="72" label="FacilitatedPaymentsPix"/> <int value="100000" label="AppLanguagePromptShown"/> <int value="100001" label="(Obsolete) PrefExplicitLanguageAskShown"/> <int value="100002" label="ContextualSearchEnabled_Android"/>
diff --git a/tools/metrics/histograms/metadata/uma/histograms.xml b/tools/metrics/histograms/metadata/uma/histograms.xml index 83d08fd..c16665a 100644 --- a/tools/metrics/histograms/metadata/uma/histograms.xml +++ b/tools/metrics/histograms/metadata/uma/histograms.xml
@@ -29,6 +29,8 @@ <variant name="GpuMetrics" summary="For GPU process metrics."/> <variant name="NotificationHelperMetrics" summary="For notification_helper process metrics."/> + <variant name="PlatformExperienceHelperMetrics" + summary="For metrics from Platform Experience Helper"/> <variant name="PpapiBrokerMetrics" summary="For "PPAPI broker" process metrics."/> <variant name="PpapiPluginMetrics" @@ -322,6 +324,7 @@ <token key="Source"> <variant name="DeferredBrowserMetrics"/> <variant name="NotificationHelperMetrics"/> + <variant name="PlatformExperienceHelperMetrics"/> <variant name="SetupMetrics"/> </token> </histogram>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 05dcb732..ad4d5a4 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@ }, "win": { "hash": "0e7ce4cd3c50b2701c0d06407af74aff6c31e1b6", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/6579c4e89c719f2501c5bb5baf20f137c0c35bd4/trace_processor_shell.exe" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/f6656e9828f5a5a5358d0782bd4d5cdecdc652f5/trace_processor_shell.exe" }, "linux_arm": { "hash": "d8e27d961be1db97db098c6826017aec0397ecfd", @@ -21,8 +21,8 @@ "full_remote_path": "perfetto-luci-artifacts/v44.0/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "a0badec3e42334e3ae0063342cf7e7317c2ef05e", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/f6656e9828f5a5a5358d0782bd4d5cdecdc652f5/trace_processor_shell" + "hash": "46f4391cc3ac746ec2ee3fc395eabc19c80dca29", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/234fd02711c642ec5211da272283db8fd8d91af4/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/perf/core/shard_maps/linux-perf_map.json b/tools/perf/core/shard_maps/linux-perf_map.json index 3cf18b5..ce8a2ca1 100644 --- a/tools/perf/core/shard_maps/linux-perf_map.json +++ b/tools/perf/core/shard_maps/linux-perf_map.json
@@ -5,7 +5,7 @@ "abridged": false }, "blink_perf.accessibility": { - "end": 12, + "end": 13, "abridged": false }, "jetstream2": { @@ -31,6 +31,9 @@ ], "abridged": false }, + "speedometer": { + "abridged": false + }, "speedometer2": { "abridged": false }, @@ -63,7 +66,7 @@ "1": { "benchmarks": { "blink_perf.accessibility": { - "begin": 12, + "begin": 13, "abridged": false }, "blink_perf.bindings": { @@ -93,6 +96,9 @@ ], "abridged": false }, + "speedometer": { + "abridged": false + }, "speedometer2": { "abridged": false }, @@ -149,6 +155,9 @@ ], "abridged": false }, + "speedometer": { + "abridged": false + }, "speedometer2": { "abridged": false }, @@ -182,7 +191,7 @@ "abridged": false }, "blink_perf.layout": { - "end": 22, + "end": 21, "abridged": false }, "jetstream2": { @@ -208,6 +217,9 @@ ], "abridged": false }, + "speedometer": { + "abridged": false + }, "speedometer2": { "abridged": false }, @@ -231,8 +243,8 @@ "4": { "benchmarks": { "blink_perf.layout": { - "begin": 22, - "end": 106, + "begin": 21, + "end": 105, "abridged": false }, "jetstream2": { @@ -258,6 +270,9 @@ ], "abridged": false }, + "speedometer": { + "abridged": false + }, "speedometer2": { "abridged": false }, @@ -281,7 +296,7 @@ "5": { "benchmarks": { "blink_perf.layout": { - "begin": 106, + "begin": 105, "abridged": false }, "blink_perf.owp_storage": { @@ -297,7 +312,7 @@ "abridged": false }, "blink_perf.shadow_dom": { - "end": 20, + "end": 18, "abridged": false }, "system_health.common_desktop": { @@ -317,6 +332,9 @@ ], "abridged": false }, + "speedometer": { + "abridged": false + }, "speedometer2": { "abridged": false }, @@ -340,7 +358,7 @@ "6": { "benchmarks": { "blink_perf.shadow_dom": { - "begin": 20, + "begin": 18, "abridged": false }, "blink_perf.svg": { @@ -379,6 +397,9 @@ ], "abridged": false }, + "speedometer": { + "abridged": false + }, "speedometer2": { "abridged": false }, @@ -418,7 +439,7 @@ "abridged": false }, "media.desktop": { - "end": 7, + "end": 6, "abridged": false }, "system_health.common_desktop": { @@ -438,6 +459,9 @@ ], "abridged": false }, + "speedometer": { + "abridged": false + }, "speedometer2": { "abridged": false }, @@ -466,11 +490,11 @@ "8": { "benchmarks": { "media.desktop": { - "begin": 7, + "begin": 6, "abridged": false }, "memory.desktop": { - "end": 2, + "end": 1, "abridged": false }, "system_health.common_desktop": { @@ -490,6 +514,9 @@ ], "abridged": false }, + "speedometer": { + "abridged": false + }, "speedometer2": { "abridged": false }, @@ -513,8 +540,8 @@ "9": { "benchmarks": { "memory.desktop": { - "begin": 2, - "end": 7, + "begin": 1, + "end": 6, "abridged": false }, "system_health.common_desktop": { @@ -534,6 +561,9 @@ ], "abridged": false }, + "speedometer": { + "abridged": false + }, "speedometer2": { "abridged": false }, @@ -557,7 +587,7 @@ "10": { "benchmarks": { "memory.desktop": { - "begin": 7, + "begin": 6, "abridged": false }, "octane": { @@ -567,7 +597,10 @@ "abridged": false }, "power.desktop": { - "end": 8, + "end": 3, + "abridged": false + }, + "speedometer": { "abridged": false }, "speedometer2": { @@ -607,14 +640,17 @@ "11": { "benchmarks": { "power.desktop": { - "begin": 8, + "begin": 3, "abridged": false }, "rasterize_and_record_micro.top_25": { "abridged": false }, "rendering.desktop": { - "end": 24, + "end": 17, + "abridged": false + }, + "speedometer": { "abridged": false }, "speedometer2": { @@ -640,8 +676,11 @@ "12": { "benchmarks": { "rendering.desktop": { - "begin": 24, - "end": 77, + "begin": 17, + "end": 67, + "abridged": false + }, + "speedometer": { "abridged": false }, "speedometer2": { @@ -667,8 +706,11 @@ "13": { "benchmarks": { "rendering.desktop": { - "begin": 77, - "end": 135, + "begin": 67, + "end": 123, + "abridged": false + }, + "speedometer": { "abridged": false }, "speedometer2": { @@ -694,8 +736,11 @@ "14": { "benchmarks": { "rendering.desktop": { - "begin": 135, - "end": 181, + "begin": 123, + "end": 174, + "abridged": false + }, + "speedometer": { "abridged": false }, "speedometer2": { @@ -721,8 +766,11 @@ "15": { "benchmarks": { "rendering.desktop": { - "begin": 181, - "end": 232, + "begin": 174, + "end": 220, + "abridged": false + }, + "speedometer": { "abridged": false }, "speedometer2": { @@ -748,8 +796,11 @@ "16": { "benchmarks": { "rendering.desktop": { - "begin": 232, - "end": 279, + "begin": 220, + "end": 268, + "abridged": false + }, + "speedometer": { "abridged": false }, "speedometer2": { @@ -775,8 +826,11 @@ "17": { "benchmarks": { "rendering.desktop": { - "begin": 279, - "end": 325, + "begin": 268, + "end": 315, + "abridged": false + }, + "speedometer": { "abridged": false }, "speedometer2": { @@ -802,7 +856,7 @@ "18": { "benchmarks": { "rendering.desktop": { - "begin": 325, + "begin": 315, "abridged": false }, "rendering.desktop.notracing": { @@ -839,7 +893,7 @@ "abridged": false }, "system_health.common_desktop": { - "end": 14, + "end": 6, "abridged": false } } @@ -847,8 +901,11 @@ "19": { "benchmarks": { "system_health.common_desktop": { - "begin": 14, - "end": 62, + "begin": 6, + "end": 54, + "abridged": false + }, + "speedometer": { "abridged": false }, "speedometer2": { @@ -874,11 +931,11 @@ "20": { "benchmarks": { "system_health.common_desktop": { - "begin": 62, + "begin": 54, "abridged": false }, "system_health.memory_desktop": { - "end": 15, + "end": 14, "abridged": false } } @@ -886,8 +943,8 @@ "21": { "benchmarks": { "system_health.memory_desktop": { - "begin": 15, - "end": 30, + "begin": 14, + "end": 27, "abridged": false } } @@ -895,8 +952,8 @@ "22": { "benchmarks": { "system_health.memory_desktop": { - "begin": 30, - "end": 56, + "begin": 27, + "end": 54, "abridged": false } } @@ -904,8 +961,8 @@ "23": { "benchmarks": { "system_health.memory_desktop": { - "begin": 56, - "end": 76, + "begin": 54, + "end": 75, "abridged": false } } @@ -913,11 +970,11 @@ "24": { "benchmarks": { "system_health.memory_desktop": { - "begin": 76, + "begin": 75, "abridged": false }, "v8.browsing_desktop": { - "end": 25, + "end": 23, "abridged": false } }, @@ -930,7 +987,7 @@ "25": { "benchmarks": { "v8.browsing_desktop": { - "begin": 25, + "begin": 23, "abridged": false }, "v8.browsing_desktop-future": { @@ -945,36 +1002,36 @@ } }, "extra_infos": { - "num_stories": 1306, - "predicted_min_shard_time": 1173.0, - "predicted_min_shard_index": 6, - "predicted_max_shard_time": 1543.0, + "num_stories": 1326, + "predicted_min_shard_time": 1199.0, + "predicted_min_shard_index": 8, + "predicted_max_shard_time": 1647.0, "predicted_max_shard_index": 25, - "shard #0": 1249.0, - "shard #1": 1256.0, - "shard #2": 1256.0, - "shard #3": 1257.0, - "shard #4": 1257.0, - "shard #5": 1261.0, - "shard #6": 1173.0, - "shard #7": 1272.0, - "shard #8": 1327.0, - "shard #9": 1255.0, - "shard #10": 1259.0, - "shard #11": 1249.0, - "shard #12": 1264.0, - "shard #13": 1262.0, - "shard #14": 1267.0, - "shard #15": 1258.0, - "shard #16": 1245.0, - "shard #17": 1263.0, - "shard #18": 1247.0, - "shard #19": 1263.0, - "shard #20": 1229.0, - "shard #21": 1248.0, - "shard #22": 1284.0, - "shard #23": 1338.0, - "shard #24": 1239.0, - "shard #25": 1543.0 + "shard #0": 1281.0, + "shard #1": 1278.0, + "shard #2": 1278.0, + "shard #3": 1275.0, + "shard #4": 1274.0, + "shard #5": 1272.0, + "shard #6": 1215.0, + "shard #7": 1264.0, + "shard #8": 1199.0, + "shard #9": 1287.0, + "shard #10": 1264.0, + "shard #11": 1282.0, + "shard #12": 1281.0, + "shard #13": 1287.0, + "shard #14": 1271.0, + "shard #15": 1278.0, + "shard #16": 1281.0, + "shard #17": 1283.0, + "shard #18": 1281.0, + "shard #19": 1294.0, + "shard #20": 1231.0, + "shard #21": 1269.0, + "shard #22": 1302.0, + "shard #23": 1275.0, + "shard #24": 1300.0, + "shard #25": 1647.0 } } \ No newline at end of file
diff --git a/tools/perf/cross_device_test_config.py b/tools/perf/cross_device_test_config.py index ed34852..f506fc1 100644 --- a/tools/perf/cross_device_test_config.py +++ b/tools/perf/cross_device_test_config.py
@@ -123,6 +123,11 @@ 'long_running:tools:gmail-background': 10, 'browse:media:youtubetv:2019': 10 }, + # set speedometer to 20 shards to help warm up speedometer2 + # benchmark runs on linux-perf b/325578543 + 'speedometer': { + 'http://browserbench.org/Speedometer/': 20, + }, 'speedometer2': { 'Speedometer2': 20, },
diff --git a/tools/polymer/html_to_wrapper.gni b/tools/polymer/html_to_wrapper.gni index 894a4db..44a80d54d 100644 --- a/tools/polymer/html_to_wrapper.gni +++ b/tools/polymer/html_to_wrapper.gni
@@ -47,7 +47,8 @@ # Exclude non-web component "*_icons.html" or "icons.html" files. is_icons_template = get_path_info(html_file, "file") == "icons.html" || - string_replace(html_file, "_icons.html", "") != html_file + string_replace(html_file, "_icons.html", "") != html_file || + string_replace(html_file, "icons_lit.html", "") != html_file if (!is_icons_template) { inputs += [ "$in_folder/" + string_replace(html_file, ".html", wrapper_extension) ]
diff --git a/tools/polymer/html_to_wrapper.py b/tools/polymer/html_to_wrapper.py index c32f109..05eaa9b 100644 --- a/tools/polymer/html_to_wrapper.py +++ b/tools/polymer/html_to_wrapper.py
@@ -61,6 +61,14 @@ document.head.appendChild(template.content); """ +# Template for Lit icon HTML files. +_LIT_ICONS_TEMPLATE = """import '%(scheme)s//resources/cr_elements/cr_icon/cr_iconset.js'; +import {html, render} from '%(scheme)s//resources/lit/v3_0/lit.rollup.js'; + +const iconsetHtml = html`%(content)s`; +render(iconsetHtml, document.head); +""" + # Tokens used to detect whether the underlying custom element is based on # Polymer or Lit. POLYMER_TOKEN = '//resources/polymer/v3_0/polymer/polymer_bundled.min.js' @@ -69,6 +77,7 @@ # Map holding all the different types of HTML files to generate wrappers for. TEMPLATE_MAP = { 'lit': _LIT_ELEMENT_TEMPLATE, + 'lit_icons': _LIT_ICONS_TEMPLATE, 'native': _NATIVE_ELEMENT_TEMPLATE, 'polymer_icons': _POLYMER_ICONS_TEMPLATE, 'polymer': _POLYMER_ELEMENT_TEMPLATE, @@ -87,6 +96,16 @@ return 'native' +def detect_icon_template_type(icons_file): + with io.open(icons_file, encoding='utf-8', mode='r') as f: + content = f.read() + if 'iron-iconset-svg' in content: + return 'polymer_icons' + assert 'cr-iconset' in content, \ + 'icons files must include iron-iconset-svg or cr-iconset' + return 'lit_icons' + + _IMPORTS_START_REGEX = '^<!-- #html_wrapper_imports_start$' _IMPORTS_END_REGEX = '^#html_wrapper_imports_end -->$' @@ -179,31 +198,52 @@ # Wrap the input files (minified or not) with an enclosing .ts file. for in_file in args.in_files: wrapper_in_file = path.join(wrapper_in_folder, in_file) + template = None + template_type = args.template + filename = path.basename(in_file) + effective_in_file = wrapper_in_file - with io.open(wrapper_in_file, encoding='utf-8', mode='r') as f: - html_content = f.read() - - template = None - template_type = args.template - filename = path.basename(in_file) - if filename == 'icons.html' or filename.endswith('_icons.html'): - assert args.template == 'polymer' or args.template == 'detect', ( - r'Polymer icons files not supported with template="%s"' % - args.template) + if filename == 'icons.html' or filename.endswith('_icons.html'): + if args.template == 'polymer': template_type = 'polymer_icons' - elif template_type == 'detect': - # Locate the file that holds the web component's definition. Assumed to - # be in the same folder as input HTML template file. - definition_file = path.splitext(path.join(in_folder, - in_file))[0] + extension - template_type = detect_template_type(definition_file) + elif args.template == 'lit': + template_type = 'lit_icons' + else: + assert args.template == 'detect', ( + r'Polymer/Lit icons files not supported with template="%s"' % + args.template) + template_type = detect_icon_template_type(wrapper_in_file) + elif filename.endswith('icons_lit.html'): + assert args.template == 'lit' or args.template == 'detect', ( + r'Lit icons files not supported with template="%s"' % args.template) + # Grab the content from the equivalent Polymer file, and substitute + # cr-iconset for iron-iconset-svg. + polymer_file = path.join(wrapper_in_folder, + in_file.replace('icons_lit', 'icons')) + effective_in_file = polymer_file + template_type = 'lit_icons' + elif template_type == 'detect': + # Locate the file that holds the web component's definition. Assumed to + # be in the same folder as input HTML template file. + definition_file = path.splitext(path.join(in_folder, + in_file))[0] + extension + template_type = detect_template_type(definition_file) + + with io.open(effective_in_file, encoding='utf-8', mode='r') as f: + html_content = f.read() substitutions = { 'content': html_content, 'scheme': 'chrome:' if args.scheme == 'chrome' else '', } - if template_type == 'lit': + if template_type == 'lit_icons': + # Replace iron-iconset-svg for the case of Lit icons files generated + # from a Polymer icons file. + if 'iron-iconset-svg' in html_content: + html_content = html_content.replace('iron-iconset-svg', 'cr-iconset') + substitutions['content'] = html_content + elif template_type == 'lit': # Add Lit specific substitutions. basename = path.splitext(path.basename(in_file))[0] # Derive class name from file name. For example
diff --git a/tools/polymer/html_to_wrapper_test.py b/tools/polymer/html_to_wrapper_test.py index fc4fce1..1885fa7 100755 --- a/tools/polymer/html_to_wrapper_test.py +++ b/tools/polymer/html_to_wrapper_test.py
@@ -107,6 +107,24 @@ 'html_to_wrapper/icons.html.ts', 'html_to_wrapper/expected/icons.html.ts') + def testHtmlToWrapperIconsLit(self): + self._run_test('html_to_wrapper/cr_icons.html', + 'html_to_wrapper/cr_icons.html.ts', + 'html_to_wrapper/expected/cr_icons.html.ts', + template='lit') + + def testHtmlToWrapperIconsLit_Detect(self): + self._run_test('html_to_wrapper/cr_icons.html', + 'html_to_wrapper/cr_icons.html.ts', + 'html_to_wrapper/expected/cr_icons.html.ts', + template='detect') + + def testHtmlToWrapperLitFromPolymer(self): + self._run_test('html_to_wrapper/icons_lit.html', + 'html_to_wrapper/icons_lit.html.ts', + 'html_to_wrapper/expected/cr_icons.html.ts', + template='detect') + def testHtmlToWrapper_Minify(self): self._run_test('html_to_wrapper/foo.html', 'html_to_wrapper/foo.html.ts',
diff --git a/tools/polymer/tests/html_to_wrapper/cr_icons.html b/tools/polymer/tests/html_to_wrapper/cr_icons.html new file mode 100644 index 0000000..45ec5ea --- /dev/null +++ b/tools/polymer/tests/html_to_wrapper/cr_icons.html
@@ -0,0 +1,7 @@ +<cr-iconset name="dummy" size="24"> + <svg> + <defs> + <g id="foo"><path d="M12 2C6.48 2 2 6.48 2"></path></g> + </defs> + </svg> +</cr-iconset>
diff --git a/tools/polymer/tests/html_to_wrapper/expected/cr_icons.html.ts b/tools/polymer/tests/html_to_wrapper/expected/cr_icons.html.ts new file mode 100644 index 0000000..b97fe1a --- /dev/null +++ b/tools/polymer/tests/html_to_wrapper/expected/cr_icons.html.ts
@@ -0,0 +1,12 @@ +import '//resources/cr_elements/cr_icon/cr_iconset.js'; +import {html, render} from '//resources/lit/v3_0/lit.rollup.js'; + +const iconsetHtml = html`<cr-iconset name="dummy" size="24"> + <svg> + <defs> + <g id="foo"><path d="M12 2C6.48 2 2 6.48 2"></path></g> + </defs> + </svg> +</cr-iconset> +`; +render(iconsetHtml, document.head);
diff --git a/tools/polymer/tests/html_to_wrapper/icons_lit.html b/tools/polymer/tests/html_to_wrapper/icons_lit.html new file mode 100644 index 0000000..de34e14 --- /dev/null +++ b/tools/polymer/tests/html_to_wrapper/icons_lit.html
@@ -0,0 +1,4 @@ +<!-- + Purposefully empty since this file is generated at buildtime from the + Polymer version. +-->
diff --git a/tools/run-swarmed.py b/tools/run-swarmed.py index c6041aa..e678ad8 100755 --- a/tools/run-swarmed.py +++ b/tools/run-swarmed.py
@@ -125,12 +125,19 @@ raise Exception('Either both of --ios-sim-version and --ios-sim-platform ' 'or --ios-device is required') - trigger_args.extend(['-service-account', args.service_account]) trigger_args.extend( ['-named-cache', f'xcode_ios_{args.ios_xcode_build_version}=Xcode.app']) trigger_args.extend( ['-cipd-package', '.:infra/tools/mac_toolchain/${platform}=latest']) + if args.service_account: + account = args.service_account + elif args.swarming_instance == 'chromium-swarm': + account = 'chromium-tester@chops-service-accounts.iam.gserviceaccount.com' + elif args.swarming_instance == 'chrome-swarming': + account = 'chrome-tester@chops-service-accounts.iam.gserviceaccount.com' + trigger_args.extend(['-service-account', account]) + if args.arch != 'detect': trigger_args += [ '-d', @@ -271,11 +278,11 @@ '--system-log-file flags to the comment.') parser.add_argument('out_dir', type=str, help='Build directory.') parser.add_argument('target_name', type=str, help='Name of target to run.') - # ios only args parser.add_argument( '--service-account', - default='chromium-tester@chops-service-accounts.iam.gserviceaccount.com', - help='The service account that the swarming task will be run using') + help='Optional service account that the swarming task will be run using. ' + 'Default value will be set based on the "--swarming-instance".') + # ios only args parser.add_argument('--ios-xcode-build-version', help='The version of xcode that will be used for all ' 'xcodebuild CLI commands')
diff --git a/tools/typescript/path_mappings.py b/tools/typescript/path_mappings.py index 9750d19..20be8b40 100644 --- a/tools/typescript/path_mappings.py +++ b/tools/typescript/path_mappings.py
@@ -26,6 +26,7 @@ "cr_components/customize_color_scheme_mode", "cr_components/customize_themes", "cr_components/help_bubble", + "cr_components/history", "cr_components/history_embeddings", "cr_components/history_clusters", "cr_components/localized_link",
diff --git a/tools/utr/builders.py b/tools/utr/builders.py index be75280..e066a88 100644 --- a/tools/utr/builders.py +++ b/tools/utr/builders.py
@@ -9,7 +9,8 @@ _THIS_DIR = pathlib.Path(__file__).resolve().parent _SRC_DIR = _THIS_DIR.parents[1] -# TODO(crbug.com/41492688): Support src-internal configs too. +# TODO(crbug.com/41492688): Support src-internal configs too. When this is done, +# ensure tools/utr/recipe.py is not using the public reclient instance _BUILDER_PROP_DIRS = _SRC_DIR.joinpath('infra', 'config', 'generated', 'builders')
diff --git a/tools/utr/recipe.py b/tools/utr/recipe.py index 1687a62..6494a92 100644 --- a/tools/utr/recipe.py +++ b/tools/utr/recipe.py
@@ -148,6 +148,15 @@ }, }, } + # TODO(crbug.com/41492688): Use the chrome version for internal builders + # when they are added. + # Set reclient and siso to use untrusted even for imitating ci builders + if not '$build/reclient' in input_props: + input_props['$build/reclient'] = {} + input_props['$build/reclient']['instance'] = 'rbe-chromium-untrusted' + if not '$build/siso' in input_props: + input_props['$build/siso'] = {} + input_props['$build/siso']['project'] = 'rbe-chromium-untrusted' self._input_props = input_props def _run(self, adapter, rerun_props=None):
diff --git a/tools/web_dev_style/js_checker.py b/tools/web_dev_style/js_checker.py index 1bda403..4ee72c2 100644 --- a/tools/web_dev_style/js_checker.py +++ b/tools/web_dev_style/js_checker.py
@@ -120,7 +120,7 @@ affected_files = self.input_api.AffectedFiles(file_filter=self.file_filter, include_deletes=False) affected_js_files = [ - f for f in affected_files if f.LocalPath().endswith((".js", "ts")) + f for f in affected_files if f.LocalPath().endswith((".js", ".ts")) ] if affected_js_files: @@ -134,7 +134,6 @@ _f for _f in [ self.BindThisCheck(i, line), self.ChromeSendCheck(i, line), - self.CommentIfAndIncludeCheck(i, line), self.EndJsDocCommentCheck(i, line), self.ExtraDotInGenericCheck(i, line), self.InheritDocCheck(i, line), @@ -143,6 +142,16 @@ ] if _f ] + if not f.LocalPath().endswith((".html.js", ".html.ts")): + # Exclude JS/TS files holding HTML strings from + # CommentIfAndIncludeCheck(). + for i, line in f.ChangedContents(): + error_lines += [ + _f for _f in [ + self.CommentIfAndIncludeCheck(i, line), + ] if _f + ] + if error_lines: error_lines = [ "Found JavaScript style violations in %s:" %
diff --git a/ui/chromeos/strings/network/network_element_localized_strings_provider.cc b/ui/chromeos/strings/network/network_element_localized_strings_provider.cc index daf1191..aa8bced 100644 --- a/ui/chromeos/strings/network/network_element_localized_strings_provider.cc +++ b/ui/chromeos/strings/network/network_element_localized_strings_provider.cc
@@ -551,6 +551,8 @@ ash::features::IsApnRevampEnabled()); html_source->AddBoolean("isCellularCarrierLockEnabled", ash::features::IsCellularCarrierLockEnabled()); + html_source->AddBoolean("isApnPoliciesEnabled", + ash::features::IsApnPoliciesEnabled()); html_source->AddString("apnSettingsDescriptionWithLink", l10n_util::GetStringFUTF16(
diff --git a/ui/display/manager/display_manager.cc b/ui/display/manager/display_manager.cc index 45d8e75..c6565792 100644 --- a/ui/display/manager/display_manager.cc +++ b/ui/display/manager/display_manager.cc
@@ -2392,43 +2392,17 @@ void DisplayManager::InsertAndUpdateDisplayInfo( const ManagedDisplayInfo& new_info) { - ManagedDisplayInfo* info = nullptr; auto it = display_info_.find(new_info.id()); if (it != display_info_.end()) { - info = &(it->second); + ManagedDisplayInfo* info = &(it->second); info->Copy(new_info); } else { - info = &display_info_[new_info.id()]; - *info = new_info; - + display_info_[new_info.id()] = new_info; // Set from_native_platform to false so that all information // (rotation, zoom factor etc.) is copied. - info->set_from_native_platform(false); - - // If an external display is plugged in for the first time and doesn't have - // any entry in display_info_, such as those from Pref or from previous - // config, apply recommended default zoom factor. - ApplyDefaultZoomFactorIfNecessary(*info); + display_info_[new_info.id()].set_from_native_platform(false); } - - CHECK(info); - info->UpdateDisplaySize(); -} - -void DisplayManager::ApplyDefaultZoomFactorIfNecessary( - ManagedDisplayInfo& info) { - // Only apply to external display. The internal display has good handle of - // default dpi. - if (IsInternalDisplayId(info.id())) { - return; - } - - // Ignore unified display. - if (info.id() == kUnifiedDisplayId) { - return; - } - - info.UpdateZoomFactorToMatchTargetDPI(); + display_info_[new_info.id()].UpdateDisplaySize(); } Display DisplayManager::CreateDisplayFromDisplayInfoById(int64_t id) {
diff --git a/ui/display/manager/display_manager.h b/ui/display/manager/display_manager.h index 2686341..139d45d 100644 --- a/ui/display/manager/display_manager.h +++ b/ui/display/manager/display_manager.h
@@ -601,11 +601,6 @@ // |GetDisplayInfo| to get the correct ManagedDisplayInfo for a display. void InsertAndUpdateDisplayInfo(const ManagedDisplayInfo& new_info); - // Applies recommended zoom factor when necessary, only used when an external - // display is connected for the first time. e.g. when a 4K native mode is used - // when firstly connected, the content is almost certainly too small. - void ApplyDefaultZoomFactorIfNecessary(ManagedDisplayInfo& info); - // Creates a display object from the ManagedDisplayInfo for // |display_id|. Display CreateDisplayFromDisplayInfoById(int64_t display_id);
diff --git a/ui/display/manager/managed_display_info.cc b/ui/display/manager/managed_display_info.cc index c4f026b..db1e98e 100644 --- a/ui/display/manager/managed_display_info.cc +++ b/ui/display/manager/managed_display_info.cc
@@ -39,13 +39,6 @@ const float kDpi96 = 96.0; -// The recommended default external display DPI, only used when an external -// display is connected for the first time. e.g. when a 4K native mode is used -// when firstly connected, the content is almost certainly too small. The value -// comes from the metrics of currently most used external effective display DPI -// - Ash.Display.ExternalDisplay.ActiveEffectiveDPI. -const float kRecommendedDefaultExternalDisplayDpi = kDpi96; - // Check the content of |spec| and fill |bounds| and |device_scale_factor|. // Returns true when |bounds| is found. void GetDisplayBounds(const std::string& spec, @@ -506,53 +499,6 @@ return pixel_size / static_cast<float>(logical_size); } -void ManagedDisplayInfo::UpdateZoomFactorToMatchTargetDPI() { - // Only update zoom factor if device dpi is valid. - if (!device_dpi_) { - return; - } - - const float target_zoom_factor = - device_dpi_ / kRecommendedDefaultExternalDisplayDpi; - - // Refine zoom factor based on available zoom factors in settings. - const int display_larger_side = - std::max(bounds_in_native_.width(), bounds_in_native_.height()); - const std::vector<float> avaialble_zoom_factors = - GetDisplayZoomFactorsByDisplayWidth(display_larger_side); - DCHECK_GE(avaialble_zoom_factors.size(), 1u); - - const float min_zoom_factor = avaialble_zoom_factors.front(); - const float max_zoom_factor = avaialble_zoom_factors.back(); - // Check min boundary. - if (target_zoom_factor <= min_zoom_factor) { - zoom_factor_ = min_zoom_factor; - } else if (target_zoom_factor >= max_zoom_factor) { - // Check max boundary. - zoom_factor_ = max_zoom_factor; - } else { - // Round to the neareast available zoom factor. - DCHECK(std::is_sorted(avaialble_zoom_factors.begin(), - avaialble_zoom_factors.end())); - for (size_t i = 0; i < avaialble_zoom_factors.size() - 1; i++) { - const float left_bound = avaialble_zoom_factors[i]; - const float right_bound = avaialble_zoom_factors[i + 1]; - if (target_zoom_factor >= right_bound) { - continue; - } - - zoom_factor_ = - (target_zoom_factor - left_bound < right_bound - target_zoom_factor) - ? left_bound - : right_bound; - break; - } - } - - // Also update the zoom factor in the zoom_factor_map_. - AddZoomFactorForSize(size_in_pixel_.ToString(), zoom_factor_); -} - gfx::Size ManagedDisplayInfo::GetSizeInPixelWithPanelOrientation() const { gfx::Size size = bounds_in_native_.size(); if (panel_orientation_ == display::PanelOrientation::kLeftUp ||
diff --git a/ui/display/manager/managed_display_info.h b/ui/display/manager/managed_display_info.h index 89bb5e6..a4951bf2 100644 --- a/ui/display/manager/managed_display_info.h +++ b/ui/display/manager/managed_display_info.h
@@ -258,10 +258,6 @@ // TODO(oshima): Rename to |GetDeviceScaleFactor()|. float GetEffectiveDeviceScaleFactor() const; - // Updates the zoom factor so that the effective dpi matches to the - // recommended default dpi. - void UpdateZoomFactorToMatchTargetDPI(); - // Copy the display info except for fields that can be modified by a user // (|rotation_|). |rotation_| is copied when the |another_info| isn't native // one.
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index f3b0ff3..5ad5e831 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -725,6 +725,7 @@ "test/scoped_default_font_description.h", "test/sk_color_eq.cc", "test/sk_color_eq.h", + "test/sk_gmock_support.h", ] if (is_apple) { sources += [ "image/image_unittest_util_apple.mm" ]
diff --git a/ui/gfx/DEPS b/ui/gfx/DEPS index 0ddd58a..a7eb37a 100644 --- a/ui/gfx/DEPS +++ b/ui/gfx/DEPS
@@ -13,8 +13,6 @@ "+ui/base/ui_base_features.h", "+ui/ios", "+ui/linux", - - "-testing/gmock", ] specific_include_rules = {
diff --git a/ui/gfx/color_transform.cc b/ui/gfx/color_transform.cc index 6b71fcd4..030ae391 100644 --- a/ui/gfx/color_transform.cc +++ b/ui/gfx/color_transform.cc
@@ -1134,8 +1134,7 @@ steps_.push_back(std::move(src_range_adjust_matrix)); if (src.GetMatrixID() == ColorSpace::MatrixID::BT2020_CL) { - // BT2020 CL is a special case. - steps_.push_back(std::make_unique<ColorTransformFromBT2020CL>()); + NOTREACHED_NORETURN(); } else { steps_.push_back(std::make_unique<ColorTransformMatrix>( Invert(src.GetTransferMatrix(options.src_bit_depth)))); @@ -1182,9 +1181,7 @@ } if (src.GetMatrixID() == ColorSpace::MatrixID::BT2020_CL) { - // BT2020 CL is a special case. - steps_.push_back(std::make_unique<ColorTransformMatrix>( - Invert(src.GetTransferMatrix(options.src_bit_depth)))); + NOTREACHED_NORETURN(); } steps_.push_back( std::make_unique<ColorTransformMatrix>(src.GetPrimaryMatrix())); @@ -1259,9 +1256,7 @@ steps_.push_back( std::make_unique<ColorTransformMatrix>(Invert(dst.GetPrimaryMatrix()))); if (dst.GetMatrixID() == ColorSpace::MatrixID::BT2020_CL) { - // BT2020 CL is a special case. - steps_.push_back(std::make_unique<ColorTransformMatrix>( - dst.GetTransferMatrix(options.dst_bit_depth))); + NOTREACHED_NORETURN(); } switch (dst.GetTransferID()) { @@ -1313,7 +1308,7 @@ steps_.push_back(std::move(dst_range_adjust_matrix)); if (dst.GetMatrixID() == ColorSpace::MatrixID::BT2020_CL) { - NOTREACHED(); + NOTREACHED_NORETURN(); } else { steps_.push_back(std::make_unique<ColorTransformMatrix>( dst.GetTransferMatrix(options.dst_bit_depth)));
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc index fa113b5..7b5f65f 100644 --- a/ui/gfx/color_transform_unittest.cc +++ b/ui/gfx/color_transform_unittest.cc
@@ -90,35 +90,6 @@ EXPECT_GT(tmp.z(), tmp.y()); } -TEST(SimpleColorSpace, BT2020CLtoBT2020RGB) { - ColorSpace bt2020cl( - ColorSpace::PrimaryID::BT2020, ColorSpace::TransferID::BT2020_10, - ColorSpace::MatrixID::BT2020_CL, ColorSpace::RangeID::LIMITED); - ColorSpace bt2020rgb(ColorSpace::PrimaryID::BT2020, - ColorSpace::TransferID::BT2020_10, - ColorSpace::MatrixID::RGB, ColorSpace::RangeID::FULL); - std::unique_ptr<ColorTransform> t( - ColorTransform::NewColorTransform(bt2020cl, bt2020rgb)); - - ColorTransform::TriStim tmp(16.0f / 255.0f, 0.5f, 0.5f); - t->Transform(&tmp, 1); - EXPECT_NEAR(tmp.x(), 0.0f, kMathEpsilon); - EXPECT_NEAR(tmp.y(), 0.0f, kMathEpsilon); - EXPECT_NEAR(tmp.z(), 0.0f, kMathEpsilon); - - tmp = ColorTransform::TriStim(235.0f / 255.0f, 0.5f, 0.5f); - t->Transform(&tmp, 1); - EXPECT_NEAR(tmp.x(), 1.0f, kMathEpsilon); - EXPECT_NEAR(tmp.y(), 1.0f, kMathEpsilon); - EXPECT_NEAR(tmp.z(), 1.0f, kMathEpsilon); - - // Test a blue color - tmp = ColorTransform::TriStim(128.0f / 255.0f, 240.0f / 255.0f, 0.5f); - t->Transform(&tmp, 1); - EXPECT_GT(tmp.z(), tmp.x()); - EXPECT_GT(tmp.z(), tmp.y()); -} - TEST(SimpleColorSpace, YCOCGLimitedToSRGB) { ColorSpace ycocg(ColorSpace::PrimaryID::BT709, ColorSpace::TransferID::SRGB, ColorSpace::MatrixID::YCOCG, ColorSpace::RangeID::LIMITED);
diff --git a/ui/gfx/test/sk_gmock_support.h b/ui/gfx/test/sk_gmock_support.h new file mode 100644 index 0000000..0c91f35 --- /dev/null +++ b/ui/gfx/test/sk_gmock_support.h
@@ -0,0 +1,75 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_TEST_SK_GMOCK_SUPPORT_H_ +#define UI_GFX_TEST_SK_GMOCK_SUPPORT_H_ + +#include "testing/gmock/include/gmock/gmock.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/color_utils.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/test/sk_color_eq.h" + +namespace gfx::test { + +MATCHER_P2(IsCloseToBitmap, expected_bmp, max_per_channel_deviation, "") { + // Number of pixels with an error + int error_pixels_count = 0; + + gfx::Rect error_bounding_rect = gfx::Rect(); + + // Check that bitmaps have identical dimensions. + if (arg.width() != expected_bmp.width()) { + *result_listener << "where widths do not match, actual: " << arg.width() + << ", expected: " << expected_bmp.width(); + return false; + } + if (arg.height() != expected_bmp.height()) { + *result_listener << "where heights do not match, actual: " << arg.height() + << ", expected: " << expected_bmp.height(); + return false; + } + + for (int x = 0; x < arg.width(); ++x) { + for (int y = 0; y < arg.height(); ++y) { + SkColor actual_color = arg.getColor(x, y); + SkColor expected_color = expected_bmp.getColor(x, y); + if (!ColorsClose(actual_color, expected_color, + max_per_channel_deviation)) { + ++error_pixels_count; + error_bounding_rect.Union(gfx::Rect(x, y, 1, 1)); + } + } + } + + if (error_pixels_count != 0) { + *result_listener + << "Number of pixel with an error, given max_per_channel_deviation of " + << max_per_channel_deviation << ": " << error_pixels_count + << "\nError Bounding Box : " << error_bounding_rect.ToString() << "\n"; + int sample_x = error_bounding_rect.x(); + int sample_y = error_bounding_rect.y(); + std::string expected_color = color_utils::SkColorToRgbaString( + expected_bmp.getColor(sample_x, sample_y)); + std::string actual_color = + color_utils::SkColorToRgbaString(arg.getColor(sample_x, sample_y)); + *result_listener << "Sample pixel comparison at " << sample_x << "x" + << sample_y << ": Expected " << expected_color + << ", actual " << actual_color; + return false; + } + + return true; +} + +MATCHER_P(EqualsBitmap, expected_bmp, "") { + return testing::ExplainMatchResult( + IsCloseToBitmap(expected_bmp, + /*max_per_channel_deviation=*/0), + arg, result_listener); +} + +} // namespace gfx::test + +#endif // UI_GFX_TEST_SK_GMOCK_SUPPORT_H_
diff --git a/ui/views/accessibility/view_accessibility.cc b/ui/views/accessibility/view_accessibility.cc index 7c0ee61d..3489dc5 100644 --- a/ui/views/accessibility/view_accessibility.cc +++ b/ui/views/accessibility/view_accessibility.cc
@@ -239,19 +239,6 @@ views::ViewAccessibilityUtils::Merge(/*source*/ data_, /*destination*/ *data); - // The ignored state depends on more than just the kIgnored state of the data, - // for instance it also depends on if the view has been pruned from the tree. - // And since some of those states we keep track of in member variables, we - // need to add this check here at the end so that if those states were set, we - // add the kIgnored state to the final AXNodeData. - // TODO(accessibility): We'll eventually want to replace this with a more - // robust and less ambiguous system, such as what Blink does on the render - // side. We might need something like ComputeIsHidden(), which could try to - // mimic what Blink does when computing 'ignoredness' of a node. - if (ViewAccessibility::GetIsIgnored()) { - data->AddState(ax::mojom::State::kIgnored); - } - // This was previously found earlier in the function. It has been moved here, // after the call to `ViewAccessibility::Merge`, so that we only check the // `data` after all the attributes have been set. Otherwise, there was a bug @@ -420,6 +407,7 @@ } data_.role = role; + AdjustIgnoredState(); } void ViewAccessibility::SetRole(const ax::mojom::Role role, @@ -642,22 +630,18 @@ } void ViewAccessibility::SetIsIgnored(bool is_ignored) { - if (is_ignored == data_.IsIgnored()) { + if (is_ignored == should_be_ignored_) { return; } - if (is_ignored) { - data_.AddState(ax::mojom::State::kIgnored); - } else { - data_.RemoveState(ax::mojom::State::kIgnored); - } + should_be_ignored_ = is_ignored; + AdjustIgnoredState(); view_->NotifyAccessibilityEvent(ax::mojom::Event::kTreeChanged, true); } bool ViewAccessibility::GetIsIgnored() const { - return data_.HasState(ax::mojom::State::kIgnored) || - ViewAccessibility::IsChildOfLeaf() || GetIsPruned(); + return data_.HasState(ax::mojom::State::kIgnored); } void ViewAccessibility::OverrideNativeWindowTitle(const std::string& title) { @@ -796,6 +780,7 @@ internal::ScopedChildrenLock lock(view_); for (auto& child : view_->children()) { child->GetViewAccessibility().pruned_ = true; + child->GetViewAccessibility().AdjustIgnoredState(); child->GetViewAccessibility().PruneSubtree(); } @@ -808,7 +793,7 @@ internal::ScopedChildrenLock lock(view_); for (auto& child : view_->children()) { child->GetViewAccessibility().pruned_ = false; - + child->GetViewAccessibility().AdjustIgnoredState(); // If we encounter a node that has already been explicitly set to be a leaf, // don't unprune it/its subtree. Otherwise we could end up in situations // where we have a node that is set to be a leaf, but has unpruned children. @@ -822,4 +807,18 @@ child->UnpruneVirtualSubtree(); } } + +void ViewAccessibility::SetState(ax::mojom::State state, bool is_enabled) { + if (is_enabled) { + data_.AddState(state); + } else { + data_.RemoveState(state); + } +} + +void ViewAccessibility::AdjustIgnoredState() { + bool is_ignored = + should_be_ignored_ || pruned_ || data_.role == ax::mojom::Role::kNone; + SetState(ax::mojom::State::kIgnored, is_ignored); +} } // namespace views
diff --git a/ui/views/accessibility/view_accessibility.h b/ui/views/accessibility/view_accessibility.h index a04ff4a..e2570b9e 100644 --- a/ui/views/accessibility/view_accessibility.h +++ b/ui/views/accessibility/view_accessibility.h
@@ -215,7 +215,9 @@ void SetIsSelected(bool selected); - // Hides this view from the accessibility APIs. + // Hides this view from the accessibility APIs. Keep in mind that this is not + // the sole determinant of whether the ignored state is set. See + // `AdjustIgnoredState`. void SetIsIgnored(bool is_ignored); virtual bool GetIsIgnored() const; @@ -413,6 +415,12 @@ bool pruned_ = false; + // This is set to true when the view is explicitly marked as ignored by + // `SetIsIgnored`. It is not the only condition that will cause a view to have + // the ignored accessible state, as `pruned_` and `is_leaf_` can also cause + // this. See `AdjustIgnoredState`. + bool should_be_ignored_ = false; + // Used by the Views system to help some assistive technologies, such as // screen readers, transition focus from one widget to another. base::WeakPtr<Widget> next_focus_ = nullptr; @@ -441,6 +449,10 @@ void PruneSubtree(); void UnpruneSubtree(); + void SetState(ax::mojom::State state, bool is_enabled); + + void AdjustIgnoredState(); + bool ignore_missing_widget_for_testing_ = false; };
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.cc b/ui/views/controls/tabbed_pane/tabbed_pane.cc index e15e955..bc62bc2d 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -10,6 +10,7 @@ #include "base/check_op.h" #include "base/i18n/rtl.h" +#include "base/notreached.h" #include "build/build_config.h" #include "cc/paint/paint_flags.h" #include "third_party/skia/include/core/SkPath.h" @@ -131,19 +132,17 @@ } gfx::Size TabbedPaneTab::CalculatePreferredSize() const { - int width = preferred_title_width_ + GetInsets().width(); - if (tabbed_pane_->GetStyle() == TabbedPane::TabStripStyle::kHighlight && - tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kVertical) - width = std::max(width, 192); - return gfx::Size(width, 32); + NOTREACHED_NORETURN() << "Use CalculatePreferredSize(SizeBounds)"; } -int TabbedPaneTab::GetHeightForWidth(int w) const { - // Because we set the LayoutManager, it will use - // LayoutManager::GetPreferredHeightForWidth by default, but this is not - // consistent with the fixed height desired by CalculatePreferredSize, so we - // override it and call it manually. - return CalculatePreferredSize().height(); +gfx::Size TabbedPaneTab::CalculatePreferredSize( + const SizeBounds& available_size) const { + int width = preferred_title_width_ + GetInsets().width(); + if (tabbed_pane_->GetStyle() == TabbedPane::TabStripStyle::kHighlight && + tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kVertical) { + width = std::max(width, 192); + } + return gfx::Size(width, 32); } void TabbedPaneTab::GetAccessibleNodeData(ui::AXNodeData* data) {
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.h b/ui/views/controls/tabbed_pane/tabbed_pane.h index 48f164c..3e3337a0 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.h +++ b/ui/views/controls/tabbed_pane/tabbed_pane.h
@@ -176,8 +176,9 @@ void OnMouseEntered(const ui::MouseEvent& event) override; void OnMouseExited(const ui::MouseEvent& event) override; void OnGestureEvent(ui::GestureEvent* event) override; - gfx::Size CalculatePreferredSize() const override; - int GetHeightForWidth(int w) const override; + gfx::Size CalculatePreferredSize() const final; + gfx::Size CalculatePreferredSize( + const SizeBounds& available_size) const override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; bool HandleAccessibleAction(const ui::AXActionData& action_data) override; void OnFocus() override;
diff --git a/ui/views/examples/multiline_example.cc b/ui/views/examples/multiline_example.cc index af9f8a9..c0c3b890 100644 --- a/ui/views/examples/multiline_example.cc +++ b/ui/views/examples/multiline_example.cc
@@ -86,28 +86,27 @@ render_text_->Draw(canvas); } - gfx::Size CalculatePreferredSize() const override { - // Turn off multiline mode to get the single-line text size, which is the - // preferred size for this view. - render_text_->SetMultiline(false); - gfx::Size size(render_text_->GetContentWidth(), - render_text_->GetStringSize().height()); - size.Enlarge(GetInsets().width(), GetInsets().height()); - render_text_->SetMultiline(true); - return size; - } + gfx::Size CalculatePreferredSize( + const SizeBounds& available_size) const override { + int w = available_size.width().value_or(0); + if (w == 0) { + // Turn off multiline mode to get the single-line text size, which is the + // preferred size for this view. + render_text_->SetMultiline(false); + gfx::Size size(render_text_->GetContentWidth(), + render_text_->GetStringSize().height()); + size.Enlarge(GetInsets().width(), GetInsets().height()); + render_text_->SetMultiline(true); + return size; + } - int GetHeightForWidth(int w) const override { - // TODO(ckocagil): Why does this happen? - if (w == 0) - return View::GetHeightForWidth(w); const gfx::Rect old_rect = render_text_->display_rect(); gfx::Rect rect = old_rect; rect.set_width(w - GetInsets().width()); render_text_->SetDisplayRect(rect); int height = render_text_->GetStringSize().height() + GetInsets().height(); render_text_->SetDisplayRect(old_rect); - return height; + return gfx::Size(w, height); } void OnThemeChanged() override {
diff --git a/ui/views/layout/layout_types.h b/ui/views/layout/layout_types.h index 14e05150..152dc37 100644 --- a/ui/views/layout/layout_types.h +++ b/ui/views/layout/layout_types.h
@@ -62,6 +62,10 @@ return is_bounded() ? std::min(this->value(), value) : value; } + constexpr int value_or(int defaule_value) const { + return is_bounded() ? value() : defaule_value; + } + void operator+=(const SizeBound& rhs); void operator-=(const SizeBound& rhs);
diff --git a/ui/views/test/test_views.cc b/ui/views/test/test_views.cc index c5dd24a8..69ac753 100644 --- a/ui/views/test/test_views.cc +++ b/ui/views/test/test_views.cc
@@ -44,14 +44,16 @@ PreferredSizeChanged(); } -int ProportionallySizedView::GetHeightForWidth(int w) const { - return w * factor_; -} - -gfx::Size ProportionallySizedView::CalculatePreferredSize() const { - if (preferred_width_ >= 0) - return gfx::Size(preferred_width_, GetHeightForWidth(preferred_width_)); - return View::CalculatePreferredSize(); +gfx::Size ProportionallySizedView::CalculatePreferredSize( + const SizeBounds& available_size) const { + if (available_size.width().is_bounded()) { + int w = available_size.width().value(); + return gfx::Size(w, w * factor_); + } else if (preferred_width_ >= 0) { + return gfx::Size(preferred_width_, preferred_width_ * factor_); + } else { + return View::CalculatePreferredSize(available_size); + } } BEGIN_METADATA(ProportionallySizedView)
diff --git a/ui/views/test/test_views.h b/ui/views/test/test_views.h index dfed1df..5f65e72 100644 --- a/ui/views/test/test_views.h +++ b/ui/views/test/test_views.h
@@ -61,8 +61,8 @@ void SetPreferredWidth(int width); - int GetHeightForWidth(int w) const override; - gfx::Size CalculatePreferredSize() const override; + gfx::Size CalculatePreferredSize( + const SizeBounds& available_size) const override; private: // The multiplicative factor between width and height, i.e.
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn index 1954443..0694d559 100644 --- a/ui/webui/resources/BUILD.gn +++ b/ui/webui/resources/BUILD.gn
@@ -91,12 +91,14 @@ if (!is_android) { public_deps += [ + "cr_components/history:build_grdp", "cr_components/history_clusters:build_grdp", "cr_components/history_embeddings:build_grdp", "cr_components/searchbox:build_grdp", "cr_components/searchbox/icons:build_grdp", ] grdp_files += [ + "$target_gen_dir/cr_components/history/resources.grdp", "$target_gen_dir/cr_components/history_clusters/resources.grdp", "$target_gen_dir/cr_components/history_embeddings/resources.grdp", "$target_gen_dir/cr_components/searchbox/resources.grdp",
diff --git a/ui/webui/resources/cr_components/history/BUILD.gn b/ui/webui/resources/cr_components/history/BUILD.gn new file mode 100644 index 0000000..fb5adc71 --- /dev/null +++ b/ui/webui/resources/cr_components/history/BUILD.gn
@@ -0,0 +1,17 @@ +# Copyright 2024 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//ui/webui/resources/tools/build_webui.gni") + +assert(!is_android && !is_ios) + +build_webui("build") { + grd_prefix = "cr_components_history_embeddings" + non_web_component_files = [ "constants.ts" ] + + ts_out_dir = "$root_gen_dir/ui/webui/resources/tsc/cr_components/history" + ts_composite = true + generate_grdp = true + grd_resource_path_prefix = rebase_path(".", "//ui/webui/resources") +}
diff --git a/ui/webui/resources/cr_components/history/OWNERS b/ui/webui/resources/cr_components/history/OWNERS new file mode 100644 index 0000000..fc5441da1 --- /dev/null +++ b/ui/webui/resources/cr_components/history/OWNERS
@@ -0,0 +1,4 @@ +file://components/history_embeddings/OWNERS + +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/ui/webui/resources/cr_components/history/constants.ts b/ui/webui/resources/cr_components/history/constants.ts new file mode 100644 index 0000000..c464e89 --- /dev/null +++ b/ui/webui/resources/cr_components/history/constants.ts
@@ -0,0 +1,14 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * Histogram buckets for UMA tracking of which type of result the History user + * clicked. + */ +export enum HistoryResultType { + TRADITIONAL = 0, + GROUPED = 1, + EMBEDDINGS = 2, + END = 3, +}
diff --git a/ui/webui/resources/cr_components/history_clusters/BUILD.gn b/ui/webui/resources/cr_components/history_clusters/BUILD.gn index 3a25340..5bd216f 100644 --- a/ui/webui/resources/cr_components/history_clusters/BUILD.gn +++ b/ui/webui/resources/cr_components/history_clusters/BUILD.gn
@@ -64,6 +64,7 @@ "../page_image_service:build_ts", "//third_party/lit/v3_0:build_ts", "//third_party/polymer/v3_0:library", + "//ui/webui/resources/cr_components/history:build_ts", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", "//ui/webui/resources/mojo:build_ts",
diff --git a/ui/webui/resources/cr_components/history_clusters/cluster.ts b/ui/webui/resources/cr_components/history_clusters/cluster.ts index 46228f6..a0b8f409 100644 --- a/ui/webui/resources/cr_components/history_clusters/cluster.ts +++ b/ui/webui/resources/cr_components/history_clusters/cluster.ts
@@ -12,6 +12,7 @@ import '//resources/polymer/v3_0/iron-collapse/iron-collapse.js'; import '//resources/cr_elements/cr_auto_img/cr_auto_img.js'; +import {HistoryResultType} from '//resources/cr_components/history/constants.js'; import {I18nMixin} from '//resources/cr_elements/i18n_mixin.js'; import {assert} from '//resources/js/assert.js'; import {loadTimeData} from '//resources/js/load_time_data.js'; @@ -186,9 +187,18 @@ ClusterAction.kVisitClicked, this.index); const visit = event.detail; + const visitIndex = this.getVisitIndex_(visit); MetricsProxyImpl.getInstance().recordVisitAction( - VisitAction.kClicked, this.getVisitIndex_(visit), - MetricsProxyImpl.getVisitType(visit)); + VisitAction.kClicked, visitIndex, MetricsProxyImpl.getVisitType(visit)); + + this.dispatchEvent(new CustomEvent('record-history-link-click', { + bubbles: true, + composed: true, + detail: { + resultType: HistoryResultType.GROUPED, + index: visitIndex, + }, + })); } private onOpenAllVisits_() {
diff --git a/ui/webui/resources/cr_components/history_embeddings/BUILD.gn b/ui/webui/resources/cr_components/history_embeddings/BUILD.gn index 9cefa67e..937a1cc 100644 --- a/ui/webui/resources/cr_components/history_embeddings/BUILD.gn +++ b/ui/webui/resources/cr_components/history_embeddings/BUILD.gn
@@ -33,6 +33,7 @@ ts_composite = true ts_deps = [ "//third_party/polymer/v3_0:library", + "//ui/webui/resources/cr_components/history:build_ts", "//ui/webui/resources/cr_elements:build_ts", "//ui/webui/resources/js:build_ts", "//ui/webui/resources/mojo:build_ts",
diff --git a/ui/webui/resources/cr_components/history_embeddings/history_embeddings.html b/ui/webui/resources/cr_components/history_embeddings/history_embeddings.html index 6054f54..c3536dd 100644 --- a/ui/webui/resources/cr_components/history_embeddings/history_embeddings.html +++ b/ui/webui/resources/cr_components/history_embeddings/history_embeddings.html
@@ -94,7 +94,8 @@ <template is="dom-repeat" items="[[searchResult_.items]]"> <cr-url-list-item url="[[item.url.url]]" title="[[item.title]]" description="[[item.urlForDisplay]]" - on-click="onResultClick_" as-anchor always-show-suffix> + on-click="onResultClick_" on-auxclick="onResultClick_" + as-anchor always-show-suffix> <span slot="suffix">[[item.relativeTime]]</span> <cr-icon-button slot="suffix" iron-icon="cr:more-vert" on-click="onMoreActionsClick_">
diff --git a/ui/webui/resources/cr_components/history_embeddings/history_embeddings.ts b/ui/webui/resources/cr_components/history_embeddings/history_embeddings.ts index a4af990..9668d15 100644 --- a/ui/webui/resources/cr_components/history_embeddings/history_embeddings.ts +++ b/ui/webui/resources/cr_components/history_embeddings/history_embeddings.ts
@@ -10,6 +10,7 @@ import '//resources/cr_elements/cr_shared_vars.css.js'; import '//resources/cr_elements/cr_url_list_item/cr_url_list_item.js'; +import {HistoryResultType} from '//resources/cr_components/history/constants.js'; import type {CrActionMenuElement} from '//resources/cr_elements/cr_action_menu/cr_action_menu.js'; import type {CrLazyRenderElement} from '//resources/cr_elements/cr_lazy_render/cr_lazy_render.js'; import {I18nMixin} from '//resources/cr_elements/i18n_mixin.js'; @@ -125,6 +126,15 @@ private onResultClick_(e: DomRepeatEvent<SearchResultItem>) { this.dispatchEvent(new CustomEvent('result-click', {detail: e.model.item})); + + this.dispatchEvent(new CustomEvent('record-history-link-click', { + bubbles: true, + composed: true, + detail: { + resultType: HistoryResultType.EMBEDDINGS, + index: e.model.index, + }, + })); } private onSearchQueryChanged_() {
diff --git a/ui/webui/resources/cr_elements/cr_icon/iconset_map.ts b/ui/webui/resources/cr_elements/cr_icon/iconset_map.ts index 91e3733b8c..df89445 100644 --- a/ui/webui/resources/cr_elements/cr_icon/iconset_map.ts +++ b/ui/webui/resources/cr_elements/cr_icon/iconset_map.ts
@@ -20,18 +20,27 @@ window.addEventListener('iron-iconset-added', e => { const event = e as unknown as CustomEvent<Iconset>; const map = IconsetMap.getInstance(); - map.set(event.detail.name, event.detail); + map.setIronIconset(event.detail.name, event.detail); }); export class IconsetMap extends EventTarget { private iconsets_: Map<string, Iconset> = new Map(); + private ironIconsets_: Map<string, Iconset> = new Map(); static getInstance() { return iconsetMap || (iconsetMap = new IconsetMap()); } get(id: string): Iconset|null { - return this.iconsets_.get(id) || null; + return this.iconsets_.get(id) || this.ironIconsets_.get(id) || null; + } + + // Remove this method once iron-iconset is no longer used. + setIronIconset(id: string, iconset: Iconset) { + assert(!this.ironIconsets_.has(id), + 'Tried to add a second iron-iconset with id ' + id); + this.ironIconsets_.set(id, iconset); + this.dispatchEvent(new CustomEvent('cr-iconset-added', {detail: id})); } set(id: string, iconset: Iconset) {
diff --git a/v8 b/v8 index 628dd19..3d675d1a 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit 628dd1909b2405aa0a68f9bd1aa00bbe5bc717b0 +Subproject commit 3d675d1ac3f96a60508bffa312e48bd46ddb466f