diff --git a/DEPS b/DEPS index e7aa029..6ac9cfc 100644 --- a/DEPS +++ b/DEPS
@@ -224,7 +224,7 @@ # luci-go CIPD package version. # Make sure the revision is uploaded by infra-packagers builder. # https://ci.chromium.org/p/infra-internal/g/infra-packagers/console - 'luci_go': 'git_revision:dbbe363b4b1aa09520e53ccdd2d52cb661875e53', + 'luci_go': 'git_revision:94ce62005f7d368ce9e36897e15bb570cf0d0027', # This can be overridden, e.g. with custom_vars, to build clang from HEAD # instead of downloading the prebuilt pinned revision. @@ -276,19 +276,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': 'ef593bebcf9e5a9d111c4f12d0732bf1366ca4b7', + 'src_internal_revision': 'f367c8fba0bcc44119ac34aa2e11dd2326780db6', # 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': '7fc6934b20348e6609552918b9d09da0d6f03457', + 'skia_revision': '804042d752991d6753dd17f8585d6f8fe951492f', # 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': '27d5ca8ed62889fc9974afc2fd89c078582d5dd4', + 'v8_revision': '99d615b4cef42ad9a32639547e8ac4bd7db462e5', # 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': 'e72cc71b28a13ec0dcd9791bc2467f55482afa35', + 'angle_revision': '1c096a8589802f2cdc12cd423a1b6f248fc930b0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -296,11 +296,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'bea10144d15d4f9f55d78095dcbf931c3d3b2813', + 'pdfium_revision': 'b69783fd189976dd4625c7dcd9c07921b94d4a3c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. - 'boringssl_revision': 'f49081b4ef4e99bae452e05170d8433807bd70e9', + 'boringssl_revision': '59fc5189630ab1409555647f361ece64930a50ca', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. @@ -328,7 +328,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': '59320b2d3c2584ac01914ed0deff64bcc8fb23b2', + 'freetype_revision': '38272bf85341348eb0a5162ba4e1c95d370f9bce', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -348,15 +348,15 @@ # 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': '452b85ea51998d34386f3b7f8bd711ba12e5d4b7', + 'catapult_revision': 'abd0e1e8ccd7f38681b8c9503bbf4c14220c86f3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling chromium_variations # and whatever else without interference from each other. - 'chromium_variations_revision': '57ea908f6afb7ef24fc1d28158837173a641617d', + 'chromium_variations_revision': '75345f6fdba14f81b63ccf0530c6fb5adfc9a103', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. - 'crossbench_revision': 'ed3404ed0b31ef20837f60d2aef1e405284e9549', + 'crossbench_revision': 'cdb37eabb31cf3b1723a1692b9762158f197730a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -372,7 +372,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '6551e43966d7dd4d085ca6c0fc05a9ef2f3f4176', + 'devtools_frontend_revision': '7d0851a8ce15f96e59c8c25fd2b5db32b0475d3d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -396,7 +396,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'afc9c139de7ea3a911171da83ac6922a0089fe34', + 'dawn_revision': 'eaeba81b24c7b6e0af1b621c3a3479bfb52a1fab', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -468,7 +468,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'libcxxabi_revision': '574b92bc1d7aa586ed30e4e9923041d1ec495017', + 'libcxxabi_revision': '77e59bec0fb93d9733378e1b6188bae0efdbc32e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -496,7 +496,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling llvm-libc # and whatever else without interference from each other. - 'llvm_libc_revision': 'c8307c52cdf40133e725a3d0912e2fa60ef014b3', + 'llvm_libc_revision': '09341dae519a08cbb4b0c58f5409b722073d2eff', # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. @@ -1304,16 +1304,16 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '5c28d3db4b56fc58531352e6cb59a7c8db2db9e3', + '94e9a17ca9d53b1cd11478b59a5185931ca5d547', 'condition': 'checkout_android and checkout_src_internal', }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + 'ffa936be041b042d683f68b68ec4f141133530e2', + 'url': Var('chromium_git') + '/website.git' + '@' + '31a2f432dc14e60054e2a361f4fa16ffff65e01b', }, 'src/ios/third_party/earl_grey2/src': { - 'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + '598d8e856bc259d9632cd26e944d46d721c43071', + 'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + '2add385c1c502920dd753dfb1fbd830b194f7809', 'condition': 'checkout_ios', }, @@ -1567,7 +1567,7 @@ 'packages': [ { 'package': 'chromium/third_party/android_build_tools/manifest_merger', - 'version': 'gsCtvMuqN-QovWEu4yfq_-E0wb0sL2kbuqtNEODHfFkC', + 'version': 'X4iLz22sYpi8ovi3X8Iv6PXgOcy2934mOa16hL5-w2gC', }, ], 'condition': 'checkout_android and non_git_source', @@ -1799,7 +1799,7 @@ 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'cbead190e5a4badb427fda83c7a57868b634511e', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'f548b21cd3554d013ac0bc53a6cb1ae0de79e2f8', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -2301,7 +2301,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '6361af291ce8ffd1f992fec3f44483c00bba124e', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '5bf4e2a65d76d5a603ff175222d1513f71d28a0b', 'src/base/tracing/test/data': { 'bucket': 'perfetto', @@ -2483,7 +2483,7 @@ 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': '4GP31XSTv8hw3F8OO6XHx00UfLiyEz2CDY9jcjJa9XUC', + 'version': 'q_wvk54XItTBlBNQMHkS4NRMp-tapPW97M292KTXHrsC', }, ], 'condition': 'checkout_android and non_git_source', @@ -2604,7 +2604,7 @@ Var('chromium_git') + '/external/github.com/GoogleChromeLabs/text-fragments-polyfill.git' + '@' + 'c036420683f672d685e27415de0a5f5e85bdc23f', 'src/third_party/tflite/src': - Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + '3ed58a749e37e7e45f1771e9c60f0fffbf139d4c', + Var('chromium_git') + '/external/github.com/tensorflow/tensorflow.git' + '@' + 'b25df276c8e912c22f57263ffcae6ca8f4c64342', 'src/third_party/turbine/cipd': { 'packages': [ @@ -2669,7 +2669,7 @@ Var('chromium_git') + '/webpagereplay.git' + '@' + Var('webpagereplay_revision'), 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '021cf5ac3ef6c5ffd8b65c7365d0f6d7ff456b9c', + Var('webrtc_git') + '/src.git' + '@' + '6ef206aa1a92ec09f936105bc19f50ece0ea297b', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -2784,7 +2784,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/eche_app/app', - 'version': 'qZm-7Wud-fUyBPomEkj7og51mxBNC6y4LN1irXirYgAC', + 'version': 'LmlIDNgYeKOXhaOkrf0-yFz8fZLBqPf7FU5jLlEUTjQC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -2795,7 +2795,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/boca_app/app', - 'version': 'qB1LRkPoZ0zFdHYSsEIRxoPCPPfdRGZmDCvkoroKAo4C', + 'version': 'tN-mkAbmQKMdLFpJju9zZmLplu3YlIZ4lEpntY6yXPsC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -2850,7 +2850,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': 'cRbLg5Udg59tUE6QxvFlY96rPtmGmUbJQBPCiklZfJgC', + 'version': 'ptGzYhmFxB58lMRbbSNUWnnNsZK0UO9kuJ3Nfjt0XIwC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -4173,7 +4173,7 @@ 'src/chromeos/assistant/internal': { 'url': Var('chrome_git') + '/chrome/assistant.git' + '@' + - '4a629f07bb5192d38397131cbbec303d81ac1179', + '366dc486f8f18d097f22acb469b8eab41b14c9ad', 'condition': 'checkout_src_internal and checkout_chromeos', }, @@ -4409,7 +4409,7 @@ 'src/components/optimization_guide/internal': { 'url': Var('chrome_git') + '/chrome/components/optimization_guide.git' + '@' + - 'b1fb5d58cb230fb5d7e2a75cff00ab025d18a6fd', + '3260a04b709daada0fdf5039d580550c0ad96c9f', 'condition': 'checkout_src_internal', }, @@ -4475,7 +4475,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - '0d766f3e5bd6d0a896a35d4e398d455f7888b805', + 'a712b786ea4b03defe96cc34b36f4dbff9f91634', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/android_webview/browser/aw_client_hints_controller_delegate.cc b/android_webview/browser/aw_client_hints_controller_delegate.cc index 1415763..5fe5debf 100644 --- a/android_webview/browser/aw_client_hints_controller_delegate.cc +++ b/android_webview/browser/aw_client_hints_controller_delegate.cc
@@ -58,15 +58,14 @@ // Regenerate the brand version lists with Android WebView product name. metadata.brand_version_list = embedder_support::GenerateBrandVersionList( major_version_number, kAndroidWebViewProductName, major_version, - std::nullopt, std::nullopt, enable_updated_grease_by_policy, + enable_updated_grease_by_policy, blink::UserAgentBrandVersionType::kMajorVersion); if (!only_low_entropy_ch) { metadata.brand_full_version_list = embedder_support::GenerateBrandVersionList( major_version_number, kAndroidWebViewProductName, - metadata.full_version, std::nullopt, std::nullopt, - enable_updated_grease_by_policy, + metadata.full_version, enable_updated_grease_by_policy, blink::UserAgentBrandVersionType::kFullVersion); }
diff --git a/android_webview/browser/component_updater/trust_token_key_commitments_component_loader.cc b/android_webview/browser/component_updater/trust_token_key_commitments_component_loader.cc index 122ee64..f266298 100644 --- a/android_webview/browser/component_updater/trust_token_key_commitments_component_loader.cc +++ b/android_webview/browser/component_updater/trust_token_key_commitments_component_loader.cc
@@ -8,12 +8,10 @@ #include <string> #include <vector> -#include "base/feature_list.h" #include "base/functional/bind.h" #include "base/logging.h" #include "components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.h" #include "content/public/browser/network_service_instance.h" -#include "services/network/public/cpp/features.h" #include "services/network/public/mojom/network_service.mojom.h" namespace android_webview { @@ -22,11 +20,6 @@ // Tokens is enabled. void LoadTrustTokenKeyCommitmentsComponent( ComponentLoaderPolicyVector& policies) { - if (!base::FeatureList::IsEnabled(network::features::kPrivateStateTokens) && - !base::FeatureList::IsEnabled(network::features::kFledgePst)) { - return; - } - DVLOG(1) << "Registering Trust Token Key Commitments component for loading in " "embedded WebView.";
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 0e26f8b..87afcd1 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
@@ -332,9 +332,6 @@ "When enabled, merchant bound virtual cards will be offered in the keyboard " + "accessory."), Flag.baseFeature( - NetworkServiceFeatures.PRIVATE_STATE_TOKENS, - "Enables the prototype Private State Tokens API."), - Flag.baseFeature( NetworkServiceFeatures.MASKED_DOMAIN_LIST, "When enabled, the masked domain list required for IP Protection is loaded."), Flag.commandLine( @@ -760,8 +757,6 @@ + " to enable BFCache through AwSettings as well. If either of" + " the flag / setting is enabled, BFCache will be enabled"), Flag.baseFeature( - ContentFeatures.WEBVIEW_SUPPRESS_TAP_DURING_FLING, "Supress tap during fling."), - Flag.baseFeature( ContentFeatures.ACCESSIBILITY_MANAGE_BROADCAST_RECEIVER_ON_BACKGROUND, "Register, un-register Accessibility broadcast receiver on a background thread."), Flag.baseFeature(
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/WebExposedTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/WebExposedTest.java index c1769df17..cb655d7 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/WebExposedTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/WebExposedTest.java
@@ -31,7 +31,6 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.UrlUtils; import java.io.File; @@ -161,7 +160,6 @@ "enable-experimental-web-platform-features", "enable-blink-test-features", }) - @DisabledTest(message = "crbug.com/381090604 - requires new baseline") public void testGlobalInterfaceListingUnstable() throws Exception { doTestGlobalInterfaceListing(""); } @@ -169,7 +167,6 @@ @Test @LargeTest @CommandLineFlags.Add({"disable-field-trial-config"}) - @DisabledTest(message = "crbug.com/381090604 - requires new baseline") public void testGlobalInterfaceListingStable() throws Exception { doTestGlobalInterfaceListing("virtual/stable/"); }
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc index df90eda..444f833 100644 --- a/android_webview/lib/aw_main_delegate.cc +++ b/android_webview/lib/aw_main_delegate.cc
@@ -324,16 +324,6 @@ InitIcuAndResourceBundleBrowserSide(); aw_feature_list_creator_->CreateFeatureListAndFieldTrials(); content::InitializeMojoCore(); - - // WebView apps can override WebView#computeScroll to achieve custom - // scroll/fling. As a result, fling animations may not be ticked, - // potentially - // confusing the tap suppression controller. Simply disable it for WebView - if (!base::FeatureList::IsEnabled( - ::features::kWebViewSuppressTapDuringFling)) { - ui::GestureConfiguration::GetInstance() - ->set_fling_touchscreen_tap_suppression_enabled(false); - } } InitializeMemorySystem(is_browser_process);
diff --git a/android_webview/test/data/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/android_webview/test/data/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index 704a882..1bbc10a 100644 --- a/android_webview/test/data/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/android_webview/test/data/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -1,5 +1,10 @@ This test documents all interface attributes and methods on the global window object and element instances. [INTERFACES] +interface AICreateMonitor : EventTarget + attribute @@toStringTag + getter ondownloadprogress + method constructor + setter ondownloadprogress interface AbortController attribute @@toStringTag getter signal @@ -58,6 +63,7 @@ getter oncancel getter onfinish getter onremove + getter overallProgress getter pending getter playState getter playbackRate @@ -150,6 +156,7 @@ interface AudioContext : BaseAudioContext attribute @@toStringTag getter baseLatency + getter onerror getter onsinkchange getter outputLatency getter sinkId @@ -162,6 +169,7 @@ method resume method setSinkId method suspend + setter onerror setter onsinkchange interface AudioData attribute @@toStringTag @@ -394,6 +402,21 @@ interface CDATASection : Text attribute @@toStringTag method constructor +interface CSPViolationReportBody : ReportBody + attribute @@toStringTag + getter blockedURL + getter columnNumber + getter disposition + getter documentURL + getter effectiveDirective + getter lineNumber + getter originalPolicy + getter referrer + getter sample + getter sourceFile + getter statusCode + method constructor + method toJSON interface CSSAnimation : Animation attribute @@toStringTag getter animationName @@ -492,6 +515,12 @@ attribute @@toStringTag getter nameList method constructor +interface CSSMarginRule : CSSRule + attribute @@toStringTag + getter name + getter style + method constructor + setter style interface CSSMathClamp : CSSMathValue attribute @@toStringTag getter lower @@ -541,6 +570,11 @@ getter namespaceURI getter prefix method constructor +interface CSSNestedDeclarations : CSSRule + attribute @@toStringTag + getter style + method constructor + setter style interface CSSNumericArray attribute @@toStringTag getter length @@ -563,7 +597,7 @@ method to method toSum method type -interface CSSPageRule : CSSRule +interface CSSPageRule : CSSGroupingRule attribute @@toStringTag getter selectorText getter style @@ -575,6 +609,155 @@ getter length method constructor setter length +interface CSSPositionTryDescriptors : CSSStyleDeclaration + attribute @@toStringTag + getter align-self + getter alignSelf + getter block-size + getter blockSize + getter bottom + getter height + getter inline-size + getter inlineSize + getter inset + getter inset-block + getter inset-block-end + getter inset-block-start + getter inset-inline + getter inset-inline-end + getter inset-inline-start + getter insetBlock + getter insetBlockEnd + getter insetBlockStart + getter insetInline + getter insetInlineEnd + getter insetInlineStart + getter justify-self + getter justifySelf + getter left + getter margin + getter margin-block + getter margin-block-end + getter margin-block-start + getter margin-bottom + getter margin-inline + getter margin-inline-end + getter margin-inline-start + getter margin-left + getter margin-right + getter margin-top + getter marginBlock + getter marginBlockEnd + getter marginBlockStart + getter marginBottom + getter marginInline + getter marginInlineEnd + getter marginInlineStart + getter marginLeft + getter marginRight + getter marginTop + getter max-block-size + getter max-height + getter max-inline-size + getter max-width + getter maxBlockSize + getter maxHeight + getter maxInlineSize + getter maxWidth + getter min-block-size + getter min-height + getter min-inline-size + getter min-width + getter minBlockSize + getter minHeight + getter minInlineSize + getter minWidth + getter place-self + getter placeSelf + getter position-anchor + getter position-area + getter positionAnchor + getter positionArea + getter right + getter top + getter width + method constructor + setter align-self + setter alignSelf + setter block-size + setter blockSize + setter bottom + setter height + setter inline-size + setter inlineSize + setter inset + setter inset-block + setter inset-block-end + setter inset-block-start + setter inset-inline + setter inset-inline-end + setter inset-inline-start + setter insetBlock + setter insetBlockEnd + setter insetBlockStart + setter insetInline + setter insetInlineEnd + setter insetInlineStart + setter justify-self + setter justifySelf + setter left + setter margin + setter margin-block + setter margin-block-end + setter margin-block-start + setter margin-bottom + setter margin-inline + setter margin-inline-end + setter margin-inline-start + setter margin-left + setter margin-right + setter margin-top + setter marginBlock + setter marginBlockEnd + setter marginBlockStart + setter marginBottom + setter marginInline + setter marginInlineEnd + setter marginInlineStart + setter marginLeft + setter marginRight + setter marginTop + setter max-block-size + setter max-height + setter max-inline-size + setter max-width + setter maxBlockSize + setter maxHeight + setter maxInlineSize + setter maxWidth + setter min-block-size + setter min-height + setter min-inline-size + setter min-width + setter minBlockSize + setter minHeight + setter minInlineSize + setter minWidth + setter place-self + setter placeSelf + setter position-anchor + setter position-area + setter positionAnchor + setter positionArea + setter right + setter top + setter width +interface CSSPositionTryRule : CSSRule + attribute @@toStringTag + getter name + getter style + method constructor + setter style interface CSSPositionValue : CSSStyleValue attribute @@toStringTag getter x @@ -609,6 +792,7 @@ attribute IMPORT_RULE attribute KEYFRAMES_RULE attribute KEYFRAME_RULE + attribute MARGIN_RULE attribute MEDIA_RULE attribute NAMESPACE_RULE attribute PAGE_RULE @@ -759,6 +943,11 @@ getter variable method constructor setter variable +interface CSSViewTransitionRule : CSSRule + attribute @@toStringTag + getter navigation + getter types + method constructor interface Cache attribute @@toStringTag method add @@ -891,12 +1080,24 @@ setter textBaseline setter textRendering setter wordSpacing +interface CaretPosition + attribute @@toStringTag + getter offset + getter offsetNode + method constructor + method getClientRect interface ChannelMergerNode : AudioNode attribute @@toStringTag method constructor interface ChannelSplitterNode : AudioNode attribute @@toStringTag method constructor +interface ChapterInformation + attribute @@toStringTag + getter artwork + getter startTime + getter title + method constructor interface CharacterBoundsUpdateEvent : Event attribute @@toStringTag getter rangeEnd @@ -943,6 +1144,16 @@ getter reason getter wasClean method constructor +interface CloseWatcher : EventTarget + attribute @@toStringTag + getter oncancel + getter onclose + method close + method constructor + method destroy + method requestClose + setter oncancel + setter onclose interface Comment : CharacterData attribute @@toStringTag method constructor @@ -1326,6 +1537,7 @@ getter type method constructor method getAsFile + method getAsFileSystemHandle method getAsString method webkitGetAsEntry interface DataTransferItemList @@ -1347,7 +1559,6 @@ method constructor interface DelegatedInkTrailPresenter attribute @@toStringTag - getter expectedImprovement getter presentationArea method constructor method updateInkTrailStartPoint @@ -1510,6 +1721,8 @@ getter onresume getter onscroll getter onscrollend + getter onscrollsnapchange + getter onscrollsnapchanging getter onsearch getter onsecuritypolicyviolation getter onseeked @@ -1568,7 +1781,9 @@ getter xmlVersion method adoptNode method append + method browsingTopics method captureEvents + method caretPositionFromPoint method caretRangeFromPoint method clear method close @@ -1725,6 +1940,8 @@ setter onresume setter onscroll setter onscrollend + setter onscrollsnapchange + setter onscrollsnapchanging setter onsearch setter onsecuritypolicyviolation setter onseeked @@ -1836,6 +2053,7 @@ getter ariaChecked getter ariaColCount getter ariaColIndex + getter ariaColIndexText getter ariaColSpan getter ariaCurrent getter ariaDescription @@ -1861,6 +2079,7 @@ getter ariaRoleDescription getter ariaRowCount getter ariaRowIndex + getter ariaRowIndexText getter ariaRowSpan getter ariaSelected getter ariaSetSize @@ -1879,6 +2098,7 @@ getter clientLeft getter clientTop getter clientWidth + getter currentCSSZoom getter elementTiming getter firstElementChild getter id @@ -1927,7 +2147,7 @@ method getElementsByClassName method getElementsByTagName method getElementsByTagNameNS - method getInnerHTML + method getHTML method hasAttribute method hasAttributeNS method hasAttributes @@ -1971,6 +2191,7 @@ setter ariaChecked setter ariaColCount setter ariaColIndex + setter ariaColIndexText setter ariaColSpan setter ariaCurrent setter ariaDescription @@ -1996,6 +2217,7 @@ setter ariaRoleDescription setter ariaRowCount setter ariaRowIndex + setter ariaRowIndexText setter ariaRowSpan setter ariaSelected setter ariaSetSize @@ -2033,6 +2255,7 @@ getter ariaChecked getter ariaColCount getter ariaColIndex + getter ariaColIndexText getter ariaColSpan getter ariaCurrent getter ariaDescription @@ -2058,6 +2281,7 @@ getter ariaRoleDescription getter ariaRowCount getter ariaRowIndex + getter ariaRowIndexText getter ariaRowSpan getter ariaSelected getter ariaSetSize @@ -2087,6 +2311,7 @@ setter ariaChecked setter ariaColCount setter ariaColIndex + setter ariaColIndexText setter ariaColSpan setter ariaCurrent setter ariaDescription @@ -2112,6 +2337,7 @@ setter ariaRoleDescription setter ariaRowCount setter ariaRowIndex + setter ariaRowIndexText setter ariaRowSpan setter ariaSelected setter ariaSetSize @@ -2402,6 +2628,7 @@ getter canvas method configure method constructor + method getConfiguration method getCurrentTexture method unconfigure interface GPUCommandBuffer @@ -2461,6 +2688,7 @@ setter label interface GPUDevice : EventTarget attribute @@toStringTag + getter adapterInfo getter features getter label getter limits @@ -2698,6 +2926,7 @@ method constructor interface GamepadHapticActuator attribute @@toStringTag + getter effects getter type method constructor method playEffect @@ -2807,6 +3036,7 @@ interface HTMLAreaElement : HTMLElement attribute @@toStringTag getter alt + getter attributionSrc getter coords getter download getter hash @@ -2830,6 +3060,7 @@ method constructor method toString setter alt + setter attributionSrc setter coords setter download setter hash @@ -3120,6 +3351,8 @@ getter onresize getter onscroll getter onscrollend + getter onscrollsnapchange + getter onscrollsnapchanging getter onsecuritypolicyviolation getter onseeked getter onseeking @@ -3253,6 +3486,8 @@ setter onresize setter onscroll setter onscrollend + setter onscrollsnapchange + setter onscrollsnapchanging setter onsecuritypolicyviolation setter onseeked setter onseeking @@ -3474,6 +3709,7 @@ getter align getter allow getter allowFullscreen + getter browsingTopics getter contentDocument getter contentWindow getter credentialless @@ -3499,6 +3735,7 @@ setter align setter allow setter allowFullscreen + setter browsingTopics setter credentialless setter csp setter frameBorder @@ -4265,10 +4502,12 @@ getter shadowRootClonable getter shadowRootDelegatesFocus getter shadowRootMode + getter shadowRootSerializable method constructor setter shadowRootClonable setter shadowRootDelegatesFocus setter shadowRootMode + setter shadowRootSerializable interface HTMLTextAreaElement : HTMLElement attribute @@toStringTag getter autocomplete @@ -4369,19 +4608,13 @@ getter videoHeight getter videoWidth getter webkitDecodedFrameCount - getter webkitDisplayingFullscreen getter webkitDroppedFrameCount - getter webkitSupportsFullscreen getter width method cancelVideoFrameCallback method constructor method getVideoPlaybackQuality method requestPictureInPicture method requestVideoFrameCallback - method webkitEnterFullScreen - method webkitEnterFullscreen - method webkitExitFullScreen - method webkitExitFullscreen setter disablePictureInPicture setter height setter onenterpictureinpicture @@ -4985,6 +5218,8 @@ getter onresize getter onscroll getter onscrollend + getter onscrollsnapchange + getter onscrollsnapchanging getter onsecuritypolicyviolation getter onseeked getter onseeking @@ -5094,6 +5329,8 @@ setter onresize setter onscroll setter onscrollend + setter onscrollsnapchange + setter onscrollsnapchanging setter onsecuritypolicyviolation setter onseeked setter onseeking @@ -5138,10 +5375,12 @@ method toJSON interface MediaDevices : EventTarget attribute @@toStringTag + getter ondevicechange method constructor method enumerateDevices method getSupportedConstraints method getUserMedia + setter ondevicechange interface MediaElementAudioSourceNode : AudioNode attribute @@toStringTag getter mediaElement @@ -5337,6 +5576,19 @@ setter onended setter onmute setter onunmute +interface MediaStreamTrackAudioStats + attribute @@toStringTag + getter averageLatency + getter deliveredFrames + getter deliveredFramesDuration + getter latency + getter maximumLatency + getter minimumLatency + getter totalFrames + getter totalFramesDuration + method constructor + method resetLatency + method toJSON interface MediaStreamTrackEvent : Event attribute @@toStringTag getter track @@ -5423,18 +5675,6 @@ method constructor method getModifierState method initMouseEvent -interface MutationEvent : Event - attribute @@toStringTag - attribute ADDITION - attribute MODIFICATION - attribute REMOVAL - getter attrChange - getter attrName - getter newValue - getter prevValue - getter relatedNode - method constructor - method initMutationEvent interface MutationObserver attribute @@toStringTag method constructor @@ -5604,6 +5844,7 @@ getter mimeTypes getter onLine getter pdfViewerEnabled + getter permissions getter platform getter plugins getter product @@ -5911,10 +6152,12 @@ method constructor interface PageRevealEvent : Event attribute @@toStringTag + getter viewTransition method constructor interface PageSwapEvent : Event attribute @@toStringTag getter activation + getter viewTransition method constructor interface PageTransitionEvent : Event attribute @@toStringTag @@ -6093,6 +6336,7 @@ getter domainLookupStart getter encodedBodySize getter fetchStart + getter finalResponseHeadersStart getter firstInterimResponseStart getter initiatorType getter nextHopProtocol @@ -6158,6 +6402,17 @@ interface PeriodicWave attribute @@toStringTag method constructor +interface PermissionStatus : EventTarget + attribute @@toStringTag + getter name + getter onchange + getter state + method constructor + setter onchange +interface Permissions + attribute @@toStringTag + method constructor + method query interface PictureInPictureEvent : Event attribute @@toStringTag getter pictureInPictureWindow @@ -6193,6 +6448,7 @@ getter azimuthAngle getter height getter isPrimary + getter persistentDeviceId getter pointerId getter pointerType getter pressure @@ -6209,21 +6465,6 @@ getter hasUAVisualTransition getter state method constructor -interface PressureObserver - static getter supportedSources - attribute @@toStringTag - method constructor - method disconnect - method observe - method takeRecords - method unobserve -interface PressureRecord - attribute @@toStringTag - getter source - getter state - getter time - method constructor - method toJSON interface ProcessingInstruction : CharacterData attribute @@toStringTag getter sheet @@ -6246,6 +6487,10 @@ getter promise getter reason method constructor +interface ProtectedAudience + attribute @@toStringTag + method constructor + method queryFeatureSupport interface RTCCertificate attribute @@toStringTag getter expires @@ -6616,6 +6861,10 @@ interface RelativeOrientationSensor : OrientationSensor attribute @@toStringTag method constructor +interface ReportBody + attribute @@toStringTag + method constructor + method toJSON interface ReportingObserver attribute @@toStringTag method constructor @@ -6629,6 +6878,7 @@ getter cache getter credentials getter destination + getter duplex getter headers getter integrity getter isHistoryNavigation @@ -6919,6 +7169,8 @@ getter onresize getter onscroll getter onscrollend + getter onscrollsnapchange + getter onscrollsnapchanging getter onsecuritypolicyviolation getter onseeked getter onseeking @@ -7030,6 +7282,8 @@ setter onresize setter onscroll setter onscrollend + setter onscrollsnapchange + setter onscrollsnapchanging setter onsecuritypolicyviolation setter onseeked setter onseeking @@ -7845,6 +8099,7 @@ attribute @@toStringTag method constructor method postTask + method yield interface Scheduling attribute @@toStringTag method constructor @@ -8019,19 +8274,25 @@ getter onslotchange getter pictureInPictureElement getter pointerLockElement + getter serializable getter slotAssignment getter styleSheets method constructor method elementFromPoint method elementsFromPoint method getAnimations - method getInnerHTML + method getHTML method getSelection method setHTMLUnsafe setter adoptedStyleSheets setter fullscreenElement setter innerHTML setter onslotchange +interface SnapEvent : Event + attribute @@toStringTag + getter snapTargetBlock + getter snapTargetInline + method constructor interface SourceBuffer : EventTarget attribute @@toStringTag getter appendWindowEnd @@ -8111,7 +8372,7 @@ getter url method constructor method initStorageEvent -interface StorageManager : EventTarget +interface StorageManager attribute @@toStringTag method constructor method estimate @@ -8445,6 +8706,7 @@ interface URL static method canParse static method createObjectURL + static method parse static method revokeObjectURL attribute @@toStringTag getter hash @@ -8648,6 +8910,7 @@ getter offsetTop getter onresize getter onscroll + getter onscrollend getter pageLeft getter pageTop getter scale @@ -8655,6 +8918,7 @@ method constructor setter onresize setter onscroll + setter onscrollend interface WGSLLanguageFeatures attribute @@toStringTag getter size @@ -9485,23 +9749,26 @@ getter size getter type method constructor -interface WebGLBuffer +interface WebGLBuffer : WebGLObject attribute @@toStringTag method constructor interface WebGLContextEvent : Event attribute @@toStringTag getter statusMessage method constructor -interface WebGLFramebuffer +interface WebGLFramebuffer : WebGLObject attribute @@toStringTag method constructor -interface WebGLProgram +interface WebGLObject attribute @@toStringTag method constructor -interface WebGLQuery +interface WebGLProgram : WebGLObject attribute @@toStringTag method constructor -interface WebGLRenderbuffer +interface WebGLQuery : WebGLObject + attribute @@toStringTag + method constructor +interface WebGLRenderbuffer : WebGLObject attribute @@toStringTag method constructor interface WebGLRenderingContext @@ -9950,10 +10217,10 @@ method viewport setter drawingBufferColorSpace setter unpackColorSpace -interface WebGLSampler +interface WebGLSampler : WebGLObject attribute @@toStringTag method constructor -interface WebGLShader +interface WebGLShader : WebGLObject attribute @@toStringTag method constructor interface WebGLShaderPrecisionFormat @@ -9962,19 +10229,19 @@ getter rangeMax getter rangeMin method constructor -interface WebGLSync +interface WebGLSync : WebGLObject attribute @@toStringTag method constructor -interface WebGLTexture +interface WebGLTexture : WebGLObject attribute @@toStringTag method constructor -interface WebGLTransformFeedback +interface WebGLTransformFeedback : WebGLObject attribute @@toStringTag method constructor interface WebGLUniformLocation attribute @@toStringTag method constructor -interface WebGLVertexArrayObject +interface WebGLVertexArrayObject : WebGLObject attribute @@toStringTag method constructor interface WebKitCSSMatrix : DOMMatrixReadOnly @@ -10420,6 +10687,7 @@ interface webkitURL static method canParse static method createObjectURL + static method parse static method revokeObjectURL attribute @@toStringTag getter hash @@ -10584,7 +10852,6 @@ setter memory [GLOBAL OBJECT] attribute android - attribute android_webview_media_token_provider_listener attribute awConsole attribute globalThis attribute propertyNamesInGlobal @@ -10709,6 +10976,8 @@ getter onresize getter onscroll getter onscrollend + getter onscrollsnapchange + getter onscrollsnapchanging getter onsearch getter onsecuritypolicyviolation getter onseeked @@ -10793,6 +11062,7 @@ method moveBy method moveTo method open + method openDatabase method postMessage method print method prompt @@ -10808,6 +11078,9 @@ method scrollTo method setInterval method setTimeout + method showDirectoryPicker + method showOpenFilePicker + method showSaveFilePicker method stop method structuredClone method webkitCancelAnimationFrame @@ -10919,6 +11192,8 @@ setter onresize setter onscroll setter onscrollend + setter onscrollsnapchange + setter onscrollsnapchanging setter onsearch setter onsecuritypolicyviolation setter onseeked
diff --git a/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt b/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt index 704a882..2dca07a0 100644 --- a/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt +++ b/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt
@@ -1,5 +1,112 @@ This test documents all interface attributes and methods on the global window object and element instances. [INTERFACES] +interface AI + attribute @@toStringTag + getter languageModel + getter rewriter + getter summarizer + getter translator + getter writer + method constructor +interface AICreateMonitor : EventTarget + attribute @@toStringTag + getter ondownloadprogress + method constructor + setter ondownloadprogress +interface AILanguageModel : EventTarget + attribute @@toStringTag + getter maxTokens + getter oncontextoverflow + getter temperature + getter tokensLeft + getter tokensSoFar + getter topK + method clone + method constructor + method countPromptTokens + method destroy + method prompt + method promptStreaming + setter oncontextoverflow +interface AILanguageModelCapabilities + attribute @@toStringTag + getter available + getter defaultTemperature + getter defaultTopK + getter maxTopK + method constructor + method languageAvailable +interface AILanguageModelFactory + attribute @@toStringTag + method capabilities + method constructor + method create +interface AIRewriter + attribute @@toStringTag + getter format + getter length + getter sharedContext + getter tone + method constructor + method destroy + method rewrite + method rewriteStreaming +interface AIRewriterFactory + attribute @@toStringTag + method availability + method constructor + method create +interface AISummarizer + attribute @@toStringTag + getter format + getter length + getter sharedContext + getter type + method constructor + method destroy + method summarize + method summarizeStreaming +interface AISummarizerCapabilities + attribute @@toStringTag + getter available + method constructor + method createOptionsAvailable + method languageAvailable +interface AISummarizerFactory + attribute @@toStringTag + method capabilities + method constructor + method create +interface AITranslator + attribute @@toStringTag + method constructor + method destroy + method translate +interface AITranslatorCapabilities + attribute @@toStringTag + getter available + method constructor + method languagePairAvailable +interface AITranslatorFactory + attribute @@toStringTag + method capabilities + method constructor + method create +interface AIWriter + attribute @@toStringTag + getter format + getter length + getter sharedContext + getter tone + method constructor + method destroy + method write + method writeStreaming +interface AIWriterFactory + attribute @@toStringTag + method availability + method constructor + method create interface AbortController attribute @@toStringTag getter signal @@ -33,6 +140,10 @@ getter y getter z method constructor +interface AmbientLightSensor : Sensor + attribute @@toStringTag + getter illuminance + method constructor interface AnalyserNode : AudioNode attribute @@toStringTag getter fftSize @@ -58,6 +169,7 @@ getter oncancel getter onfinish getter onremove + getter overallProgress getter pending getter playState getter playbackRate @@ -109,6 +221,7 @@ getter currentTime getter duration method constructor + method getCurrentTime interface Attr : Node attribute @@toStringTag getter localName @@ -120,6 +233,10 @@ getter value method constructor setter value +interface AttributePart : NodePart + attribute @@toStringTag + getter localName + method constructor interface Audio attribute @@toStringTag method constructor @@ -150,8 +267,10 @@ interface AudioContext : BaseAudioContext attribute @@toStringTag getter baseLatency + getter onerror getter onsinkchange getter outputLatency + getter playoutStats getter sinkId method close method constructor @@ -162,6 +281,7 @@ method resume method setSinkId method suspend + setter onerror setter onsinkchange interface AudioData attribute @@toStringTag @@ -262,6 +382,17 @@ method has method keys method values +interface AudioPlayoutStats + attribute @@toStringTag + getter averageLatency + getter fallbackFramesDuration + getter fallbackFramesEvents + getter maximumLatency + getter minimumLatency + getter totalFramesDuration + method constructor + method resetLatency + method toJSON interface AudioProcessingEvent : Event attribute @@toStringTag getter inputBuffer @@ -279,6 +410,28 @@ attribute @@toStringTag getter type method constructor +interface AudioTrack + attribute @@toStringTag + getter enabled + getter id + getter kind + getter label + getter language + getter sourceBuffer + method constructor + setter enabled +interface AudioTrackList : EventTarget + attribute @@toStringTag + getter length + getter onaddtrack + getter onchange + getter onremovetrack + method @@iterator + method constructor + method getTrackById + setter onaddtrack + setter onchange + setter onremovetrack interface AudioWorklet : Worklet attribute @@toStringTag method constructor @@ -289,6 +442,12 @@ getter port method constructor setter onprocessorerror +interface BackForwardCacheRestoration : PerformanceEntry + attribute @@toStringTag + getter pageshowEventEnd + getter pageshowEventStart + method constructor + method toJSON interface BarProp attribute @@toStringTag getter visible @@ -338,6 +497,11 @@ setter onchargingtimechange setter ondischargingtimechange setter onlevelchange +interface BeforeCreatePolicyEvent : Event + attribute @@toStringTag + getter policyName + method constructor + setter policyName interface BeforeInstallPromptEvent : Event attribute @@toStringTag getter platforms @@ -373,6 +537,47 @@ getter data getter timecode method constructor +interface BluetoothAdvertisingEvent : Event + attribute @@toStringTag + getter appearance + getter device + getter manufacturerData + getter name + getter rssi + getter serviceData + getter txPower + getter uuids + method constructor +interface BluetoothLEScan + attribute @@toStringTag + getter acceptAllAdvertisements + getter active + getter filters + getter keepRepeatedDevices + method constructor + method stop +interface BluetoothManufacturerDataMap + attribute @@toStringTag + getter size + method @@iterator + method constructor + method entries + method forEach + method get + method has + method keys + method values +interface BluetoothServiceDataMap + attribute @@toStringTag + getter size + method @@iterator + method constructor + method entries + method forEach + method get + method has + method keys + method values interface BroadcastChannel : EventTarget attribute @@toStringTag getter name @@ -394,10 +599,32 @@ interface CDATASection : Text attribute @@toStringTag method constructor +interface CSPViolationReportBody : ReportBody + attribute @@toStringTag + getter blockedURL + getter columnNumber + getter disposition + getter documentURL + getter effectiveDirective + getter lineNumber + getter originalPolicy + getter referrer + getter sample + getter sourceFile + getter statusCode + method constructor + method toJSON interface CSSAnimation : Animation attribute @@toStringTag getter animationName method constructor +interface CSSColorValue + static method parse + attribute @@toStringTag + method constructor + method toHSL + method toHWB + method toRGB interface CSSConditionRule : CSSGroupingRule attribute @@toStringTag getter conditionText @@ -449,6 +676,28 @@ method constructor method deleteRule method insertRule +interface CSSHSL : CSSColorValue + attribute @@toStringTag + getter alpha + getter h + getter l + getter s + method constructor + setter alpha + setter h + setter l + setter s +interface CSSHWB : CSSColorValue + attribute @@toStringTag + getter alpha + getter b + getter h + getter w + method constructor + setter alpha + setter b + setter h + setter w interface CSSImageValue : CSSStyleValue attribute @@toStringTag method constructor @@ -492,6 +741,12 @@ attribute @@toStringTag getter nameList method constructor +interface CSSMarginRule : CSSRule + attribute @@toStringTag + getter name + getter style + method constructor + setter style interface CSSMathClamp : CSSMathValue attribute @@toStringTag getter lower @@ -541,6 +796,11 @@ getter namespaceURI getter prefix method constructor +interface CSSNestedDeclarations : CSSRule + attribute @@toStringTag + getter style + method constructor + setter style interface CSSNumericArray attribute @@toStringTag getter length @@ -563,7 +823,7 @@ method to method toSum method type -interface CSSPageRule : CSSRule +interface CSSPageRule : CSSGroupingRule attribute @@toStringTag getter selectorText getter style @@ -575,6 +835,155 @@ getter length method constructor setter length +interface CSSPositionTryDescriptors : CSSStyleDeclaration + attribute @@toStringTag + getter align-self + getter alignSelf + getter block-size + getter blockSize + getter bottom + getter height + getter inline-size + getter inlineSize + getter inset + getter inset-block + getter inset-block-end + getter inset-block-start + getter inset-inline + getter inset-inline-end + getter inset-inline-start + getter insetBlock + getter insetBlockEnd + getter insetBlockStart + getter insetInline + getter insetInlineEnd + getter insetInlineStart + getter justify-self + getter justifySelf + getter left + getter margin + getter margin-block + getter margin-block-end + getter margin-block-start + getter margin-bottom + getter margin-inline + getter margin-inline-end + getter margin-inline-start + getter margin-left + getter margin-right + getter margin-top + getter marginBlock + getter marginBlockEnd + getter marginBlockStart + getter marginBottom + getter marginInline + getter marginInlineEnd + getter marginInlineStart + getter marginLeft + getter marginRight + getter marginTop + getter max-block-size + getter max-height + getter max-inline-size + getter max-width + getter maxBlockSize + getter maxHeight + getter maxInlineSize + getter maxWidth + getter min-block-size + getter min-height + getter min-inline-size + getter min-width + getter minBlockSize + getter minHeight + getter minInlineSize + getter minWidth + getter place-self + getter placeSelf + getter position-anchor + getter position-area + getter positionAnchor + getter positionArea + getter right + getter top + getter width + method constructor + setter align-self + setter alignSelf + setter block-size + setter blockSize + setter bottom + setter height + setter inline-size + setter inlineSize + setter inset + setter inset-block + setter inset-block-end + setter inset-block-start + setter inset-inline + setter inset-inline-end + setter inset-inline-start + setter insetBlock + setter insetBlockEnd + setter insetBlockStart + setter insetInline + setter insetInlineEnd + setter insetInlineStart + setter justify-self + setter justifySelf + setter left + setter margin + setter margin-block + setter margin-block-end + setter margin-block-start + setter margin-bottom + setter margin-inline + setter margin-inline-end + setter margin-inline-start + setter margin-left + setter margin-right + setter margin-top + setter marginBlock + setter marginBlockEnd + setter marginBlockStart + setter marginBottom + setter marginInline + setter marginInlineEnd + setter marginInlineStart + setter marginLeft + setter marginRight + setter marginTop + setter max-block-size + setter max-height + setter max-inline-size + setter max-width + setter maxBlockSize + setter maxHeight + setter maxInlineSize + setter maxWidth + setter min-block-size + setter min-height + setter min-inline-size + setter min-width + setter minBlockSize + setter minHeight + setter minInlineSize + setter minWidth + setter place-self + setter placeSelf + setter position-anchor + setter position-area + setter positionAnchor + setter positionArea + setter right + setter top + setter width +interface CSSPositionTryRule : CSSRule + attribute @@toStringTag + getter name + getter style + method constructor + setter style interface CSSPositionValue : CSSStyleValue attribute @@toStringTag getter x @@ -589,6 +998,17 @@ getter name getter syntax method constructor +interface CSSRGB : CSSColorValue + attribute @@toStringTag + getter alpha + getter b + getter g + getter r + method constructor + setter alpha + setter b + setter g + setter r interface CSSRotate : CSSTransformComponent attribute @@toStringTag getter angle @@ -609,6 +1029,7 @@ attribute IMPORT_RULE attribute KEYFRAMES_RULE attribute KEYFRAME_RULE + attribute MARGIN_RULE attribute MEDIA_RULE attribute NAMESPACE_RULE attribute PAGE_RULE @@ -759,6 +1180,11 @@ getter variable method constructor setter variable +interface CSSViewTransitionRule : CSSRule + attribute @@toStringTag + getter navigation + getter types + method constructor interface Cache attribute @@toStringTag method add @@ -782,6 +1208,9 @@ getter canvas method constructor method requestFrame +interface CanvasFilter + attribute @@toStringTag + method constructor interface CanvasGradient attribute @@toStringTag method addColorStop @@ -821,6 +1250,7 @@ getter wordSpacing method arc method arcTo + method beginLayer method beginPath method bezierCurveTo method clearRect @@ -830,17 +1260,24 @@ method createConicGradient method createImageData method createLinearGradient + method createMesh2DIndexBuffer + method createMesh2DUVBuffer + method createMesh2DVertexBuffer method createPattern method createRadialGradient method drawFocusIfNeeded method drawImage + method drawMesh method ellipse + method endLayer method fill method fillRect method fillText + method fillTextCluster method getContextAttributes method getImageData method getLineDash + method getTextureFormat method getTransform method isContextLost method isPointInPath @@ -848,6 +1285,7 @@ method lineTo method measureText method moveTo + method placeElement method putImageData method quadraticCurveTo method rect @@ -863,6 +1301,8 @@ method stroke method strokeRect method strokeText + method transferBackFromGPUTexture + method transferToGPUTexture method transform method translate setter direction @@ -891,12 +1331,24 @@ setter textBaseline setter textRendering setter wordSpacing +interface CaretPosition + attribute @@toStringTag + getter offset + getter offsetNode + method constructor + method getClientRect interface ChannelMergerNode : AudioNode attribute @@toStringTag method constructor interface ChannelSplitterNode : AudioNode attribute @@toStringTag method constructor +interface ChapterInformation + attribute @@toStringTag + getter artwork + getter startTime + getter title + method constructor interface CharacterBoundsUpdateEvent : Event attribute @@toStringTag getter rangeEnd @@ -920,6 +1372,16 @@ method replaceWith method substringData setter data +interface ChildNodePart : Part + attribute @@toStringTag + getter children + getter nextSibling + getter previousSibling + getter rootContainer + method clone + method constructor + method getParts + method replaceChildren interface Clipboard : EventTarget attribute @@toStringTag method constructor @@ -943,6 +1405,21 @@ getter reason getter wasClean method constructor +interface CloseWatcher : EventTarget + attribute @@toStringTag + getter oncancel + getter onclose + method close + method constructor + method destroy + method requestClose + setter oncancel + setter onclose +interface CommandEvent : Event + attribute @@toStringTag + getter command + getter source + method constructor interface Comment : CharacterData attribute @@toStringTag method constructor @@ -1326,6 +1803,7 @@ getter type method constructor method getAsFile + method getAsFileSystemHandle method getAsString method webkitGetAsEntry interface DataTransferItemList @@ -1347,11 +1825,11 @@ method constructor interface DelegatedInkTrailPresenter attribute @@toStringTag - getter expectedImprovement getter presentationArea method constructor method updateInkTrailStartPoint interface DeviceMotionEvent : Event + static method requestPermission attribute @@toStringTag getter acceleration getter accelerationIncludingGravity @@ -1371,13 +1849,25 @@ getter gamma method constructor interface DeviceOrientationEvent : Event + static method requestPermission attribute @@toStringTag getter absolute getter alpha getter beta getter gamma method constructor +interface DigitalCredential : Credential + attribute @@toStringTag + getter data + getter protocol + method constructor +interface Directive + attribute @@toStringTag + getter type + method constructor + method toString interface Document : Node + static method parseHTML static method parseHTMLUnsafe attribute @@toStringTag attribute @@unscopables @@ -1486,6 +1976,7 @@ getter onmouseover getter onmouseup getter onmousewheel + getter onoverscroll getter onpaste getter onpause getter onplay @@ -1510,6 +2001,8 @@ getter onresume getter onscroll getter onscrollend + getter onscrollsnapchange + getter onscrollsnapchanging getter onsearch getter onsecuritypolicyviolation getter onseeked @@ -1551,6 +2044,7 @@ getter rootElement getter scripts getter scrollingElement + getter softNavigations getter styleSheets getter timeline getter title @@ -1568,7 +2062,10 @@ getter xmlVersion method adoptNode method append + method ariaNotify + method browsingTopics method captureEvents + method caretPositionFromPoint method caretRangeFromPoint method clear method close @@ -1601,6 +2098,7 @@ method getElementsByName method getElementsByTagName method getElementsByTagNameNS + method getPartRoot method getSelection method hasFocus method hasPrivateToken @@ -1608,6 +2106,7 @@ method hasStorageAccess method hasUnpartitionedCookieAccess method importNode + method moveBefore method open method prepend method queryCommandEnabled @@ -1621,6 +2120,7 @@ method replaceChildren method requestStorageAccess method requestStorageAccessFor + method setSequentialFocusStartingPoint method startViewTransition method webkitCancelFullScreen method webkitExitFullscreen @@ -1701,6 +2201,7 @@ setter onmouseover setter onmouseup setter onmousewheel + setter onoverscroll setter onpaste setter onpause setter onplay @@ -1725,6 +2226,8 @@ setter onresume setter onscroll setter onscrollend + setter onscrollsnapchange + setter onscrollsnapchanging setter onsearch setter onsecuritypolicyviolation setter onseeked @@ -1770,10 +2273,18 @@ method append method constructor method getElementById + method getPartRoot + method moveBefore method prepend method querySelector method querySelectorAll method replaceChildren +interface DocumentPartRoot + attribute @@toStringTag + getter rootContainer + method clone + method constructor + method getParts interface DocumentTimeline : AnimationTimeline attribute @@toStringTag method constructor @@ -1828,6 +2339,8 @@ interface Element : Node attribute @@toStringTag attribute @@unscopables + getter anchorElement + getter ariaActiveDescendantElement getter ariaAtomic getter ariaAutoComplete getter ariaBrailleLabel @@ -1836,22 +2349,30 @@ getter ariaChecked getter ariaColCount getter ariaColIndex + getter ariaColIndexText getter ariaColSpan + getter ariaControlsElements getter ariaCurrent + getter ariaDescribedByElements getter ariaDescription + getter ariaDetailsElements getter ariaDisabled + getter ariaErrorMessageElements getter ariaExpanded + getter ariaFlowToElements getter ariaHasPopup getter ariaHidden getter ariaInvalid getter ariaKeyShortcuts getter ariaLabel + getter ariaLabelledByElements getter ariaLevel getter ariaLive getter ariaModal getter ariaMultiLine getter ariaMultiSelectable getter ariaOrientation + getter ariaOwnsElements getter ariaPlaceholder getter ariaPosInSet getter ariaPressed @@ -1861,6 +2382,7 @@ getter ariaRoleDescription getter ariaRowCount getter ariaRowIndex + getter ariaRowIndexText getter ariaRowSpan getter ariaSelected getter ariaSetSize @@ -1869,6 +2391,7 @@ getter ariaValueMin getter ariaValueNow getter ariaValueText + getter ariaVirtualContent getter assignedSlot getter attributes getter childElementCount @@ -1879,6 +2402,9 @@ getter clientLeft getter clientTop getter clientWidth + getter computedName + getter computedRole + getter currentCSSZoom getter elementTiming getter firstElementChild getter id @@ -1910,6 +2436,7 @@ method after method animate method append + method ariaNotify method attachShadow method before method checkVisibility @@ -1927,7 +2454,7 @@ method getElementsByClassName method getElementsByTagName method getElementsByTagNameNS - method getInnerHTML + method getHTML method hasAttribute method hasAttributeNS method hasAttributes @@ -1936,6 +2463,7 @@ method insertAdjacentHTML method insertAdjacentText method matches + method moveBefore method prepend method querySelector method querySelectorAll @@ -1957,12 +2485,15 @@ method setAttributeNS method setAttributeNode method setAttributeNodeNS + method setHTML method setHTMLUnsafe method setPointerCapture method toggleAttribute method webkitMatchesSelector method webkitRequestFullScreen method webkitRequestFullscreen + setter anchorElement + setter ariaActiveDescendantElement setter ariaAtomic setter ariaAutoComplete setter ariaBrailleLabel @@ -1971,22 +2502,30 @@ setter ariaChecked setter ariaColCount setter ariaColIndex + setter ariaColIndexText setter ariaColSpan + setter ariaControlsElements setter ariaCurrent + setter ariaDescribedByElements setter ariaDescription + setter ariaDetailsElements setter ariaDisabled + setter ariaErrorMessageElements setter ariaExpanded + setter ariaFlowToElements setter ariaHasPopup setter ariaHidden setter ariaInvalid setter ariaKeyShortcuts setter ariaLabel + setter ariaLabelledByElements setter ariaLevel setter ariaLive setter ariaModal setter ariaMultiLine setter ariaMultiSelectable setter ariaOrientation + setter ariaOwnsElements setter ariaPlaceholder setter ariaPosInSet setter ariaPressed @@ -1996,6 +2535,7 @@ setter ariaRoleDescription setter ariaRowCount setter ariaRowIndex + setter ariaRowIndexText setter ariaRowSpan setter ariaSelected setter ariaSetSize @@ -2004,6 +2544,7 @@ setter ariaValueMin setter ariaValueNow setter ariaValueText + setter ariaVirtualContent setter classList setter className setter elementTiming @@ -2025,6 +2566,7 @@ setter slot interface ElementInternals attribute @@toStringTag + getter ariaActiveDescendantElement getter ariaAtomic getter ariaAutoComplete getter ariaBrailleLabel @@ -2033,22 +2575,30 @@ getter ariaChecked getter ariaColCount getter ariaColIndex + getter ariaColIndexText getter ariaColSpan + getter ariaControlsElements getter ariaCurrent + getter ariaDescribedByElements getter ariaDescription + getter ariaDetailsElements getter ariaDisabled + getter ariaErrorMessageElements getter ariaExpanded + getter ariaFlowToElements getter ariaHasPopup getter ariaHidden getter ariaInvalid getter ariaKeyShortcuts getter ariaLabel + getter ariaLabelledByElements getter ariaLevel getter ariaLive getter ariaModal getter ariaMultiLine getter ariaMultiSelectable getter ariaOrientation + getter ariaOwnsElements getter ariaPlaceholder getter ariaPosInSet getter ariaPressed @@ -2058,6 +2608,7 @@ getter ariaRoleDescription getter ariaRowCount getter ariaRowIndex + getter ariaRowIndexText getter ariaRowSpan getter ariaSelected getter ariaSetSize @@ -2066,6 +2617,7 @@ getter ariaValueMin getter ariaValueNow getter ariaValueText + getter ariaVirtualContent getter form getter labels getter role @@ -2079,6 +2631,7 @@ method reportValidity method setFormValue method setValidity + setter ariaActiveDescendantElement setter ariaAtomic setter ariaAutoComplete setter ariaBrailleLabel @@ -2087,22 +2640,30 @@ setter ariaChecked setter ariaColCount setter ariaColIndex + setter ariaColIndexText setter ariaColSpan + setter ariaControlsElements setter ariaCurrent + setter ariaDescribedByElements setter ariaDescription + setter ariaDetailsElements setter ariaDisabled + setter ariaErrorMessageElements setter ariaExpanded + setter ariaFlowToElements setter ariaHasPopup setter ariaHidden setter ariaInvalid setter ariaKeyShortcuts setter ariaLabel + setter ariaLabelledByElements setter ariaLevel setter ariaLive setter ariaModal setter ariaMultiLine setter ariaMultiSelectable setter ariaOrientation + setter ariaOwnsElements setter ariaPlaceholder setter ariaPosInSet setter ariaPressed @@ -2112,6 +2673,7 @@ setter ariaRoleDescription setter ariaRowCount setter ariaRowIndex + setter ariaRowIndexText setter ariaRowSpan setter ariaSelected setter ariaSetSize @@ -2120,6 +2682,7 @@ setter ariaValueMin setter ariaValueNow setter ariaValueText + setter ariaVirtualContent setter role interface EncodedAudioChunk attribute @@toStringTag @@ -2204,11 +2767,16 @@ method constructor method dispatchEvent method removeEventListener + method when interface External attribute @@toStringTag method AddSearchProvider method IsSearchProviderInstalled method constructor +interface FaceDetector + attribute @@toStringTag + method constructor + method detect interface FeaturePolicy attribute @@toStringTag method allowedFeatures @@ -2223,6 +2791,10 @@ getter protocol getter provider method constructor +interface FetchLaterResult + attribute @@toStringTag + getter activated + method constructor interface File : Blob attribute @@toStringTag getter lastModified @@ -2262,6 +2834,14 @@ setter onloadend setter onloadstart setter onprogress +interface FileSystemChangeRecord + attribute @@toStringTag + getter changedHandle + getter relativePathComponents + getter relativePathMovedFrom + getter root + getter type + method constructor interface FileSystemDirectoryHandle : FileSystemHandle attribute @@toStringTag method @@asyncIterator @@ -2284,10 +2864,18 @@ getter kind getter name method constructor + method getUniqueId method isSameEntry + method move method queryPermission method remove method requestPermission +interface FileSystemObserver + attribute @@toStringTag + method constructor + method disconnect + method observe + method unobserve interface FileSystemWritableFileStream : WritableStream attribute @@toStringTag getter mode @@ -2353,7 +2941,9 @@ method constructor interface FragmentDirective attribute @@toStringTag + getter items method constructor + method createSelectorDirective interface GPU attribute @@toStringTag getter wgslLanguageFeatures @@ -2364,6 +2954,7 @@ attribute @@toStringTag getter features getter info + getter isCompatibilityMode getter isFallbackAdapter getter limits method constructor @@ -2402,6 +2993,7 @@ getter canvas method configure method constructor + method getConfiguration method getCurrentTexture method unconfigure interface GPUCommandBuffer @@ -2425,6 +3017,7 @@ method popDebugGroup method pushDebugGroup method resolveQuerySet + method writeTimestamp setter label interface GPUCompilationInfo attribute @@toStringTag @@ -2461,6 +3054,7 @@ setter label interface GPUDevice : EventTarget attribute @@toStringTag + getter adapterInfo getter features getter label getter limits @@ -2570,6 +3164,8 @@ method endOcclusionQuery method executeBundles method insertDebugMarker + method multiDrawIndexedIndirect + method multiDrawIndirect method popDebugGroup method pushDebugGroup method setBindGroup @@ -2632,6 +3228,7 @@ getter maxStorageBufferBindingSize getter maxStorageBuffersPerShaderStage getter maxStorageTexturesPerShaderStage + getter maxSubgroupSize getter maxTextureArrayLayers getter maxTextureDimension1D getter maxTextureDimension2D @@ -2642,6 +3239,7 @@ getter maxVertexBufferArrayStride getter maxVertexBuffers getter minStorageBufferOffsetAlignment + getter minSubgroupSize getter minUniformBufferOffsetAlignment method constructor interface GPUTexture @@ -2684,6 +3282,7 @@ getter index getter mapping getter timestamp + getter touchEvents getter vibrationActuator method constructor interface GamepadButton @@ -2698,10 +3297,18 @@ method constructor interface GamepadHapticActuator attribute @@toStringTag + getter effects getter type method constructor method playEffect method reset +interface GamepadTouch + attribute @@toStringTag + getter position + getter surfaceDimensions + getter surfaceId + getter touchId + method constructor interface Geolocation attribute @@toStringTag method clearWatch @@ -2760,6 +3367,8 @@ getter hostname getter href getter hreflang + getter interestAction + getter interestTargetElement getter name getter origin getter password @@ -2788,6 +3397,8 @@ setter hostname setter href setter hreflang + setter interestAction + setter interestTargetElement setter name setter password setter pathname @@ -2807,12 +3418,15 @@ interface HTMLAreaElement : HTMLElement attribute @@toStringTag getter alt + getter attributionSrc getter coords getter download getter hash getter host getter hostname getter href + getter interestAction + getter interestTargetElement getter noHref getter origin getter password @@ -2830,12 +3444,15 @@ method constructor method toString setter alt + setter attributionSrc setter coords setter download setter hash setter host setter hostname setter href + setter interestAction + setter interestTargetElement setter noHref setter password setter pathname @@ -2881,6 +3498,7 @@ getter onload getter onmessage getter onmessageerror + getter onmove getter onoffline getter ononline getter onorientationchange @@ -2891,6 +3509,7 @@ getter onresize getter onscroll getter onstorage + getter ontimezonechange getter onunhandledrejection getter onunload getter text @@ -2911,6 +3530,7 @@ setter onload setter onmessage setter onmessageerror + setter onmove setter onoffline setter ononline setter onorientationchange @@ -2921,12 +3541,15 @@ setter onresize setter onscroll setter onstorage + setter ontimezonechange setter onunhandledrejection setter onunload setter text setter vLink interface HTMLButtonElement : HTMLElement attribute @@toStringTag + getter command + getter commandForElement getter disabled getter form getter formAction @@ -2934,6 +3557,8 @@ getter formMethod getter formNoValidate getter formTarget + getter interestAction + getter interestTargetElement getter labels getter name getter popoverTargetAction @@ -2947,12 +3572,16 @@ method constructor method reportValidity method setCustomValidity + setter command + setter commandForElement setter disabled setter formAction setter formEnctype setter formMethod setter formNoValidate setter formTarget + setter interestAction + setter interestTargetElement setter name setter popoverTargetAction setter popoverTargetElement @@ -2963,6 +3592,7 @@ getter height getter width method captureStream + method configureHighDynamicRange method constructor method getContext method toBlob @@ -3000,12 +3630,15 @@ setter open interface HTMLDialogElement : HTMLElement attribute @@toStringTag + getter closedBy getter open getter returnValue method close method constructor + method requestClose method show method showModal + setter closedBy setter open setter returnValue interface HTMLDirectoryElement : HTMLElement @@ -3033,6 +3666,7 @@ getter draggable getter editContext getter enterKeyHint + getter focusgroup getter hidden getter inert getter innerText @@ -3101,6 +3735,7 @@ getter onmouseover getter onmouseup getter onmousewheel + getter onoverscroll getter onpaste getter onpause getter onplay @@ -3120,6 +3755,8 @@ getter onresize getter onscroll getter onscrollend + getter onscrollsnapchange + getter onscrollsnapchanging getter onsecuritypolicyviolation getter onseeked getter onseeking @@ -3172,6 +3809,7 @@ setter draggable setter editContext setter enterKeyHint + setter focusgroup setter hidden setter inert setter innerText @@ -3234,6 +3872,7 @@ setter onmouseover setter onmouseup setter onmousewheel + setter onoverscroll setter onpaste setter onpause setter onplay @@ -3253,6 +3892,8 @@ setter onresize setter onscroll setter onscrollend + setter onscrollsnapchange + setter onscrollsnapchanging setter onsecuritypolicyviolation setter onseeked setter onseeking @@ -3403,6 +4044,7 @@ getter onload getter onmessage getter onmessageerror + getter onmove getter onoffline getter ononline getter onorientationchange @@ -3413,6 +4055,7 @@ getter onresize getter onscroll getter onstorage + getter ontimezonechange getter onunhandledrejection getter onunload getter rows @@ -3429,6 +4072,7 @@ setter onload setter onmessage setter onmessageerror + setter onmove setter onoffline setter ononline setter onorientationchange @@ -3439,6 +4083,7 @@ setter onresize setter onscroll setter onstorage + setter ontimezonechange setter onunhandledrejection setter onunload setter rows @@ -3474,6 +4119,7 @@ getter align getter allow getter allowFullscreen + getter browsingTopics getter contentDocument getter contentWindow getter credentialless @@ -3486,6 +4132,7 @@ getter marginHeight getter marginWidth getter name + getter policy getter privateToken getter referrerPolicy getter sandbox @@ -3499,6 +4146,7 @@ setter align setter allow setter allowFullscreen + setter browsingTopics setter credentialless setter csp setter frameBorder @@ -3508,6 +4156,7 @@ setter marginHeight setter marginWidth setter name + setter policy setter privateToken setter referrerPolicy setter sandbox @@ -3589,6 +4238,8 @@ getter height getter incremental getter indeterminate + getter interestAction + getter interestTargetElement getter labels getter list getter max @@ -3648,6 +4299,8 @@ setter height setter incremental setter indeterminate + setter interestAction + setter interestTargetElement setter max setter maxLength setter min @@ -3779,6 +4432,7 @@ attribute NETWORK_IDLE attribute NETWORK_LOADING attribute NETWORK_NO_SOURCE + getter audioTracks getter autoplay getter buffered getter controls @@ -3791,6 +4445,7 @@ getter duration getter ended getter error + getter latencyHint getter loop getter mediaKeys getter muted @@ -3808,6 +4463,7 @@ getter src getter srcObject getter textTracks + getter videoTracks getter volume getter webkitAudioDecodedByteCount getter webkitVideoDecodedByteCount @@ -3826,6 +4482,7 @@ setter currentTime setter defaultMuted setter defaultPlaybackRate + setter latencyHint setter loop setter muted setter onencrypted @@ -4070,6 +4727,7 @@ getter name getter options getter required + getter selectedContentElement getter selectedIndex getter selectedOptions getter size @@ -4094,9 +4752,13 @@ setter multiple setter name setter required + setter selectedContentElement setter selectedIndex setter size setter value +interface HTMLSelectedContentElement : HTMLElement + attribute @@toStringTag + method constructor interface HTMLSlotElement : HTMLElement attribute @@toStringTag getter name @@ -4262,13 +4924,17 @@ interface HTMLTemplateElement : HTMLElement attribute @@toStringTag getter content + getter parseparts getter shadowRootClonable getter shadowRootDelegatesFocus getter shadowRootMode + getter shadowRootSerializable method constructor + setter parseparts setter shadowRootClonable setter shadowRootDelegatesFocus setter shadowRootMode + setter shadowRootSerializable interface HTMLTextAreaElement : HTMLElement attribute @@toStringTag getter autocomplete @@ -4369,19 +5035,13 @@ getter videoHeight getter videoWidth getter webkitDecodedFrameCount - getter webkitDisplayingFullscreen getter webkitDroppedFrameCount - getter webkitSupportsFullscreen getter width method cancelVideoFrameCallback method constructor method getVideoPlaybackQuality method requestPictureInPicture method requestVideoFrameCallback - method webkitEnterFullScreen - method webkitEnterFullscreen - method webkitExitFullScreen - method webkitExitFullscreen setter disablePictureInPicture setter height setter onenterpictureinpicture @@ -4389,6 +5049,12 @@ setter playsInline setter poster setter width +interface HandwritingStroke + attribute @@toStringTag + method addPoint + method clear + method constructor + method getPoints interface HashChangeEvent : Event attribute @@toStringTag getter newURL @@ -4505,6 +5171,7 @@ method get method getAll method getAllKeys + method getAllRecords method getKey method openCursor method openKeyCursor @@ -4538,6 +5205,7 @@ method get method getAll method getAllKeys + method getAllRecords method getKey method index method openCursor @@ -4551,6 +5219,12 @@ method constructor setter onblocked setter onupgradeneeded +interface IDBRecord + attribute @@toStringTag + getter key + getter primaryKey + getter value + method constructor interface IDBRequest : EventTarget attribute @@toStringTag getter error @@ -4681,6 +5355,7 @@ getter colorSpace getter data getter height + getter storageFormat getter width method constructor interface ImageDecoder @@ -4730,6 +5405,11 @@ getter isComposing method constructor method getTargetRanges +interface InterestEvent : Event + attribute @@toStringTag + getter action + getter invoker + method constructor interface IntersectionObserver attribute @@toStringTag getter delay @@ -4802,16 +5482,32 @@ setter composite setter pseudoElement setter target +interface LanguageTranslator + attribute @@toStringTag + method constructor + method destroy + method translate interface LargestContentfulPaint : PerformanceEntry attribute @@toStringTag getter element getter id getter loadTime + getter paintTime + getter presentationTime getter renderTime getter size getter url method constructor method toJSON +interface LaunchParams + attribute @@toStringTag + getter files + getter targetURL + method constructor +interface LaunchQueue + attribute @@toStringTag + method constructor + method setConsumer interface LayoutShift : PerformanceEntry attribute @@toStringTag getter hadRecentInput @@ -4904,11 +5600,18 @@ method constructor method open setter onstatechange +interface Magnetometer : Sensor + attribute @@toStringTag + getter x + getter y + getter z + method constructor interface MathMLElement : Element attribute @@toStringTag getter attributeStyleMap getter autofocus getter dataset + getter focusgroup getter nonce getter onabort getter onanimationend @@ -4966,6 +5669,7 @@ getter onmouseover getter onmouseup getter onmousewheel + getter onoverscroll getter onpaste getter onpause getter onplay @@ -4985,6 +5689,8 @@ getter onresize getter onscroll getter onscrollend + getter onscrollsnapchange + getter onscrollsnapchanging getter onsecuritypolicyviolation getter onseeked getter onseeking @@ -5018,6 +5724,7 @@ method constructor method focus setter autofocus + setter focusgroup setter nonce setter onabort setter onanimationend @@ -5075,6 +5782,7 @@ setter onmouseover setter onmouseup setter onmousewheel + setter onoverscroll setter onpaste setter onpause setter onplay @@ -5094,6 +5802,8 @@ setter onresize setter onscroll setter onscrollend + setter onscrollsnapchange + setter onscrollsnapchanging setter onsecuritypolicyviolation setter onseeked setter onseeking @@ -5138,10 +5848,14 @@ method toJSON interface MediaDevices : EventTarget attribute @@toStringTag + getter ondevicechange method constructor method enumerateDevices + method getDisplayMedia method getSupportedConstraints method getUserMedia + method setPreferredSinkId + setter ondevicechange interface MediaElementAudioSourceNode : AudioNode attribute @@toStringTag getter mediaElement @@ -5320,6 +6034,7 @@ getter kind getter label getter muted + getter onconfigurationchange getter onended getter onmute getter onunmute @@ -5334,9 +6049,23 @@ method stop setter contentHint setter enabled + setter onconfigurationchange setter onended setter onmute setter onunmute +interface MediaStreamTrackAudioStats + attribute @@toStringTag + getter averageLatency + getter deliveredFrames + getter deliveredFramesDuration + getter latency + getter maximumLatency + getter minimumLatency + getter totalFrames + getter totalFramesDuration + method constructor + method resetLatency + method toJSON interface MediaStreamTrackEvent : Event attribute @@toStringTag getter track @@ -5356,6 +6085,15 @@ getter totalFrames method constructor method toJSON +interface Mesh2DIndexBuffer + attribute @@toStringTag + method constructor +interface Mesh2DUVBuffer + attribute @@toStringTag + method constructor +interface Mesh2DVertexBuffer + attribute @@toStringTag + method constructor interface MessageChannel attribute @@toStringTag getter port1 @@ -5373,12 +6111,14 @@ method initMessageEvent interface MessagePort : EventTarget attribute @@toStringTag + getter onclose getter onmessage getter onmessageerror method close method constructor method postMessage method start + setter onclose setter onmessage setter onmessageerror interface MimeType @@ -5395,6 +6135,59 @@ method constructor method item method namedItem +interface Mojo + static method bindInterface + static method createDataPipe + static method createMessagePipe + static method createSharedBuffer + attribute @@toStringTag + attribute RESULT_ABORTED + attribute RESULT_ALREADY_EXISTS + attribute RESULT_BUSY + attribute RESULT_CANCELLED + attribute RESULT_DATA_LOSS + attribute RESULT_DEADLINE_EXCEEDED + attribute RESULT_FAILED_PRECONDITION + attribute RESULT_INTERNAL + attribute RESULT_INVALID_ARGUMENT + attribute RESULT_NOT_FOUND + attribute RESULT_OK + attribute RESULT_OUT_OF_RANGE + attribute RESULT_PERMISSION_DENIED + attribute RESULT_RESOURCE_EXHAUSTED + attribute RESULT_SHOULD_WAIT + attribute RESULT_UNAVAILABLE + attribute RESULT_UNIMPLEMENTED + attribute RESULT_UNKNOWN + method constructor +interface MojoHandle + attribute @@toStringTag + method close + method constructor + method discardData + method duplicateBufferHandle + method mapBuffer + method queryData + method readData + method readMessage + method watch + method writeData + method writeMessage +interface MojoInterfaceInterceptor : EventTarget + attribute @@toStringTag + getter oninterfacerequest + method constructor + method start + method stop + setter oninterfacerequest +interface MojoInterfaceRequestEvent : Event + attribute @@toStringTag + getter handle + method constructor +interface MojoWatcher + attribute @@toStringTag + method cancel + method constructor interface MouseEvent : UIEvent attribute @@toStringTag getter altKey @@ -5423,18 +6216,6 @@ method constructor method getModifierState method initMouseEvent -interface MutationEvent : Event - attribute @@toStringTag - attribute ADDITION - attribute MODIFICATION - attribute REMOVAL - getter attrChange - getter attrName - getter newValue - getter prevValue - getter relatedNode - method constructor - method initMutationEvent interface MutationObserver attribute @@toStringTag method constructor @@ -5506,7 +6287,9 @@ getter info getter navigationType getter signal + getter sourceElement getter userInitiated + method commit method constructor method intercept method scroll @@ -5592,10 +6375,12 @@ getter geolocation getter gpu getter hardwareConcurrency + getter identity getter ink getter keyboard getter language getter languages + getter lockedMode getter locks getter managed getter maxTouchPoints @@ -5604,8 +6389,10 @@ getter mimeTypes getter onLine getter pdfViewerEnabled + getter permissions getter platform getter plugins + getter preferences getter product getter productSub getter scheduling @@ -5622,23 +6409,33 @@ getter webdriver getter webkitPersistentStorage getter webkitTemporaryStorage + method canShare method clearAppBadge method constructor + method createHandwritingRecognizer method getBattery method getGamepads method getUserMedia + method install method javaEnabled + method queryHandwritingRecognizer method requestMIDIAccess method requestMediaKeySystemAccess method sendBeacon method setAppBadge + method share method vibrate method webkitGetUserMedia interface NavigatorManagedData : EventTarget attribute @@toStringTag getter onmanagedconfigurationchange method constructor + method getAnnotatedAssetId + method getAnnotatedLocation + method getDirectoryId + method getHostname method getManagedConfiguration + method getSerialNumber setter onmanagedconfigurationchange interface NavigatorUAData attribute @@toStringTag @@ -5734,6 +6531,10 @@ method item method keys method values +interface NodePart : Part + attribute @@toStringTag + getter node + method constructor interface NotRestoredReasonDetails attribute @@toStringTag getter reason @@ -5749,6 +6550,28 @@ getter url method constructor method toJSON +interface Observable + static method from + attribute @@toStringTag + method catch + method constructor + method drop + method every + method filter + method find + method first + method flatMap + method forEach + method inspect + method last + method map + method reduce + method some + method subscribe + method switchMap + method take + method takeUntil + method toArray interface OfflineAudioCompletionEvent : Event attribute @@toStringTag getter renderedBuffer @@ -5807,6 +6630,7 @@ getter wordSpacing method arc method arcTo + method beginLayer method beginPath method bezierCurveTo method clearRect @@ -5816,15 +6640,22 @@ method createConicGradient method createImageData method createLinearGradient + method createMesh2DIndexBuffer + method createMesh2DUVBuffer + method createMesh2DVertexBuffer method createPattern method createRadialGradient method drawImage + method drawMesh method ellipse + method endLayer method fill method fillRect method fillText + method fillTextCluster method getImageData method getLineDash + method getTextureFormat method getTransform method isContextLost method isPointInPath @@ -5847,6 +6678,8 @@ method stroke method strokeRect method strokeText + method transferBackFromGPUTexture + method transferToGPUTexture method transform method translate setter direction @@ -5909,12 +6742,19 @@ attribute @@toStringTag getter constraint method constructor +interface OverscrollEvent : Event + attribute @@toStringTag + getter deltaX + getter deltaY + method constructor interface PageRevealEvent : Event attribute @@toStringTag + getter viewTransition method constructor interface PageSwapEvent : Event attribute @@toStringTag getter activation + getter viewTransition method constructor interface PageTransitionEvent : Event attribute @@toStringTag @@ -5947,6 +6787,12 @@ setter panningModel setter refDistance setter rolloffFactor +interface Part + attribute @@toStringTag + getter metadata + getter root + method constructor + method disconnect interface PasswordCredential : Credential attribute @@toStringTag getter iconURL @@ -5970,11 +6816,13 @@ interface Performance : EventTarget attribute @@toStringTag getter eventCounts + getter interactionCount getter memory getter navigation getter onresourcetimingbufferfull getter timeOrigin getter timing + method bind method clearMarks method clearMeasures method clearResourceTimings @@ -5997,6 +6845,8 @@ getter loadTime getter naturalHeight getter naturalWidth + getter paintTime + getter presentationTime getter renderTime getter url method constructor @@ -6006,6 +6856,7 @@ getter duration getter entryType getter name + getter navigationId getter startTime method constructor method toJSON @@ -6022,6 +6873,8 @@ attribute @@toStringTag getter blockingDuration getter firstUIEventTimestamp + getter paintTime + getter presentationTime getter renderStart getter scripts getter styleAndLayoutStart @@ -6053,6 +6906,7 @@ interface PerformanceNavigationTiming : PerformanceResourceTiming attribute @@toStringTag getter activationStart + getter confidence getter criticalCHRestart getter domComplete getter domContentLoadedEventEnd @@ -6062,6 +6916,7 @@ getter loadEventStart getter notRestoredReasons getter redirectCount + getter systemEntropy getter type getter unloadEventEnd getter unloadEventStart @@ -6082,17 +6937,22 @@ method getEntriesByType interface PerformancePaintTiming : PerformanceEntry attribute @@toStringTag + getter paintTime + getter presentationTime method constructor + method toJSON interface PerformanceResourceTiming : PerformanceEntry attribute @@toStringTag getter connectEnd getter connectStart + getter contentType getter decodedBodySize getter deliveryType getter domainLookupEnd getter domainLookupStart getter encodedBodySize getter fetchStart + getter finalResponseHeadersStart getter firstInterimResponseStart getter initiatorType getter nextHopProtocol @@ -6155,9 +7015,29 @@ getter unloadEventStart method constructor method toJSON +interface PerformanceTimingConfidence + attribute @@toStringTag + getter randomizedTriggerRate + getter value + method constructor + method toJSON interface PeriodicWave attribute @@toStringTag method constructor +interface PermissionStatus : EventTarget + attribute @@toStringTag + getter name + getter onchange + getter state + method constructor + setter onchange +interface Permissions + attribute @@toStringTag + method constructor + method query + method request + method requestAll + method revoke interface PictureInPictureEvent : Event attribute @@toStringTag getter pictureInPictureWindow @@ -6193,6 +7073,7 @@ getter azimuthAngle getter height getter isPrimary + getter persistentDeviceId getter pointerId getter pointerType getter pressure @@ -6209,21 +7090,29 @@ getter hasUAVisualTransition getter state method constructor -interface PressureObserver - static getter supportedSources +interface PreferenceManager + attribute @@toStringTag + getter colorScheme + getter contrast + getter reducedData + getter reducedMotion + getter reducedTransparency + method constructor +interface PreferenceObject : EventTarget + attribute @@toStringTag + getter onchange + getter override + getter validValues + getter value + method clearOverride + method constructor + method requestOverride + setter onchange +interface PrivateAttribution attribute @@toStringTag method constructor - method disconnect - method observe - method takeRecords - method unobserve -interface PressureRecord - attribute @@toStringTag - getter source - getter state - getter time - method constructor - method toJSON + method getEncryptedMatchKey + method getHelperNetworks interface ProcessingInstruction : CharacterData attribute @@toStringTag getter sheet @@ -6246,6 +7135,10 @@ getter promise getter reason method constructor +interface ProtectedAudience + attribute @@toStringTag + method constructor + method queryFeatureSupport interface RTCCertificate attribute @@toStringTag getter expires @@ -6280,6 +7173,7 @@ getter onmessage getter onopen getter ordered + getter priority getter protocol getter readyState getter reliable @@ -6314,6 +7208,7 @@ getter timestamp method constructor method getMetadata + method setMetadata method toString setter data interface RTCEncodedVideoFrame @@ -6323,6 +7218,7 @@ getter type method constructor method getMetadata + method setMetadata method toString setter data interface RTCError : DOMException @@ -6399,6 +7295,7 @@ getter pendingLocalDescription getter pendingRemoteDescription getter remoteDescription + getter rtpTransport getter sctp getter signalingState method addIceCandidate @@ -6448,6 +7345,13 @@ attribute @@toStringTag getter candidate method constructor +interface RTCRtpAcks + attribute @@toStringTag + getter explicitCongestionNotification + getter receivedTime + getter remoteSendTimestamp + method acks + method constructor interface RTCRtpReceiver static method getCapabilities attribute @@toStringTag @@ -6455,6 +7359,7 @@ getter playoutDelayHint getter rtcpTransport getter track + getter transform getter transport method constructor method createEncodedStreams @@ -6464,20 +7369,42 @@ method getSynchronizationSources setter jitterBufferTarget setter playoutDelayHint + setter transform +interface RTCRtpScriptTransform + attribute @@toStringTag + method constructor +interface RTCRtpSendResult + attribute @@toStringTag + getter sent + getter unsent + method constructor +interface RTCRtpSendStream + attribute @@toStringTag + method constructor + method sendRtp interface RTCRtpSender static method getCapabilities attribute @@toStringTag getter dtmf getter rtcpTransport getter track + getter transform getter transport method constructor method createEncodedStreams method getParameters method getStats + method replaceSendStreams method replaceTrack method setParameters method setStreams + setter transform +interface RTCRtpSent + attribute @@toStringTag + getter ackId + getter size + getter time + method constructor interface RTCRtpTransceiver attribute @@toStringTag getter currentDirection @@ -6493,6 +7420,10 @@ method setHeaderExtensionsToNegotiate method stop setter direction +interface RTCRtpTransport + attribute @@toStringTag + method constructor + method createProcessor interface RTCSctpTransport : EventTarget attribute @@toStringTag getter maxChannels @@ -6616,6 +7547,10 @@ interface RelativeOrientationSensor : OrientationSensor attribute @@toStringTag method constructor +interface ReportBody + attribute @@toStringTag + method constructor + method toJSON interface ReportingObserver attribute @@toStringTag method constructor @@ -6629,6 +7564,7 @@ getter cache getter credentials getter destination + getter duplex getter headers getter integrity getter isHistoryNavigation @@ -6692,8 +7628,12 @@ interface SVGAElement : SVGGraphicsElement attribute @@toStringTag getter href + getter interestAction + getter interestTargetElement getter target method constructor + setter interestAction + setter interestTargetElement interface SVGAngle attribute @@toStringTag attribute SVG_ANGLETYPE_DEG @@ -6843,6 +7783,7 @@ getter autofocus getter className getter dataset + getter focusgroup getter nonce getter onabort getter onanimationend @@ -6900,6 +7841,7 @@ getter onmouseover getter onmouseup getter onmousewheel + getter onoverscroll getter onpaste getter onpause getter onplay @@ -6919,6 +7861,8 @@ getter onresize getter onscroll getter onscrollend + getter onscrollsnapchange + getter onscrollsnapchanging getter onsecuritypolicyviolation getter onseeked getter onseeking @@ -6954,6 +7898,7 @@ method constructor method focus setter autofocus + setter focusgroup setter nonce setter onabort setter onanimationend @@ -7011,6 +7956,7 @@ setter onmouseover setter onmouseup setter onmousewheel + setter onoverscroll setter onpaste setter onpause setter onplay @@ -7030,6 +7976,8 @@ setter onresize setter onscroll setter onscrollend + setter onscrollsnapchange + setter onscrollsnapchanging setter onsecuritypolicyviolation setter onseeked setter onseeking @@ -7841,10 +8789,23 @@ getter zoomAndPan method constructor setter zoomAndPan +interface Sanitizer + attribute @@toStringTag + method allowAttribute + method allowElement + method constructor + method get + method removeAttribute + method removeElement + method removeUnsafe + method replaceWithChildrenElement + method setComments + method setDataAttributes interface Scheduler attribute @@toStringTag method constructor method postTask + method yield interface Scheduling attribute @@toStringTag method constructor @@ -7864,14 +8825,27 @@ getter width method constructor setter onchange +interface ScreenCaptureMediaStreamTrack : MediaStreamTrack + attribute @@toStringTag + method constructor + method screenDetailed interface ScreenDetailed : Screen attribute @@toStringTag + getter bluePrimaryX + getter bluePrimaryY getter devicePixelRatio + getter greenPrimaryX + getter greenPrimaryY + getter highDynamicRangeHeadroom getter isInternal getter isPrimary getter label getter left + getter redPrimaryX + getter redPrimaryY getter top + getter whitePointX + getter whitePointY method constructor interface ScreenDetails : EventTarget attribute @@toStringTag @@ -7923,6 +8897,7 @@ getter anchorOffset getter baseNode getter baseOffset + getter direction getter extentNode getter extentOffset getter focusNode @@ -7939,6 +8914,7 @@ method deleteFromDocument method empty method extend + method getComposedRanges method getRangeAt method modify method removeAllRanges @@ -7947,6 +8923,10 @@ method setBaseAndExtent method setPosition method toString +interface SelectorDirective : Directive + attribute @@toStringTag + method constructor + method getMatchingRange interface Sensor : EventTarget attribute @@toStringTag getter activated @@ -8019,23 +8999,39 @@ getter onslotchange getter pictureInPictureElement getter pointerLockElement + getter referenceTarget + getter registry + getter serializable getter slotAssignment getter styleSheets method constructor + method createElement + method createElementNS method elementFromPoint method elementsFromPoint method getAnimations - method getInnerHTML + method getHTML method getSelection + method setHTML method setHTMLUnsafe setter adoptedStyleSheets setter fullscreenElement setter innerHTML setter onslotchange + setter referenceTarget +interface SnapEvent : Event + attribute @@toStringTag + getter snapTargetBlock + getter snapTargetInline + method constructor +interface SoftNavigationEntry : PerformanceEntry + attribute @@toStringTag + method constructor interface SourceBuffer : EventTarget attribute @@toStringTag getter appendWindowEnd getter appendWindowStart + getter audioTracks getter buffered getter mode getter onabort @@ -8044,9 +9040,12 @@ getter onupdateend getter onupdatestart getter timestampOffset + getter trackDefaults getter updating + getter videoTracks method abort method appendBuffer + method appendEncodedChunks method changeType method constructor method remove @@ -8059,6 +9058,7 @@ setter onupdateend setter onupdatestart setter timestampOffset + setter trackDefaults interface SourceBufferList : EventTarget attribute @@toStringTag getter length @@ -8088,8 +9088,10 @@ attribute @@toStringTag getter caches getter indexedDB + getter locks getter name method constructor + method durability method estimate method expires method getDirectory @@ -8111,7 +9113,7 @@ getter url method constructor method initStorageEvent -interface StorageManager : EventTarget +interface StorageManager attribute @@toStringTag method constructor method estimate @@ -8159,6 +9161,15 @@ attribute @@toStringTag getter submitter method constructor +interface Subscriber + attribute @@toStringTag + getter active + getter signal + method addTeardown + method complete + method constructor + method error + method next interface SubtleCrypto attribute @@toStringTag method constructor @@ -8207,6 +9218,15 @@ getter wholeText method constructor method splitText +interface TextCluster + attribute @@toStringTag + getter align + getter baseline + getter begin + getter end + getter x + getter y + method constructor interface TextDecoder attribute @@toStringTag getter encoding @@ -8222,6 +9242,17 @@ getter readable getter writable method constructor +interface TextDetector + attribute @@toStringTag + method constructor + method detect +interface TextDirective : SelectorDirective + attribute @@toStringTag + getter prefix + getter suffix + getter textEnd + getter textStart + method constructor interface TextEncoder attribute @@toStringTag getter encoding @@ -8257,12 +9288,18 @@ getter actualBoundingBoxLeft getter actualBoundingBoxRight getter alphabeticBaseline + getter emHeightAscent + getter emHeightDescent getter fontBoundingBoxAscent getter fontBoundingBoxDescent getter hangingBaseline getter ideographicBaseline getter width method constructor + method getActualBoundingBox + method getIndexFromOffset + method getSelectionRects + method getTextClusters interface TextTrack : EventTarget attribute @@toStringTag getter activeCues @@ -8326,6 +9363,10 @@ method constructor method end method start +interface TimestampTrigger + attribute @@toStringTag + getter timestamp + method constructor interface ToggleEvent : Event attribute @@toStringTag getter newState @@ -8362,6 +9403,19 @@ method @@iterator method constructor method item +interface TrackDefault + attribute @@toStringTag + getter byteStreamTrackID + getter kinds + getter label + getter language + getter type + method constructor +interface TrackDefaultList + attribute @@toStringTag + getter length + method @@iterator + method constructor interface TrackEvent : Event attribute @@toStringTag getter track @@ -8384,6 +9438,11 @@ getter propertyName getter pseudoElement method constructor +interface Translation + attribute @@toStringTag + method canTranslate + method constructor + method createTranslator interface TreeWalker attribute @@toStringTag getter currentNode @@ -8400,16 +9459,19 @@ method previousSibling setter currentNode interface TrustedHTML + static method fromLiteral attribute @@toStringTag method constructor method toJSON method toString interface TrustedScript + static method fromLiteral attribute @@toStringTag method constructor method toJSON method toString interface TrustedScriptURL + static method fromLiteral attribute @@toStringTag method constructor method toJSON @@ -8426,6 +9488,7 @@ getter defaultPolicy getter emptyHTML getter emptyScript + getter onbeforecreatepolicy method constructor method createPolicy method getAttributeType @@ -8434,6 +9497,7 @@ method isHTML method isScript method isScriptURL + setter onbeforecreatepolicy interface UIEvent : Event attribute @@toStringTag getter detail @@ -8445,6 +9509,7 @@ interface URL static method canParse static method createObjectURL + static method parse static method revokeObjectURL attribute @@toStringTag getter hash @@ -8473,6 +9538,7 @@ setter search setter username interface URLPattern + static method compareComponent attribute @@toStringTag getter hasRegExpGroups getter hash @@ -8513,6 +9579,7 @@ getter align getter line getter position + getter region getter size getter snapToLines getter text @@ -8522,10 +9589,30 @@ setter align setter line setter position + setter region setter size setter snapToLines setter text setter vertical +interface VTTRegion + attribute @@toStringTag + getter id + getter lines + getter regionAnchorX + getter regionAnchorY + getter scroll + getter viewportAnchorX + getter viewportAnchorY + getter width + method constructor + setter id + setter lines + setter regionAnchorX + setter regionAnchorY + setter scroll + setter viewportAnchorX + setter viewportAnchorY + setter width interface ValidityState attribute @@toStringTag getter badInput @@ -8572,8 +9659,13 @@ method constructor method encode method flush + method getAllFrameBuffers method reset setter ondequeue +interface VideoEncoderBuffer + attribute @@toStringTag + getter id + method constructor interface VideoFrame attribute @@toStringTag getter codedHeight @@ -8583,7 +9675,9 @@ getter displayHeight getter displayWidth getter duration + getter flip getter format + getter rotation getter timestamp getter visibleRect method allocationSize @@ -8591,6 +9685,7 @@ method close method constructor method copyTo + method metadata interface VideoPlaybackQuality attribute @@toStringTag getter corruptedVideoFrames @@ -8598,6 +9693,36 @@ getter droppedVideoFrames getter totalVideoFrames method constructor +interface VideoTrack + attribute @@toStringTag + getter id + getter kind + getter label + getter language + getter selected + getter sourceBuffer + method constructor + setter selected +interface VideoTrackGenerator + attribute @@toStringTag + getter muted + getter track + getter writable + method constructor + setter muted +interface VideoTrackList : EventTarget + attribute @@toStringTag + getter length + getter onaddtrack + getter onchange + getter onremovetrack + getter selectedIndex + method @@iterator + method constructor + method getTrackById + setter onaddtrack + setter onchange + setter onremovetrack interface ViewTimeline : ScrollTimeline attribute @@toStringTag getter endOffset @@ -8648,6 +9773,7 @@ getter offsetTop getter onresize getter onscroll + getter onscrollend getter pageLeft getter pageTop getter scale @@ -8655,6 +9781,7 @@ method constructor setter onresize setter onscroll + setter onscrollend interface WGSLLanguageFeatures attribute @@toStringTag getter size @@ -9284,6 +10411,7 @@ method clearStencil method clientWaitSync method colorMask + method commit method compileShader method compressedTexImage2D method compressedTexImage3D @@ -9485,23 +10613,26 @@ getter size getter type method constructor -interface WebGLBuffer +interface WebGLBuffer : WebGLObject attribute @@toStringTag method constructor interface WebGLContextEvent : Event attribute @@toStringTag getter statusMessage method constructor -interface WebGLFramebuffer +interface WebGLFramebuffer : WebGLObject attribute @@toStringTag method constructor -interface WebGLProgram +interface WebGLObject attribute @@toStringTag method constructor -interface WebGLQuery +interface WebGLProgram : WebGLObject attribute @@toStringTag method constructor -interface WebGLRenderbuffer +interface WebGLQuery : WebGLObject + attribute @@toStringTag + method constructor +interface WebGLRenderbuffer : WebGLObject attribute @@toStringTag method constructor interface WebGLRenderingContext @@ -9830,6 +10961,7 @@ method clearDepth method clearStencil method colorMask + method commit method compileShader method compressedTexImage2D method compressedTexSubImage2D @@ -9950,10 +11082,10 @@ method viewport setter drawingBufferColorSpace setter unpackColorSpace -interface WebGLSampler +interface WebGLSampler : WebGLObject attribute @@toStringTag method constructor -interface WebGLShader +interface WebGLShader : WebGLObject attribute @@toStringTag method constructor interface WebGLShaderPrecisionFormat @@ -9962,19 +11094,19 @@ getter rangeMax getter rangeMin method constructor -interface WebGLSync +interface WebGLSync : WebGLObject attribute @@toStringTag method constructor -interface WebGLTexture +interface WebGLTexture : WebGLObject attribute @@toStringTag method constructor -interface WebGLTransformFeedback +interface WebGLTransformFeedback : WebGLObject attribute @@toStringTag method constructor interface WebGLUniformLocation attribute @@toStringTag method constructor -interface WebGLVertexArrayObject +interface WebGLVertexArrayObject : WebGLObject attribute @@toStringTag method constructor interface WebKitCSSMatrix : DOMMatrixReadOnly @@ -10089,6 +11221,7 @@ method constructor method createBidirectionalStream method createUnidirectionalStream + method getStats interface WebTransportBidirectionalStream attribute @@toStringTag getter readable @@ -10258,6 +11391,21 @@ method constructor method iterateNext method snapshotItem +interface XRCompositionLayer : XRLayer + attribute @@toStringTag + getter blendTextureSourceAlpha + getter chromaticAberrationCorrection + getter forceMonoPresentation + getter layout + getter mipLevels + getter needsRedraw + getter opacity + method constructor + method destroy + setter blendTextureSourceAlpha + setter chromaticAberrationCorrection + setter forceMonoPresentation + setter opacity interface XRDOMOverlayState attribute @@toStringTag getter type @@ -10265,6 +11413,17 @@ interface XRLayer : EventTarget attribute @@toStringTag method constructor +interface XRProjectionLayer : XRCompositionLayer + attribute @@toStringTag + getter deltaPose + getter fixedFoveation + getter ignoreDepthValues + getter textureArrayLength + getter textureHeight + getter textureWidth + method constructor + setter deltaPose + setter fixedFoveation interface XRWebGLBinding attribute @@toStringTag method constructor @@ -10323,6 +11482,7 @@ getter pendingLocalDescription getter pendingRemoteDescription getter remoteDescription + getter rtpTransport getter sctp getter signalingState method addIceCandidate @@ -10420,6 +11580,7 @@ interface webkitURL static method canParse static method createObjectURL + static method parse static method revokeObjectURL attribute @@toStringTag getter hash @@ -10451,6 +11612,7 @@ namespace CSS attribute @@toStringTag getter highlights + getter layoutWorklet getter paintWorklet method Hz method Q @@ -10584,15 +11746,16 @@ setter memory [GLOBAL OBJECT] attribute android - attribute android_webview_media_token_provider_listener attribute awConsole attribute globalThis attribute propertyNamesInGlobal + getter ai getter caches getter clientInformation getter closed getter cookieStore getter credentialless + getter crossOriginEmbedderPolicy getter crossOriginIsolated getter crypto getter customElements @@ -10607,6 +11770,7 @@ getter innerHeight getter innerWidth getter isSecureContext + getter launchQueue getter length getter localStorage getter location @@ -10682,9 +11846,11 @@ getter onmouseover getter onmouseup getter onmousewheel + getter onmove getter onoffline getter ononline getter onorientationchange + getter onoverscroll getter onpagehide getter onpagereveal getter onpageshow @@ -10709,6 +11875,8 @@ getter onresize getter onscroll getter onscrollend + getter onscrollsnapchange + getter onscrollsnapchanging getter onsearch getter onsecuritypolicyviolation getter onseeked @@ -10722,6 +11890,7 @@ getter onsubmit getter onsuspend getter ontimeupdate + getter ontimezonechange getter ontoggle getter ontouchcancel getter ontouchend @@ -10751,6 +11920,7 @@ getter parent getter performance getter personalbar + getter privateAttribution getter scheduler getter screen getter screenLeft @@ -10767,6 +11937,7 @@ getter styleMedia getter toolbar getter top + getter translation getter trustedTypes getter visualViewport getter window @@ -10784,15 +11955,21 @@ method confirm method createImageBitmap method fetch + method fetchLater method find method focus method getComputedStyle method getScreenDetails method getSelection method matchMedia + method maximize + method minimize method moveBy method moveTo method open + method openDatabase + method popinContextType + method popinContextTypesSupported method postMessage method print method prompt @@ -10803,15 +11980,21 @@ method requestIdleCallback method resizeBy method resizeTo + method restore method scroll method scrollBy method scrollTo method setInterval + method setResizable method setTimeout + method showDirectoryPicker + method showOpenFilePicker + method showSaveFilePicker method stop method structuredClone method webkitCancelAnimationFrame method webkitRequestAnimationFrame + setter ai setter clientInformation setter devicePixelRatio setter event @@ -10892,9 +12075,11 @@ setter onmouseover setter onmouseup setter onmousewheel + setter onmove setter onoffline setter ononline setter onorientationchange + setter onoverscroll setter onpagehide setter onpagereveal setter onpageshow @@ -10919,6 +12104,8 @@ setter onresize setter onscroll setter onscrollend + setter onscrollsnapchange + setter onscrollsnapchanging setter onsearch setter onsecuritypolicyviolation setter onseeked @@ -10932,6 +12119,7 @@ setter onsubmit setter onsuspend setter ontimeupdate + setter ontimezonechange setter ontoggle setter ontouchcancel setter ontouchend @@ -10959,6 +12147,7 @@ setter parent setter performance setter personalbar + setter privateAttribution setter scheduler setter screen setter screenLeft @@ -10972,5 +12161,6 @@ setter status setter statusbar setter toolbar + setter translation setter visualViewport TEST FINISHED
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc index c877bbb..14660cc3 100644 --- a/ash/capture_mode/capture_mode_controller.cc +++ b/ash/capture_mode/capture_mode_controller.cc
@@ -356,6 +356,14 @@ kCaptureModeIcon); } +// Shows a toast informing the user that text has been copied to clipboard. +void ShowTextCopiedToast() { + // TODO(crbug.com/375967525): Finalize and translate the toast string. + ToastManager::Get()->Show(ToastData(kCaptureModeTextCopiedToastId, + ToastCatalogName::kCaptureModeTextCopied, + u"Text copied to clipboard")); +} + // Copies the bitmap representation of the given |image| to the clipboard. void CopyImageToClipboard(const gfx::Image& image) { ui::ScopedClipboardWriter(ui::ClipboardBuffer::kCopyPaste) @@ -672,14 +680,6 @@ /*default_value=*/false); } -// static -void CaptureModeController::ShowTextCopiedToast() { - // TODO(crbug.com/375967525): Finalize and translate the toast string. - ToastManager::Get()->Show(ToastData(kCaptureModeTextCopiedToastId, - ToastCatalogName::kCaptureModeTextCopied, - u"Text copied to clipboard")); -} - SearchResultsPanel* CaptureModeController::GetSearchResultsPanel() const { return search_results_panel_widget_ ? views::AsViewClass<SearchResultsPanel>(
diff --git a/ash/capture_mode/capture_mode_controller.h b/ash/capture_mode/capture_mode_controller.h index c3d8e7a..47323d5 100644 --- a/ash/capture_mode/capture_mode_controller.h +++ b/ash/capture_mode/capture_mode_controller.h
@@ -100,9 +100,6 @@ static void RegisterProfilePrefs(PrefRegistrySimple* registry); - // Shows a toast informing the user that text has been copied to clipboard. - static void ShowTextCopiedToast(); - CaptureModeCameraController* camera_controller() { return camera_controller_.get(); }
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 7d79e629..91538d36 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -1067,7 +1067,7 @@ BASE_FEATURE(kFocusMode, "FocusMode", base::FEATURE_ENABLED_BY_DEFAULT); // Enables or disables Focus Mode YTM integration on ChromeOS. -BASE_FEATURE(kFocusModeYTM, "FocusModeYTM", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kFocusModeYTM, "FocusModeYTM", base::FEATURE_ENABLED_BY_DEFAULT); // If enabled, makes the Projector app use server side speech // recognition instead of on-device speech recognition. @@ -2462,6 +2462,12 @@ // controls whether the projector app uses updated styles and ui components. BASE_FEATURE(kProjectorGm3, "ProjectorGm3", base::FEATURE_ENABLED_BY_DEFAULT); +// Controls whether the projector app uses the latest endpoint for retrieving +// playback urls. +BASE_FEATURE(kProjectorUseDVSPlaybackEndpoint, + "ProjectorUseDVSPlaybackEndpoint", + base::FEATURE_DISABLED_BY_DEFAULT); + // Controls whether to show promise icons during app installations. BASE_FEATURE(kPromiseIcons, "PromiseIcons", base::FEATURE_ENABLED_BY_DEFAULT); @@ -4365,6 +4371,10 @@ return base::FeatureList::IsEnabled(kProjectorGm3); } +bool IsProjectorUseDVSPlaybackEndpointEnabled() { + return base::FeatureList::IsEnabled(kProjectorUseDVSPlaybackEndpoint); +} + bool IsQuickDimEnabled() { return base::FeatureList::IsEnabled(kQuickDim) && switches::HasHps(); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index bc292bad..465568c 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -794,6 +794,8 @@ BASE_DECLARE_FEATURE(kProjectorUseUSMForS3); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kProjectorDynamicColors); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kProjectorGm3); +COMPONENT_EXPORT(ASH_CONSTANTS) +BASE_DECLARE_FEATURE(kProjectorUseDVSPlaybackEndpoint); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPromiseIcons); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPromiseIconsWebApps); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kQuickDim); @@ -1316,6 +1318,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsProjectorUseUSMForS3Enabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsProjectorDynamicColorsEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsProjectorGm3Enabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsProjectorUseDVSPlaybackEndpointEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsQuickDimEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsRenderArcNotificationsByChromeEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS)
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc index b08de80..59fbb8f3 100644 --- a/ash/constants/ash_switches.cc +++ b/ash/constants/ash_switches.cc
@@ -777,9 +777,6 @@ const char kKioskSplashScreenMinTimeSeconds[] = "kiosk-splash-screen-min-time-seconds"; -// When this flag is set, the lacros-availability policy is ignored. -const char kLacrosAvailabilityIgnore[] = "lacros-availability-ignore"; - // If this switch is set, then ash-chrome will exec the lacros-chrome binary // from the indicated path rather than from component updater. Note that the // path should be to a directory that contains a binary named 'chrome'.
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h index 63e51d1..788d56d 100644 --- a/ash/constants/ash_switches.h +++ b/ash/constants/ash_switches.h
@@ -251,7 +251,6 @@ extern const char kInstallLogFastUploadForTests[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kKioskSplashScreenMinTimeSeconds[]; -COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kLacrosAvailabilityIgnore[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kLacrosChromePath[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kLacrosSelectionPolicyIgnore[];
diff --git a/ash/constants/notifier_catalogs.h b/ash/constants/notifier_catalogs.h index 329b653..3763151 100644 --- a/ash/constants/notifier_catalogs.h +++ b/ash/constants/notifier_catalogs.h
@@ -328,7 +328,9 @@ kCopyImageToClipboardAction = 56, kCaptureModeTextCopied = 57, kCoralSavedGroupLimitMax = 58, - kMaxValue = kCoralSavedGroupLimitMax + kScannerActionSuccess = 59, + kScannerActionFailure = 60, + kMaxValue = kScannerActionFailure }; } // namespace ash
diff --git a/ash/frame_sink/frame_sink_holder.cc b/ash/frame_sink/frame_sink_holder.cc index ee905a1..577cfb5 100644 --- a/ash/frame_sink/frame_sink_holder.cc +++ b/ash/frame_sink/frame_sink_holder.cc
@@ -29,12 +29,14 @@ FrameSinkHolder::FrameSinkHolder( std::unique_ptr<cc::LayerTreeFrameSink> frame_sink, - const GetCompositorFrameCallback get_compositor_frame_callback, - const OnFirstFrameRequestedCallback on_first_frame_requested_callback) + GetCompositorFrameCallback get_compositor_frame_callback, + OnFirstFrameRequestedCallback on_first_frame_requested_callback, + OnFrameSinkLost on_frame_sink_lost_callback) : frame_sink_(std::move(frame_sink)), get_compositor_frame_callback_(std::move(get_compositor_frame_callback)), on_first_frame_requested_callback_( - std::move(on_first_frame_requested_callback)) { + std::move(on_first_frame_requested_callback)), + on_frame_sink_lost_callback_(std::move(on_frame_sink_lost_callback)) { frame_sink_->BindToClient(this); } @@ -291,6 +293,8 @@ resource_manager().LostExportedResources(); if (WaitingToScheduleDelete()) { ScheduleDelete(); + } else { + std::move(on_frame_sink_lost_callback_).Run(); } }
diff --git a/ash/frame_sink/frame_sink_holder.h b/ash/frame_sink/frame_sink_holder.h index 9fac44b..3d996c3d 100644 --- a/ash/frame_sink/frame_sink_holder.h +++ b/ash/frame_sink/frame_sink_holder.h
@@ -51,14 +51,20 @@ bool auto_update, const gfx::Size& last_submitted_frame_size, float last_submitted_frame_dsf)>; + // Refer to declaration of `FrameSinkHost::OnFirstFrameRequested` for a // detailed comment. using OnFirstFrameRequestedCallback = base::RepeatingCallback<void()>; + // Refer to declaration of `FrameSinkHost::OnFrameSinkLost` for a detailed + // comment. + using OnFrameSinkLost = base::OnceCallback<void()>; + FrameSinkHolder( std::unique_ptr<cc::LayerTreeFrameSink> frame_sink, GetCompositorFrameCallback get_compositor_frame_callback, - OnFirstFrameRequestedCallback on_first_frame_requested_callback); + OnFirstFrameRequestedCallback on_first_frame_requested_callback, + OnFrameSinkLost on_frame_sink_lost_callback); FrameSinkHolder(const FrameSinkHolder&) = delete; FrameSinkHolder& operator=(const FrameSinkHolder&) = delete; @@ -202,6 +208,9 @@ // frame for the first time. OnFirstFrameRequestedCallback on_first_frame_requested_callback_; + // The callback invoked when the connection to `frame_sink_` is lost. + OnFrameSinkLost on_frame_sink_lost_callback_; + // Observation of the root window to which this holder becomes an observer to // extend its lifespan till all the in-flight resource to display compositor // are reclaimed.
diff --git a/ash/frame_sink/frame_sink_holder_unittest.cc b/ash/frame_sink/frame_sink_holder_unittest.cc index 9a8d12d..f287132 100644 --- a/ash/frame_sink/frame_sink_holder_unittest.cc +++ b/ash/frame_sink/frame_sink_holder_unittest.cc
@@ -79,8 +79,6 @@ return frame; } - void OnFirstFrameRequested() {} - void SetFrameResources(std::vector<viz::ResourceId> frame_resource) { latest_frame_resources_ = std::move(frame_resource); } @@ -126,8 +124,8 @@ std::move(layer_tree_frame_sink), base::BindRepeating(&TestFrameFactory::CreateCompositorFrame, base::Unretained(frame_factory_.get())), - base::BindRepeating(&TestFrameFactory::OnFirstFrameRequested, - base::Unretained(frame_factory_.get()))); + /*on_first_frame_requested_callback=*/base::DoNothing(), + /*on_frame_sink_lost_callback=*/base::DoNothing()); holder_weak_ptr_ = frame_sink_holder_->GetWeakPtr(); }
diff --git a/ash/frame_sink/frame_sink_host.cc b/ash/frame_sink/frame_sink_host.cc index 9d88eb7..1b12bc8b 100644 --- a/ash/frame_sink/frame_sink_host.cc +++ b/ash/frame_sink/frame_sink_host.cc
@@ -58,7 +58,8 @@ base::BindRepeating(&FrameSinkHost::CreateCompositorFrame, base::Unretained(this)), base::BindRepeating(&FrameSinkHost::OnFirstFrameRequested, - base::Unretained(this))); + base::Unretained(this)), + base::BindOnce(&FrameSinkHost::OnFrameSinkLost, base::Unretained(this))); } void FrameSinkHost::SetHostWindow(aura::Window* host_window) { @@ -123,4 +124,16 @@ void FrameSinkHost::OnFirstFrameRequested() {} +void FrameSinkHost::OnFrameSinkLost() { + frame_sink_holder_.reset(); + InitFrameSinkHolder(host_window(), host_window()->CreateLayerTreeFrameSink()); + + // Since some implementations of FrameSinkHost rarely update the surface, + // submit a compositor frame in order to update the surface. Otherwise, + // host_window will show a white surface instead. + const gfx::Rect& content_rect = host_window_->bounds(); + const gfx::Rect& damage_rect = content_rect; + UpdateSurface(content_rect, damage_rect, /*synchronous_draw=*/true); +} + } // namespace ash
diff --git a/ash/frame_sink/frame_sink_host.h b/ash/frame_sink/frame_sink_host.h index d48406e..2af88a4 100644 --- a/ash/frame_sink/frame_sink_host.h +++ b/ash/frame_sink/frame_sink_host.h
@@ -124,6 +124,10 @@ aura::Window* host_window, std::unique_ptr<cc::LayerTreeFrameSink> layer_tree_frame_sink); + // Callback invoked when the connection to `LayerTreeFrameSink` is lost. (i.e + // gpu crashed, host_window closes etc) + void OnFrameSinkLost(); + // Observation to track the lifetime of `host_window_`. base::ScopedObservation<aura::Window, aura::WindowObserver> host_window_observation_{this};
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index 9b992b0..3d5c251 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -308,6 +308,8 @@ "scanner/scanner_action.h", "scanner/scanner_delegate.h", "scanner/scanner_enums.h", + "scanner/scanner_feedback_info.cc", + "scanner/scanner_feedback_info.h", "scanner/scanner_profile_scoped_delegate.h", "scanner/scanner_system_state.cc", "scanner/scanner_system_state.h",
diff --git a/ash/public/cpp/ash_web_view.h b/ash/public/cpp/ash_web_view.h index 518fcd1..0a80bd6 100644 --- a/ash/public/cpp/ash_web_view.h +++ b/ash/public/cpp/ash_web_view.h
@@ -11,9 +11,9 @@ #include "base/observer_list_types.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/gfx/geometry/rounded_corners_f.h" -#include "url/gurl.h" #include "ui/views/view.h" +class GURL; enum class WindowOpenDisposition; namespace ash { @@ -74,10 +74,6 @@ // Used to override the Media Controls source title. Empty strings will // trigger default parent behavior. std::string source_title; - - // URL to open when AshWebView contents are activated but the widget is not - // activatable. Empty GURLs will trigger default parent behavior. - GURL activation_url; }; // An observer which receives AshWebView events.
diff --git a/ash/public/cpp/scanner/scanner_delegate.h b/ash/public/cpp/scanner/scanner_delegate.h index 6bf7c46..0f82b4e 100644 --- a/ash/public/cpp/scanner/scanner_delegate.h +++ b/ash/public/cpp/scanner/scanner_delegate.h
@@ -9,6 +9,7 @@ namespace ash { +struct ScannerFeedbackInfo; class ScannerProfileScopedDelegate; // Provides access to the browser from //ash/scanner. @@ -22,7 +23,7 @@ // // TODO: b/382562555 - Consider taking in a `context::BrowserContext*` here // to ensure that the dialog is opened for the correct user. - virtual void OpenFeedbackDialog() = 0; + virtual void OpenFeedbackDialog(ScannerFeedbackInfo feedback_info) = 0; }; } // namespace ash
diff --git a/ash/public/cpp/scanner/scanner_feedback_info.cc b/ash/public/cpp/scanner/scanner_feedback_info.cc new file mode 100644 index 0000000..ed097d2 --- /dev/null +++ b/ash/public/cpp/scanner/scanner_feedback_info.cc
@@ -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. + +#include "ash/public/cpp/scanner/scanner_feedback_info.h" + +#include <string> +#include <utility> + +#include "base/memory/ref_counted_memory.h" +#include "base/memory/scoped_refptr.h" + +namespace ash { + +ScannerFeedbackInfo::ScannerFeedbackInfo( + std::string action_details, + scoped_refptr<base::RefCountedMemory> screenshot) + : action_details(std::move(action_details)), + screenshot(std::move(screenshot)) {} + +ScannerFeedbackInfo::ScannerFeedbackInfo(const ScannerFeedbackInfo&) = default; +ScannerFeedbackInfo& ScannerFeedbackInfo::operator=( + const ScannerFeedbackInfo&) = default; +ScannerFeedbackInfo::ScannerFeedbackInfo(ScannerFeedbackInfo&&) = default; +ScannerFeedbackInfo& ScannerFeedbackInfo::operator=(ScannerFeedbackInfo&&) = + default; + +ScannerFeedbackInfo::~ScannerFeedbackInfo() = default; + +} // namespace ash
diff --git a/ash/public/cpp/scanner/scanner_feedback_info.h b/ash/public/cpp/scanner/scanner_feedback_info.h new file mode 100644 index 0000000..8516266f --- /dev/null +++ b/ash/public/cpp/scanner/scanner_feedback_info.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 ASH_PUBLIC_CPP_SCANNER_SCANNER_FEEDBACK_INFO_H_ +#define ASH_PUBLIC_CPP_SCANNER_SCANNER_FEEDBACK_INFO_H_ + +#include <string> + +#include "ash/public/cpp/ash_public_export.h" +#include "base/memory/ref_counted_memory.h" +#include "base/memory/scoped_refptr.h" + +namespace ash { + +struct ASH_PUBLIC_EXPORT ScannerFeedbackInfo { + std::string action_details; + scoped_refptr<base::RefCountedMemory> screenshot; + + ScannerFeedbackInfo(std::string action_details, + scoped_refptr<base::RefCountedMemory> screenshot); + + ScannerFeedbackInfo(const ScannerFeedbackInfo&); + ScannerFeedbackInfo& operator=(const ScannerFeedbackInfo&); + ScannerFeedbackInfo(ScannerFeedbackInfo&&); + ScannerFeedbackInfo& operator=(ScannerFeedbackInfo&&); + + ~ScannerFeedbackInfo(); +}; + +} // namespace ash + +#endif // ASH_PUBLIC_CPP_SCANNER_SCANNER_FEEDBACK_INFO_H_
diff --git a/ash/quick_insert/search/quick_insert_search_request.cc b/ash/quick_insert/search/quick_insert_search_request.cc index c909e50..d74aa0b 100644 --- a/ash/quick_insert/search/quick_insert_search_request.cc +++ b/ash/quick_insert/search/quick_insert_search_request.cc
@@ -59,7 +59,7 @@ constexpr auto kGoogleCorpGotoHosts = base::MakeFixedFlatSet<std::string_view>( {"goto2.corp.google.com", "goto.corp.google.com", "goto.google.com", "go"}); -constexpr int kMaxGifsToSearch = 50; +constexpr int kMaxGifsToSearch = 25; const char* SearchSourceToHistogram(QuickInsertSearchSource source) { switch (source) {
diff --git a/ash/scanner/fake_scanner_delegate.h b/ash/scanner/fake_scanner_delegate.h index 1190cf9..733da3e 100644 --- a/ash/scanner/fake_scanner_delegate.h +++ b/ash/scanner/fake_scanner_delegate.h
@@ -6,6 +6,7 @@ #define ASH_SCANNER_FAKE_SCANNER_DELEGATE_H_ #include "ash/public/cpp/scanner/scanner_delegate.h" +#include "ash/public/cpp/scanner/scanner_feedback_info.h" #include "ash/scanner/fake_scanner_profile_scoped_delegate.h" namespace ash { @@ -20,7 +21,7 @@ // ScannerDelegate: ScannerProfileScopedDelegate* GetProfileScopedDelegate() override; - void OpenFeedbackDialog() override {} + void OpenFeedbackDialog(ScannerFeedbackInfo feedback_info) override {} private: FakeScannerProfileScopedDelegate fake_scanner_profile_scoped_delegate_;
diff --git a/ash/scanner/scanner_command_delegate_impl.cc b/ash/scanner/scanner_command_delegate_impl.cc index 505190c7..c9eed39 100644 --- a/ash/scanner/scanner_command_delegate_impl.cc +++ b/ash/scanner/scanner_command_delegate_impl.cc
@@ -7,7 +7,6 @@ #include <memory> #include <utility> -#include "ash/capture_mode/capture_mode_controller.h" #include "ash/public/cpp/new_window_delegate.h" #include "ash/public/cpp/scanner/scanner_profile_scoped_delegate.h" #include "base/check_deref.h" @@ -43,10 +42,6 @@ std::unique_ptr<ui::ClipboardData> data) { CHECK_DEREF(ui::ClipboardNonBacked::GetForCurrentThread()) .WriteClipboardData(std::move(data)); - - // TODO: crbug.com/382182688 - Use a Scanner action toast instead of the - // capture mode copy text toast. - CaptureModeController::ShowTextCopiedToast(); } base::WeakPtr<ScannerCommandDelegate> ScannerCommandDelegateImpl::GetWeakPtr() {
diff --git a/ash/scanner/scanner_controller.cc b/ash/scanner/scanner_controller.cc index 3417434..a04bbdbd 100644 --- a/ash/scanner/scanner_controller.cc +++ b/ash/scanner/scanner_controller.cc
@@ -13,6 +13,8 @@ #include "ash/public/cpp/scanner/scanner_delegate.h" #include "ash/public/cpp/scanner/scanner_enums.h" #include "ash/public/cpp/scanner/scanner_profile_scoped_delegate.h" +#include "ash/public/cpp/system/toast_data.h" +#include "ash/public/cpp/system/toast_manager.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/scanner/scanner_command_delegate_impl.h" #include "ash/scanner/scanner_session.h" @@ -30,6 +32,9 @@ constexpr char kScannerActionNotificationId[] = "scanner_action_notification"; constexpr char kScannerNotifierId[] = "ash.scanner"; +constexpr char kScannerActionSuccessToastId[] = "scanner_action_success"; +constexpr char kScannerActionFailureToastId[] = "scanner_action_failure"; + // Shows an action progress notification. Note that this will remove the // previous action notification if there is one. void ShowActionProgressNotification() { @@ -58,11 +63,27 @@ // Should be called when an action finishes execution. void OnActionFinished(bool success) { + // Remove the action progress notification. message_center::MessageCenter::Get()->RemoveNotification( kScannerActionNotificationId, /*by_user=*/false); - // TODO: crbug.com/382182688 - Show an error message if the action was not - // successful. + + if (success) { + // TODO: crbug.com/382182688 - The action success text should depend on the + // type of action executed. + constexpr char16_t kPlaceholderActionSuccessText[] = u"Action Finished"; + // TODO: crbug.com/383925780 - Add feedback mechanism to the toast. + ToastManager::Get()->Show(ToastData(kScannerActionSuccessToastId, + ToastCatalogName::kScannerActionSuccess, + kPlaceholderActionSuccessText)); + } else { + // TODO: crbug.com/378582420 - The action failure text should depend on the + // type of action attempted. + constexpr char16_t kPlaceholderActionFailureText[] = u"Action Failed"; + ToastManager::Get()->Show(ToastData(kScannerActionFailureToastId, + ToastCatalogName::kScannerActionFailure, + kPlaceholderActionFailureText)); + } } } // namespace
diff --git a/ash/scanner/scanner_controller_unittest.cc b/ash/scanner/scanner_controller_unittest.cc index f93fe25..c112ff9 100644 --- a/ash/scanner/scanner_controller_unittest.cc +++ b/ash/scanner/scanner_controller_unittest.cc
@@ -13,6 +13,7 @@ #include "ash/public/cpp/scanner/scanner_delegate.h" #include "ash/public/cpp/scanner/scanner_enums.h" #include "ash/public/cpp/scanner/scanner_system_state.h" +#include "ash/public/cpp/system/toast_manager.h" #include "ash/scanner/fake_scanner_profile_scoped_delegate.h" #include "ash/scanner/scanner_action_view_model.h" #include "ash/shell.h" @@ -39,6 +40,9 @@ using ::testing::SizeIs; using ::testing::WithArg; +constexpr char kScannerActionSuccessToastId[] = "scanner_action_success"; +constexpr char kScannerActionFailureToastId[] = "scanner_action_failure"; + FakeScannerProfileScopedDelegate* GetFakeScannerProfileScopedDelegate( ScannerController& scanner_controller) { return static_cast<FakeScannerProfileScopedDelegate*>( @@ -162,6 +166,65 @@ IsEmpty()); } +TEST_F(ScannerControllerTest, ShowsToastAfterActionSuccess) { + base::test::TestFuture<std::vector<ScannerActionViewModel>> actions_future; + ScannerController* scanner_controller = Shell::Get()->scanner_controller(); + ASSERT_TRUE(scanner_controller); + EXPECT_TRUE(scanner_controller->StartNewSession()); + manta::proto::ScannerOutput output; + output.add_objects()->add_actions()->mutable_new_event()->set_title( + "Event title"); + FakeScannerProfileScopedDelegate& fake_profile_scoped_delegate = + *GetFakeScannerProfileScopedDelegate(*scanner_controller); + // Mock a successful action. + EXPECT_CALL(fake_profile_scoped_delegate, FetchActionsForImage) + .WillOnce(RunOnceCallback<1>( + std::make_unique<manta::proto::ScannerOutput>(output), + manta::MantaStatus())); + EXPECT_CALL(fake_profile_scoped_delegate, FetchActionDetailsForImage) + .WillOnce(RunOnceCallback<2>( + std::make_unique<manta::proto::ScannerOutput>(output), + manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk})); + + // Fetch an action and execute it. + scanner_controller->FetchActionsForImage(/*jpeg_bytes=*/nullptr, + actions_future.GetCallback()); + std::vector<ScannerActionViewModel> actions = actions_future.Take(); + ASSERT_THAT(actions, SizeIs(1)); + scanner_controller->ExecuteAction(actions[0]); + + EXPECT_TRUE(ToastManager::Get()->IsToastShown(kScannerActionSuccessToastId)); +} + +TEST_F(ScannerControllerTest, ShowsToastAfterActionFailure) { + base::test::TestFuture<std::vector<ScannerActionViewModel>> actions_future; + ScannerController* scanner_controller = Shell::Get()->scanner_controller(); + ASSERT_TRUE(scanner_controller); + EXPECT_TRUE(scanner_controller->StartNewSession()); + auto output = std::make_unique<manta::proto::ScannerOutput>(); + output->add_objects()->add_actions()->mutable_new_event()->set_title( + "Event title"); + FakeScannerProfileScopedDelegate& fake_profile_scoped_delegate = + *GetFakeScannerProfileScopedDelegate(*scanner_controller); + EXPECT_CALL(fake_profile_scoped_delegate, FetchActionsForImage) + .WillOnce(RunOnceCallback<1>(std::move(output), manta::MantaStatus())); + // Mock a failure to fetch action details. + EXPECT_CALL(fake_profile_scoped_delegate, FetchActionDetailsForImage) + .WillOnce(RunOnceCallback<2>( + /*output=*/nullptr, + manta::MantaStatus{.status_code = + manta::MantaStatusCode::kBackendFailure})); + + // Fetch an action and try to execute it. + scanner_controller->FetchActionsForImage(/*jpeg_bytes=*/nullptr, + actions_future.GetCallback()); + std::vector<ScannerActionViewModel> actions = actions_future.Take(); + ASSERT_THAT(actions, SizeIs(1)); + scanner_controller->ExecuteAction(actions[0]); + + EXPECT_TRUE(ToastManager::Get()->IsToastShown(kScannerActionFailureToastId)); +} + } // namespace } // namespace ash
diff --git a/ash/system/audio/audio_effects_controller.cc b/ash/system/audio/audio_effects_controller.cc index 53324ca6..1469408 100644 --- a/ash/system/audio/audio_effects_controller.cc +++ b/ash/system/audio/audio_effects_controller.cc
@@ -29,8 +29,7 @@ if (CrasAudioHandler::Get()->GetAudioEffectDlcs() == std::nullopt) { return false; } - return CrasAudioHandler::Get()->IsStyleTransferSupportedForDevice( - CrasAudioHandler::Get()->GetPrimaryActiveInputNode()); + return CrasAudioHandler::Get()->style_transfer_supported(); } // Vc can only support either noise cancellation or style transfer. So we skip
diff --git a/ash/system/focus_mode/focus_mode_controller.cc b/ash/system/focus_mode/focus_mode_controller.cc index 09dc887..f4feec7 100644 --- a/ash/system/focus_mode/focus_mode_controller.cc +++ b/ash/system/focus_mode/focus_mode_controller.cc
@@ -30,10 +30,8 @@ #include "ash/system/status_area_widget.h" #include "ash/system/toast/anchored_nudge_manager_impl.h" #include "ash/system/unified/unified_system_tray.h" -#include "base/check_op.h" #include "base/metrics/histogram_functions.h" #include "base/rand_util.h" -#include "base/strings/strcat.h" #include "base/time/time.h" #include "chromeos/ash/components/audio/sounds.h" #include "chromeos/ash/components/audio/system_sounds_delegate.h" @@ -57,12 +55,6 @@ constexpr base::TimeDelta kEndingMomentBounceAnimationDelay = base::Minutes(1); -// YouTube Music API playlist name prefix. -constexpr std::string_view kPlaylistIdPrefix = "playlists/"; -constexpr std::string_view kBasePlaylistUrl = - "https://music.youtube.com/playlist?list="; -constexpr std::string_view kYouTubeMusicUrl = "https://music.youtube.com/"; - bool IsQuietModeOnSetByFocusMode() { auto* message_center = message_center::MessageCenter::Get(); return message_center->IsQuietMode() && @@ -151,25 +143,6 @@ std::move(callback).Run(task); } -// Returns the direct URL to view info for the associated YouTube Music -// `playlist`. -GURL GetYouTubeMusicPlaylistUrl(focus_mode_util::SelectedPlaylist playlist) { - CHECK_EQ(playlist.type, focus_mode_util::SoundType::kYouTubeMusic); - - if (playlist.id.starts_with(kPlaylistIdPrefix)) { - // Strip the prefix from `playlist.id` to get the actual playlist id and - // construct the URL. - return GURL(base::StrCat( - {kBasePlaylistUrl, playlist.id.substr(kPlaylistIdPrefix.length())})); - } - - // The expected api playlist name should have the prefix "playlists/". Check - // the playlists api documentation: - // https://developers.google.com/youtube/mediaconnect/reference/rest/v1/playlists#Playlist" - LOG(WARNING) << "YTM playlist name format is invalid"; - return GURL(kYouTubeMusicUrl); -} - } // namespace FocusModeController::FocusModeController( @@ -904,14 +877,6 @@ web_view_params.source_title = focus_mode_util::GetSourceTitleForMediaControls( focus_mode_sounds_controller_->selected_playlist()); - // Provide the playlist source URL to show for when users click on the media - // controls view. - if (focus_mode_sounds_controller_->selected_playlist().type == - focus_mode_util::SoundType::kYouTubeMusic) { - web_view_params.activation_url = GetYouTubeMusicPlaylistUrl( - focus_mode_sounds_controller_->selected_playlist()); - } - focus_mode_media_view_ = media_widget_->SetContentsView( AshWebViewFactory::Get()->Create(web_view_params)); focus_mode_media_view_->Navigate(GURL(chrome::kChromeUIFocusModeMediaURL));
diff --git a/ash/system/focus_mode/focus_mode_util.cc b/ash/system/focus_mode/focus_mode_util.cc index cf83ba1..9c049dc 100644 --- a/ash/system/focus_mode/focus_mode_util.cc +++ b/ash/system/focus_mode/focus_mode_util.cc
@@ -46,8 +46,6 @@ u"☑"), }; -constexpr const char* kYouTubeMusicUrl = "music.youtube.com"; - } // namespace SelectedPlaylist::SelectedPlaylist() = default; @@ -145,10 +143,10 @@ return ""; } - return playlist.type == SoundType::kYouTubeMusic - ? kYouTubeMusicUrl - : l10n_util::GetStringUTF8( - IDS_ASH_STATUS_TRAY_FOCUS_MODE_SOUNDS_SOUNDSCAPE_BUTTON); + return l10n_util::GetStringUTF8( + playlist.type == SoundType::kYouTubeMusic + ? IDS_ASH_STATUS_TRAY_FOCUS_MODE_SOUNDS_YOUTUBE_MUSIC_BUTTON + : IDS_ASH_STATUS_TRAY_FOCUS_MODE_SOUNDS_SOUNDSCAPE_BUTTON); } std::u16string GetCongratulatoryText(const size_t index) {
diff --git a/ash/system/focus_mode/focus_mode_util_unittest.cc b/ash/system/focus_mode/focus_mode_util_unittest.cc index 5ee7c29..b58bd8e 100644 --- a/ash/system/focus_mode/focus_mode_util_unittest.cc +++ b/ash/system/focus_mode/focus_mode_util_unittest.cc
@@ -22,8 +22,7 @@ SelectedPlaylist selected_playlist; selected_playlist.id = "id0"; selected_playlist.type = SoundType::kYouTubeMusic; - EXPECT_EQ(GetSourceTitleForMediaControls(selected_playlist), - "music.youtube.com"); + EXPECT_EQ(GetSourceTitleForMediaControls(selected_playlist), "YouTube Music"); } // Verify the Soundscape source string.
diff --git a/ash/webui/common/resources/sea_pen/sea_pen_samples_element.html b/ash/webui/common/resources/sea_pen/sea_pen_samples_element.html index fec5c54..aa1ea3a 100644 --- a/ash/webui/common/resources/sea_pen/sea_pen_samples_element.html +++ b/ash/webui/common/resources/sea_pen/sea_pen_samples_element.html
@@ -44,6 +44,8 @@ items="[[samples]]" as="sample" grid + aria-label="$i18n{seaPenFreeformAriaLabelSamplePrompts}" + aria-setsize="6" role="listbox"> <template> <div class="container">
diff --git a/ash/webui/common/resources/sea_pen/sea_pen_suggestions_element.html b/ash/webui/common/resources/sea_pen/sea_pen_suggestions_element.html index 8e718ef..2678914 100644 --- a/ash/webui/common/resources/sea_pen/sea_pen_suggestions_element.html +++ b/ash/webui/common/resources/sea_pen/sea_pen_suggestions_element.html
@@ -51,6 +51,8 @@ id="suggestionSelector" selected="0" selected-item="{{ironSelectedSuggestion_}}" + aria-label="$i18n{seaPenFreeformAriaLabelSuggestions}" + aria-setsize$="[[selectableSuggestions_.length]]" role="radiogroup"> <template is="dom-repeat" items="[[selectableSuggestions_]]" as="suggestion"> <cr-button
diff --git a/ash/webui/common/sea_pen_resources.cc b/ash/webui/common/sea_pen_resources.cc index da362c4..bf29059e 100644 --- a/ash/webui/common/sea_pen_resources.cc +++ b/ash/webui/common/sea_pen_resources.cc
@@ -86,6 +86,10 @@ IDS_SEA_PEN_INTRODUCTION_DIALOG_FIRST_PARAGRAPH}, {"seaPenFreeformIntroductionDialogFirstParagraph", IDS_SEA_PEN_FREEFORM_INTRODUCTION_DIALOG_FIRST_PARAGRAPH}, + {"seaPenFreeformAriaLabelSamplePrompts", + IDS_SEA_PEN_FREEFORM_ARIA_LABEL_SAMPLE_PROMPTS}, + {"seaPenFreeformAriaLabelSuggestions", + IDS_SEA_PEN_FREEFORM_ARIA_LABEL_SUGGESTIONS}, {"seaPenDismissError", IDS_PERSONALIZATION_APP_DISMISS}, {"ariaLabelLoading", IDS_PERSONALIZATION_APP_ARIA_LABEL_LOADING},
diff --git a/ash/webui/projector_app/projector_oauth_token_fetcher.cc b/ash/webui/projector_app/projector_oauth_token_fetcher.cc index 08c1c81..f0fb421a 100644 --- a/ash/webui/projector_app/projector_oauth_token_fetcher.cc +++ b/ash/webui/projector_app/projector_oauth_token_fetcher.cc
@@ -4,6 +4,7 @@ #include "ash/webui/projector_app/projector_oauth_token_fetcher.h" +#include "ash/constants/ash_features.h" #include "ash/public/cpp/projector/projector_controller.h" #include "ash/webui/projector_app/projector_app_client.h" #include "base/containers/contains.h" @@ -29,6 +30,12 @@ } OAuth2AccessTokenManager::ScopeSet GetScopeSet() { + if (ash::features::IsProjectorUseDVSPlaybackEndpointEnabled()) { + return OAuth2AccessTokenManager::ScopeSet{ + GaiaConstants::kDriveOAuth2Scope, + GaiaConstants::kDriveReadOnlyOAuth2Scope}; + } + return OAuth2AccessTokenManager::ScopeSet{GaiaConstants::kDriveOAuth2Scope}; }
diff --git a/ash/webui/projector_app/projector_xhr_sender.cc b/ash/webui/projector_app/projector_xhr_sender.cc index 4707bf7..8c83a4b 100644 --- a/ash/webui/projector_app/projector_xhr_sender.cc +++ b/ash/webui/projector_app/projector_xhr_sender.cc
@@ -12,6 +12,7 @@ #include "ash/webui/projector_app/public/mojom/projector_types.mojom.h" #include "base/containers/flat_map.h" #include "base/functional/bind.h" +#include "base/strings/pattern.h" #include "base/strings/string_util.h" #include "components/signin/public/identity_manager/access_token_info.h" #include "components/signin/public/identity_manager/identity_manager.h" @@ -105,8 +106,19 @@ "https://drive.google.com/u/0/get_video_info", "https://translation.googleapis.com/language/translate/v2"}; +bool IsDVSPlaybackUrl(const std::string& url) { + return base::MatchPattern(url, + "https://staging-workspacevideo-pa.googleapis.com/" + "v1/drive/media/*/playback"); +} + // Return true if the url matches the allowed URL prefix. bool IsUrlAllowlisted(const std::string& url) { + if (features::IsProjectorUseDVSPlaybackEndpointEnabled() && + IsDVSPlaybackUrl(url)) { + return true; + } + for (auto* urlPrefix : kUrlAllowlist) { if (base::StartsWith(url, urlPrefix, base::CompareCase::SENSITIVE)) return true;
diff --git a/ash/webui/scanner_feedback_ui/BUILD.gn b/ash/webui/scanner_feedback_ui/BUILD.gn index d487db2..ed28cc4 100644 --- a/ash/webui/scanner_feedback_ui/BUILD.gn +++ b/ash/webui/scanner_feedback_ui/BUILD.gn
@@ -8,6 +8,10 @@ static_library("scanner_feedback_ui") { sources = [ + "scanner_feedback_browser_context_data.cc", + "scanner_feedback_browser_context_data.h", + "scanner_feedback_page_handler.cc", + "scanner_feedback_page_handler.h", "scanner_feedback_untrusted_ui.cc", "scanner_feedback_untrusted_ui.h", "url_constants.h", @@ -21,7 +25,10 @@ ] public_deps = [ + "//ash/public/cpp", "//ash/webui/common:chrome_os_webui_config", + "//ash/webui/scanner_feedback_ui/mojom", + "//ui/web_dialogs", "//ui/webui", ] }
diff --git a/ash/webui/scanner_feedback_ui/DEPS b/ash/webui/scanner_feedback_ui/DEPS new file mode 100644 index 0000000..2aa5189 --- /dev/null +++ b/ash/webui/scanner_feedback_ui/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+ui/web_dialogs", +]
diff --git a/ash/webui/scanner_feedback_ui/mojom/BUILD.gn b/ash/webui/scanner_feedback_ui/mojom/BUILD.gn new file mode 100644 index 0000000..e91847fe --- /dev/null +++ b/ash/webui/scanner_feedback_ui/mojom/BUILD.gn
@@ -0,0 +1,15 @@ +# 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("//build/config/chromeos/ui_mode.gni") +import("//mojo/public/tools/bindings/mojom.gni") + +assert(is_chromeos_ash, "Scanner is ash-chrome only") + +mojom("mojom") { + sources = [ "scanner_feedback_ui.mojom" ] + + public_deps = [ "//url/mojom:url_mojom_gurl" ] + webui_module_path = "/" +}
diff --git a/ash/webui/scanner_feedback_ui/mojom/OWNERS b/ash/webui/scanner_feedback_ui/mojom/OWNERS new file mode 100644 index 0000000..08850f4 --- /dev/null +++ b/ash/webui/scanner_feedback_ui/mojom/OWNERS
@@ -0,0 +1,2 @@ +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/ash/webui/scanner_feedback_ui/mojom/scanner_feedback_ui.mojom b/ash/webui/scanner_feedback_ui/mojom/scanner_feedback_ui.mojom new file mode 100644 index 0000000..785b975 --- /dev/null +++ b/ash/webui/scanner_feedback_ui/mojom/scanner_feedback_ui.mojom
@@ -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. + +module ash.mojom.scanner_feedback_ui; + +import "url/mojom/url.mojom"; + +// Encompasses all fixed additional information to attach to a given feedback +// report. Will be displayed to the user in the feedback form. +struct FeedbackInfo { + // A human-readible string showing the details of the action performed. + // Will realistically be <50kB. + // The contents are derived from a Google-owned server response. + string action_details; + // A `chrome-untrusted://scanner-feedback/screenshots/UNGUESSABLETOKEN.png` + // URL which, when accessed, will display the screenshot. + // The contents are a (possibly resized) screen capture from Ash. + url.mojom.Url screenshot_url; +}; + +// Handles communication from `chrome-untrusted://scanner-feedback` to the +// trusted browser process. +interface PageHandler { + // Gets the `FeedbackInfo` for this page handler. + // If no feedback information was attached to this page handler (for example, + // if `chrome-untrusted://scanner-feedback` was manually opened in the + // browser) calling this will kill the renderer process by reporting a bad + // message. + GetFeedbackInfo() => (FeedbackInfo feedback_info); + + // Requests for the dialog displaying this page to be closed. + // May not immediately close the dialog or the page handler. + // + // If no "close dialog" callback was attached to this page handler, calling + // this will kill the renderer process by reporting a bad message. + CloseDialog(); +};
diff --git a/ash/webui/scanner_feedback_ui/resources/BUILD.gn b/ash/webui/scanner_feedback_ui/resources/BUILD.gn index d5ed3e2..e2bbbb20 100644 --- a/ash/webui/scanner_feedback_ui/resources/BUILD.gn +++ b/ash/webui/scanner_feedback_ui/resources/BUILD.gn
@@ -17,10 +17,16 @@ web_component_files = [ "app.ts" ] + mojo_files_deps = + [ "//ash/webui/scanner_feedback_ui/mojom:mojom_ts__generator" ] + + mojo_files = [ "$root_gen_dir/ash/webui/scanner_feedback_ui/mojom/scanner_feedback_ui.mojom-webui.ts" ] + ts_deps = [ "//third_party/cros-components:cros_components_ts", "//third_party/polymer/v3_0:library", "//ui/webui/resources/cr_components/color_change_listener:build_ts", + "//ui/webui/resources/mojo:build_ts", ] ts_composite = true
diff --git a/ash/webui/scanner_feedback_ui/resources/app.html b/ash/webui/scanner_feedback_ui/resources/app.html index eac703c..b8eb533 100644 --- a/ash/webui/scanner_feedback_ui/resources/app.html +++ b/ash/webui/scanner_feedback_ui/resources/app.html
@@ -1,4 +1,9 @@ -<mako-orca-feedback - string-source="[[stringSource]]" - open-url="[[openUrl]]" - ></mako-orca-feedback> +<template is="dom-if" if="[[!isEmpty(screenshotUrl)]]"> + <mako-orca-feedback + string-source="[[stringSource]]" + open-url="[[openUrl]]" + extra-info-callback="[[extraInfoCallback]]" + extra-image="[[screenshotUrl]]" + revert-to-previous-screen="[[revertToPreviousScreen]]" + ></mako-orca-feedback> +</template>
diff --git a/ash/webui/scanner_feedback_ui/resources/app.ts b/ash/webui/scanner_feedback_ui/resources/app.ts index e015b43..1d21c2e 100644 --- a/ash/webui/scanner_feedback_ui/resources/app.ts +++ b/ash/webui/scanner_feedback_ui/resources/app.ts
@@ -9,6 +9,13 @@ import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './app.html.js'; +import {PageHandler} from './scanner_feedback_ui.mojom-webui.js'; + +const PAGE_HANDLER_REMOTE = PageHandler.getRemote(); + +const FEEDBACK_INFO_PROMISE = PAGE_HANDLER_REMOTE.getFeedbackInfo().then( + ({feedbackInfo}) => feedbackInfo); + // `StringSource` is not exported from orca-feedback.js, so get a reference to // it via `OrcaFeedback`. @@ -51,14 +58,35 @@ // Private properties: stringSource: Object, openUrl: Object, + extraInfoCallback: Object, + screenshotUrl: String, + revertToPeviousScreen: Object, }; } + // Used in template: private readonly stringSource = STRING_SOURCE; private readonly openUrl = (url: string) => { window.open(url, '_blank'); - // TODO: b/382562555 - Close the dialog after opening the URL. + this.revertToPreviousScreen(); }; + private readonly extraInfoCallback = () => + FEEDBACK_INFO_PROMISE.then(feedbackInfo => feedbackInfo.actionDetails); + private screenshotUrl = ''; + private readonly revertToPreviousScreen = () => + PAGE_HANDLER_REMOTE.closeDialog(); + + constructor() { + super(); + FEEDBACK_INFO_PROMISE.then(feedbackInfo => { + this.screenshotUrl = feedbackInfo.screenshotUrl.url; + }); + } + + // Used in computed bindings: + private isEmpty(string: string): boolean { + return string === ''; + } } declare global {
diff --git a/ash/webui/scanner_feedback_ui/scanner_feedback_browser_context_data.cc b/ash/webui/scanner_feedback_ui/scanner_feedback_browser_context_data.cc new file mode 100644 index 0000000..07e55d8 --- /dev/null +++ b/ash/webui/scanner_feedback_ui/scanner_feedback_browser_context_data.cc
@@ -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. + +#include "ash/webui/scanner_feedback_ui/scanner_feedback_browser_context_data.h" + +#include <map> +#include <memory> +#include <utility> + +#include "ash/public/cpp/scanner/scanner_feedback_info.h" +#include "base/compiler_specific.h" +#include "base/functional/bind.h" +#include "base/functional/callback_helpers.h" +#include "base/memory/weak_ptr.h" +#include "base/supports_user_data.h" +#include "base/unguessable_token.h" +#include "content/public/browser/browser_context.h" + +namespace ash { + +namespace { + +const void* const kBrowserContextKey = &kBrowserContextKey; + +struct BrowserContextData : public base::SupportsUserData::Data { + std::map<base::UnguessableToken, ScannerFeedbackInfo> feedback_info_map; + + static BrowserContextData* GetForBrowserContext( + content::BrowserContext& browser_context LIFETIME_BOUND) { + base::SupportsUserData::Data* data = + browser_context.GetUserData(&kBrowserContextKey); + + // Can be nullptr. + return static_cast<BrowserContextData*>(data); + } + + static BrowserContextData& CreateOrGetForBrowserContext( + content::BrowserContext& browser_context LIFETIME_BOUND) { + BrowserContextData* current_data = GetForBrowserContext(browser_context); + + if (current_data != nullptr) { + return *current_data; + } + + auto new_data = std::make_unique<BrowserContextData>(); + BrowserContextData& new_data_ref = *new_data; + browser_context.SetUserData(&kBrowserContextKey, std::move(new_data)); + // Still valid, as the `unique_ptr` - now owned by the browser context - + // still points to the same heap-allocated memory. + return new_data_ref; + } +}; + +} // namespace + +base::ScopedClosureRunner SetScannerFeedbackInfoForBrowserContext( + content::BrowserContext& browser_context, + base::UnguessableToken id, + ScannerFeedbackInfo feedback_info) { + auto& data = + BrowserContextData::CreateOrGetForBrowserContext(browser_context); + data.feedback_info_map.insert({id, std::move(feedback_info)}); + + return base::ScopedClosureRunner(base::BindOnce( + [](base::WeakPtr<content::BrowserContext> weak_browser_context, + base::UnguessableToken id) { + if (weak_browser_context == nullptr) { + // The browser context is already gone - no need to clean up. + return; + } + + auto* data = + BrowserContextData::GetForBrowserContext(*weak_browser_context); + if (data == nullptr) { + // The browser context's user data was cleared. + return; + } + + data->feedback_info_map.erase(id); + }, + browser_context.GetWeakPtr(), id)); +} + +ScannerFeedbackInfo* GetScannerFeedbackInfoForBrowserContext( + content::BrowserContext& browser_context LIFETIME_BOUND, + base::UnguessableToken id) { + auto* data = BrowserContextData::GetForBrowserContext(browser_context); + if (data == nullptr) { + return nullptr; + } + + auto it = data->feedback_info_map.find(id); + if (it == data->feedback_info_map.end()) { + return nullptr; + } + + return &it->second; +} + +} // namespace ash
diff --git a/ash/webui/scanner_feedback_ui/scanner_feedback_browser_context_data.h b/ash/webui/scanner_feedback_ui/scanner_feedback_browser_context_data.h new file mode 100644 index 0000000..4479bdf2 --- /dev/null +++ b/ash/webui/scanner_feedback_ui/scanner_feedback_browser_context_data.h
@@ -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. + +#ifndef ASH_WEBUI_SCANNER_FEEDBACK_UI_SCANNER_FEEDBACK_BROWSER_CONTEXT_DATA_H_ +#define ASH_WEBUI_SCANNER_FEEDBACK_UI_SCANNER_FEEDBACK_BROWSER_CONTEXT_DATA_H_ + +#include "ash/public/cpp/scanner/scanner_feedback_info.h" +#include "base/compiler_specific.h" +#include "base/functional/callback_helpers.h" +#include "base/unguessable_token.h" + +// Functions for storing and retrieving `ScannerFeedbackInfo` on a browser +// context, keyed by an `base::UnguessableToken` ID. Allows access to a WebUI's +// `ScannerFeedbackInfo` from both the page handler (which stores the ID) as +// well as any request filters, provided the ID is encoded in the URL. + +namespace content { +class BrowserContext; +} + +namespace ash { + +// Sets `feedback_info` keyed by `id` in `browser_context`. +// `feedback_info` can later be retrieved from the `Get` function below. +// Returns an object that, when destructed, also destructs `feedback_info` to +// prevent memory leaks. +base::ScopedClosureRunner SetScannerFeedbackInfoForBrowserContext( + content::BrowserContext& browser_context, + base::UnguessableToken id, + ScannerFeedbackInfo feedback_info); + +// Gets a reference to a `ScannerFeedbackInfo` keyed by `id` in +// `browser_context`, set by the `Set` function above. +// If no `ScannerFeedbackInfo` exists for `id`, returns nullptr. +ScannerFeedbackInfo* GetScannerFeedbackInfoForBrowserContext( + content::BrowserContext& browser_context LIFETIME_BOUND, + base::UnguessableToken id); + +} // namespace ash + +#endif // ASH_WEBUI_SCANNER_FEEDBACK_UI_SCANNER_FEEDBACK_BROWSER_CONTEXT_DATA_H_
diff --git a/ash/webui/scanner_feedback_ui/scanner_feedback_page_handler.cc b/ash/webui/scanner_feedback_ui/scanner_feedback_page_handler.cc new file mode 100644 index 0000000..f342288 --- /dev/null +++ b/ash/webui/scanner_feedback_ui/scanner_feedback_page_handler.cc
@@ -0,0 +1,69 @@ +// 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 "ash/webui/scanner_feedback_ui/scanner_feedback_page_handler.h" + +#include <utility> + +#include "ash/public/cpp/scanner/scanner_feedback_info.h" +#include "ash/webui/scanner_feedback_ui/mojom/scanner_feedback_ui.mojom.h" +#include "ash/webui/scanner_feedback_ui/scanner_feedback_browser_context_data.h" +#include "ash/webui/scanner_feedback_ui/url_constants.h" +#include "base/strings/strcat.h" +#include "base/unguessable_token.h" +#include "content/public/browser/browser_context.h" +#include "mojo/public/cpp/bindings/message.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" + +namespace ash { + +ScannerFeedbackPageHandler::ScannerFeedbackPageHandler( + content::BrowserContext& browser_context) + : id_(base::UnguessableToken::Create()), + browser_context_(browser_context) {} + +ScannerFeedbackPageHandler::~ScannerFeedbackPageHandler() = default; + +void ScannerFeedbackPageHandler::Bind( + mojo::PendingReceiver<mojom::scanner_feedback_ui::PageHandler> receiver) { + if (receiver_.is_bound()) { + receiver_.reset(); + } + receiver_.Bind(std::move(receiver)); +} + +void ScannerFeedbackPageHandler::GetFeedbackInfo( + GetFeedbackInfoCallback callback) { + auto feedback_info_ptr = mojom::scanner_feedback_ui::FeedbackInfo::New(); + ScannerFeedbackInfo* feedback_info = + GetScannerFeedbackInfoForBrowserContext(*browser_context_, id_); + if (feedback_info == nullptr) { + mojo::ReportBadMessage("No feedback info was set."); + // The callback still needs to be called with a valid `FeedbackInfoPtr` + // before the renderer can be killed. + std::move(callback).Run(std::move(feedback_info_ptr)); + return; + } + + feedback_info_ptr->action_details = feedback_info->action_details; + feedback_info_ptr->screenshot_url = GURL(base::StrCat({ + kScannerFeedbackUntrustedUrl, + kScannerFeedbackScreenshotPrefix, + id_.ToString(), + kScannerFeedbackScreenshotSuffix, + })); + + std::move(callback).Run(std::move(feedback_info_ptr)); +} + +void ScannerFeedbackPageHandler::CloseDialog() { + if (close_dialog_callback_.is_null()) { + mojo::ReportBadMessage( + "No close dialog callback was attached to the page handler."); + return; + } + close_dialog_callback_.Run(); +} + +} // namespace ash
diff --git a/ash/webui/scanner_feedback_ui/scanner_feedback_page_handler.h b/ash/webui/scanner_feedback_ui/scanner_feedback_page_handler.h new file mode 100644 index 0000000..fd739aae --- /dev/null +++ b/ash/webui/scanner_feedback_ui/scanner_feedback_page_handler.h
@@ -0,0 +1,73 @@ +// 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 ASH_WEBUI_SCANNER_FEEDBACK_UI_SCANNER_FEEDBACK_PAGE_HANDLER_H_ +#define ASH_WEBUI_SCANNER_FEEDBACK_UI_SCANNER_FEEDBACK_PAGE_HANDLER_H_ + +#include "ash/webui/scanner_feedback_ui/mojom/scanner_feedback_ui.mojom.h" +#include "base/functional/callback_forward.h" +#include "base/memory/raw_ref.h" +#include "base/unguessable_token.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver.h" + +namespace content { +class BrowserContext; +} + +namespace ash { + +// Stores and handles all data related to a Scanner feedback prompt. +// +// Used for serving Mojo calls for a given `ScannerFeedbackUntrustedUI`. Serves +// data from feedback info stored on the browser context - see +// scanner_feedback_browser_context_data.h for more details. Use `id()` to get +// the ID used for this page. +class ScannerFeedbackPageHandler + : public mojom::scanner_feedback_ui::PageHandler { + public: + // Callback called from `CloseDialog`. + // Not guaranteed to be called if, for example, if the user closes the UI + // through other means such as the Escape key. + // May be called multiple times if, for example, this callback is a no-op and + // the button is clicked multiple times, or a user's click races the closing + // of the dialog. + using CloseDialogCallback = base::RepeatingClosure; + + explicit ScannerFeedbackPageHandler(content::BrowserContext& browser_context); + + ScannerFeedbackPageHandler(const ScannerFeedbackPageHandler&) = delete; + ScannerFeedbackPageHandler& operator=(const ScannerFeedbackPageHandler&) = + delete; + + ~ScannerFeedbackPageHandler() override; + + // Binds the receiver, unbinding the existing one if necessary. + void Bind( + mojo::PendingReceiver<mojom::scanner_feedback_ui::PageHandler> receiver); + + void SetCloseDialogCallback(CloseDialogCallback close_dialog_callback) { + close_dialog_callback_ = std::move(close_dialog_callback); + } + + base::UnguessableToken id() const { return id_; } + + // mojom::scanner_feedback_ui::PageHandler: + void GetFeedbackInfo(GetFeedbackInfoCallback callback) override; + void CloseDialog() override; + + private: + const base::UnguessableToken id_; + + // Null on construction. Set in `SetCloseDialogCallback`. + CloseDialogCallback close_dialog_callback_; + + const raw_ref<content::BrowserContext> browser_context_; + + mojo::Receiver<mojom::scanner_feedback_ui::PageHandler> receiver_{this}; +}; + +} // namespace ash + +#endif // ASH_WEBUI_SCANNER_FEEDBACK_UI_SCANNER_FEEDBACK_PAGE_HANDLER_H_
diff --git a/ash/webui/scanner_feedback_ui/scanner_feedback_untrusted_ui.cc b/ash/webui/scanner_feedback_ui/scanner_feedback_untrusted_ui.cc index f5abc30f..d5deff4 100644 --- a/ash/webui/scanner_feedback_ui/scanner_feedback_untrusted_ui.cc +++ b/ash/webui/scanner_feedback_ui/scanner_feedback_untrusted_ui.cc
@@ -4,29 +4,125 @@ #include "ash/webui/scanner_feedback_ui/scanner_feedback_untrusted_ui.h" +#include <cstddef> #include <memory> +#include <optional> #include <string> +#include <string_view> #include <utility> #include "ash/constants/ash_features.h" +#include "ash/public/cpp/scanner/scanner_feedback_info.h" #include "ash/webui/common/chrome_os_webui_config.h" #include "ash/webui/common/trusted_types_util.h" #include "ash/webui/grit/ash_scanner_feedback_ui_resources.h" #include "ash/webui/grit/ash_scanner_feedback_ui_resources_map.h" +#include "ash/webui/scanner_feedback_ui/mojom/scanner_feedback_ui.mojom.h" +#include "ash/webui/scanner_feedback_ui/scanner_feedback_browser_context_data.h" +#include "ash/webui/scanner_feedback_ui/scanner_feedback_page_handler.h" #include "ash/webui/scanner_feedback_ui/url_constants.h" +#include "base/check.h" +#include "base/check_deref.h" +#include "base/functional/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/unguessable_token.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_controller.h" #include "content/public/browser/web_ui_data_source.h" +#include "content/public/common/bindings_policy.h" #include "content/public/common/url_constants.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "services/network/public/mojom/content_security_policy.mojom-shared.h" +#include "ui/web_dialogs/web_dialog_ui.h" #include "ui/webui/color_change_listener/color_change_handler.h" #include "ui/webui/resources/cr_components/color_change_listener/color_change_listener.mojom.h" -#include "ui/webui/untrusted_web_ui_controller.h" namespace ash { +namespace { + +constexpr bool HasOverlap(std::string_view prefix, std::string_view suffix) { + for (size_t i = 0; i < suffix.size(); ++i) { + std::string_view truncated_suffix = suffix; + truncated_suffix.remove_suffix(i); + if (prefix.ends_with(truncated_suffix)) { + return true; + } + } + return false; +} + +// `kScannerFeedbackScreenshotPrefix` and `kScannerFeedbackScreenshotSuffix` +// must not have any "overlap", or else +// (path.starts_with(kScannerFeedbackScreenshotPrefix) && +// path.ends_with(kScannerFeedbackScreenshotSuffix)) +// may not necessarily imply that +// (path.size() >= +// kScannerFeedbackScreenshotSuffix.size() + +// kScannerFeedbackScreenshotSuffix.size()) +static_assert(!HasOverlap(kScannerFeedbackScreenshotPrefix, + kScannerFeedbackScreenshotSuffix)); + +// Returns the `base::UnguessableToken` ID for a given screenshot URL path. +std::optional<base::UnguessableToken> GetScreenshotId(std::string_view path) { + if (!path.starts_with(kScannerFeedbackScreenshotPrefix)) { + return std::nullopt; + } + + if (!path.ends_with(kScannerFeedbackScreenshotSuffix)) { + return std::nullopt; + } + + path.remove_prefix(kScannerFeedbackScreenshotPrefix.size()); + path.remove_suffix(kScannerFeedbackScreenshotSuffix.size()); + + return base::UnguessableToken::DeserializeFromString(path); +} + +// Returns whether we should handle a given request, given the path. +bool ShouldHandleRequest(base::WeakPtr<content::BrowserContext> browser_context, + const std::string& path) { + std::optional<base::UnguessableToken> id = GetScreenshotId(path); + if (!id.has_value()) { + return false; + } + + CHECK(browser_context); + ScannerFeedbackInfo* feedback_info = + GetScannerFeedbackInfoForBrowserContext(*browser_context, *id); + + return feedback_info != nullptr; +} + +// Handles the given request and returns the screenshot to the +// `GotDataCallback`. +void HandleRequest(base::WeakPtr<content::BrowserContext> browser_context, + const std::string& path, + content::WebUIDataSource::GotDataCallback callback) { + std::optional<base::UnguessableToken> id = GetScreenshotId(path); + // `GetScreenshotId` is deterministic, so this should always be true as we + // checked it in `ShouldHandleRequest`. + CHECK(id.has_value()); + + CHECK(browser_context); + ScannerFeedbackInfo* feedback_info = + GetScannerFeedbackInfoForBrowserContext(*browser_context, *id); + + // `GetScannerFeedbackInfoForBrowserContext` is _not_ deterministic, but is + // run synchronously after `ShouldHandleRequest` in + // `WebUIDataSourceImpl::StartDataRequest`. + // If this ever changes - for example, it is `PostTask`ed instead, this + // `CHECK` could fail if the `WebUI` is destroyed between + // `ShouldHandleRequest` and `HandleRequest`. + CHECK(feedback_info); + + std::move(callback).Run(feedback_info->screenshot); +} + +} // namespace + ScannerFeedbackUntrustedUIConfig::ScannerFeedbackUntrustedUIConfig() : ChromeOSWebUIConfig(content::kChromeUIUntrustedScheme, kScannerFeedbackUntrustedHost) {} @@ -39,7 +135,17 @@ } ScannerFeedbackUntrustedUI::ScannerFeedbackUntrustedUI(content::WebUI* web_ui) - : ui::UntrustedWebUIController(web_ui) { + : ui::WebDialogUI(web_ui), + page_handler_( + CHECK_DEREF(CHECK_DEREF(CHECK_DEREF(web_ui).GetWebContents()) + .GetBrowserContext())) { + // Emulate `ui::UntrustedWebUIController`. This should never enable bindings. + web_ui->SetBindings(content::BindingsPolicySet()); + + // This should be non-null as it was checked above. + content::BrowserContext* browser_context = + web_ui->GetWebContents()->GetBrowserContext(); + // `content::WebUIDataSource`s are stored on the browser context. If an // existing `content::WebUIDataSource` exists in the browser context for the // given source name, calling `CreateAndAdd` will destroy the previous one. @@ -61,8 +167,7 @@ // sources, so this may change in the future. content::WebUIDataSource* untrusted_source = content::WebUIDataSource::CreateAndAdd( - web_ui->GetWebContents()->GetBrowserContext(), - std::string(kScannerFeedbackUntrustedUrl)); + browser_context, std::string(kScannerFeedbackUntrustedUrl)); untrusted_source->AddResourcePaths(kAshScannerFeedbackUiResources); // We intentionally do not use `SetDefaultResource` here as we do not want to @@ -73,6 +178,10 @@ untrusted_source->OverrideContentSecurityPolicy( network::mojom::CSPDirectiveName::StyleSrc, "style-src-elem 'self' theme;"); + + untrusted_source->SetRequestFilter( + base::BindRepeating(&ShouldHandleRequest, browser_context->GetWeakPtr()), + base::BindRepeating(&HandleRequest, browser_context->GetWeakPtr())); } ScannerFeedbackUntrustedUI::~ScannerFeedbackUntrustedUI() = default; @@ -83,6 +192,11 @@ web_ui()->GetWebContents(), std::move(receiver)); } +void ScannerFeedbackUntrustedUI::BindInterface( + mojo::PendingReceiver<mojom::scanner_feedback_ui::PageHandler> receiver) { + page_handler_.Bind(std::move(receiver)); +} + WEB_UI_CONTROLLER_TYPE_IMPL(ScannerFeedbackUntrustedUI) } // namespace ash
diff --git a/ash/webui/scanner_feedback_ui/scanner_feedback_untrusted_ui.h b/ash/webui/scanner_feedback_ui/scanner_feedback_untrusted_ui.h index f8400e7e..4b4b98f 100644 --- a/ash/webui/scanner_feedback_ui/scanner_feedback_untrusted_ui.h +++ b/ash/webui/scanner_feedback_ui/scanner_feedback_untrusted_ui.h
@@ -8,10 +8,12 @@ #include <memory> #include "ash/webui/common/chrome_os_webui_config.h" +#include "ash/webui/scanner_feedback_ui/mojom/scanner_feedback_ui.mojom-forward.h" +#include "ash/webui/scanner_feedback_ui/scanner_feedback_page_handler.h" #include "content/public/browser/web_ui_controller.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "ui/web_dialogs/web_dialog_ui.h" #include "ui/webui/resources/cr_components/color_change_listener/color_change_listener.mojom-forward.h" -#include "ui/webui/untrusted_web_ui_controller.h" namespace content { class BrowserContext; @@ -35,7 +37,7 @@ bool IsWebUIEnabled(content::BrowserContext* browser_context) override; }; -class ScannerFeedbackUntrustedUI : public ui::UntrustedWebUIController { +class ScannerFeedbackUntrustedUI : public ui::WebDialogUI { public: explicit ScannerFeedbackUntrustedUI(content::WebUI* web_ui); @@ -45,15 +47,22 @@ ~ScannerFeedbackUntrustedUI() override; + ScannerFeedbackPageHandler& page_handler() { return page_handler_; } + void BindInterface( mojo::PendingReceiver<color_change_listener::mojom::PageHandler> receiver); + void BindInterface( + mojo::PendingReceiver<mojom::scanner_feedback_ui::PageHandler> receiver); + private: // The color change handler notifies the WebUI when the color provider // changes. std::unique_ptr<ui::ColorChangeHandler> color_provider_handler_; + ScannerFeedbackPageHandler page_handler_; + WEB_UI_CONTROLLER_TYPE_DECL(); };
diff --git a/ash/webui/scanner_feedback_ui/url_constants.h b/ash/webui/scanner_feedback_ui/url_constants.h index 87a9c4e..d9e0484 100644 --- a/ash/webui/scanner_feedback_ui/url_constants.h +++ b/ash/webui/scanner_feedback_ui/url_constants.h
@@ -13,6 +13,9 @@ "chrome-untrusted://scanner-feedback/"; inline constexpr std::string_view kScannerFeedbackUntrustedHost = "scanner-feedback"; +inline constexpr std::string_view kScannerFeedbackScreenshotPrefix = + "screenshots/"; +inline constexpr std::string_view kScannerFeedbackScreenshotSuffix = ".jpg"; } // namespace ash
diff --git a/ash/webui/settings/public/constants/routes.mojom b/ash/webui/settings/public/constants/routes.mojom index 3cbc7cd..5098203 100644 --- a/ash/webui/settings/public/constants/routes.mojom +++ b/ash/webui/settings/public/constants/routes.mojom
@@ -22,7 +22,7 @@ // https://crbug.com/1074101. Do not reuse. // Note: Value 10 was for deprecated kDateAndTime. Do not reuse. kPrivacyAndSecurity = 11, - kLanguagesAndInput = 12, + // Note: Value 12 was used for deprecated kLanguagesAndInput. Do not reuse. // Note: Value 13 was for deprecated kFiles. Do not reuse. // Note: Value 14 was for deprecated kPrinting. Do not reuse. kAccessibility = 15, @@ -310,7 +310,6 @@ "osPrivacy/privacyHub/geolocation/advanced"; // Languages and Input section. -const string kLanguagesAndInputSectionPath = "osLanguages"; const string kInputMethodOptionsSubpagePath = "osLanguages/inputMethodOptions"; const string kLanguagesSubpagePath = "osLanguages/languages"; const string kInputSubpagePath = "osLanguages/input";
diff --git a/base/check.h b/base/check.h index 08c7ac3..b7605cc 100644 --- a/base/check.h +++ b/base/check.h
@@ -78,44 +78,56 @@ // Takes ownership of `log_message`. explicit CheckError(LogMessage* log_message); + // All instances that take a base::Location should use + // base::Location::CurrentWithoutFunctionName() by default since we + // immediately pass file_name() and line_number() to LogMessage's constructor + // and discard the function_name() anyways. This saves ~23k on the Android + // size bots (as of 2024-12-17) but that's the official build that barely uses + // these for CHECKs. The size gains are believed to be significantly larger on + // developer builds and official+DCHECK where all CHECK failures generate + // logs. + // TODO(pbos): Make all static methods that currently return some version of // CheckError return LogMessage*. - static CheckError Check( - const char* condition, - base::NotFatalUntil fatal_milestone, - const base::Location& location = base::Location::Current()); + static CheckError Check(const char* condition, + base::NotFatalUntil fatal_milestone, + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); // Takes ownership over (free()s after using) `log_message_str`, for use with // CHECK_op macros. - static LogMessage* CheckOp( - char* log_message_str, - base::NotFatalUntil fatal_milestone, - const base::Location& location = base::Location::Current()); + static LogMessage* CheckOp(char* log_message_str, + base::NotFatalUntil fatal_milestone, + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); - static CheckError DCheck( - const char* condition, - const base::Location& location = base::Location::Current()); + static CheckError DCheck(const char* condition, + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); // Takes ownership over (free()s after using) `log_message_str`, for use with // DCHECK_op macros. - static LogMessage* DCheckOp( - char* log_message_str, - const base::Location& location = base::Location::Current()); + static LogMessage* DCheckOp(char* log_message_str, + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); static CheckError DumpWillBeCheck( const char* condition, - const base::Location& location = base::Location::Current()); + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); // Takes ownership over (free()s after using) `log_message_str`, for use with // DUMP_WILL_BE_CHECK_op macros. static LogMessage* DumpWillBeCheckOp( char* log_message_str, - const base::Location& location = base::Location::Current()); + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); - static CheckError DPCheck( - const char* condition, - const base::Location& location = base::Location::Current()); + static CheckError DPCheck(const char* condition, + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); static CheckError NotImplemented( const char* function, - const base::Location& location = base::Location::Current()); + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); // Stream for adding optional details to the error message. std::ostream& stream(); @@ -144,18 +156,21 @@ static CheckNoreturnError Check( const char* condition, - const base::Location& location = base::Location::Current()); + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); // Takes ownership over (free()s after using) `log_message_str`, for use with // CHECK_op macros. - static LogMessage* CheckOp( - char* log_message_str, - const base::Location& location = base::Location::Current()); + static LogMessage* CheckOp(char* log_message_str, + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); static CheckNoreturnError PCheck( const char* condition, - const base::Location& location = base::Location::Current()); + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); static CheckNoreturnError PCheck( - const base::Location& location = base::Location::Current()); + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); }; // Used for NOTREACHED(base::NotFatalUntil) and DUMP_WILL_BE_NOTREACHED(). @@ -163,10 +178,12 @@ public: static NotReachedError NotReached( base::NotFatalUntil fatal_milestone, - const base::Location& location = base::Location::Current()); + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); static NotReachedError DumpWillBeNotReached( - const base::Location& location = base::Location::Current()); + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); NOMERGE NOINLINE NOT_TAIL_CALLED ~NotReachedError(); @@ -178,7 +195,8 @@ class BASE_EXPORT NotReachedNoreturnError : public CheckError { public: explicit NotReachedNoreturnError( - const base::Location& location = base::Location::Current()); + const base::Location& location = + base::Location::CurrentWithoutFunctionName()); [[noreturn]] NOMERGE NOINLINE NOT_TAIL_CALLED ~NotReachedNoreturnError(); };
diff --git a/base/location.cc b/base/location.cc index 917460f..da4356f 100644 --- a/base/location.cc +++ b/base/location.cc
@@ -137,6 +137,13 @@ RETURN_ADDRESS()); } +// static +NOINLINE Location Location::CurrentWithoutFunctionName(const char* file_name, + int line_number) { + return Location(nullptr, file_name + kStrippedPrefixLength, line_number, + RETURN_ADDRESS()); +} + //------------------------------------------------------------------------------ NOINLINE const void* GetProgramCounter() { return RETURN_ADDRESS();
diff --git a/base/location.h b/base/location.h index e9bc21a..f324c40 100644 --- a/base/location.h +++ b/base/location.h
@@ -79,6 +79,10 @@ const char* file_name = __builtin_FILE(), int line_number = __builtin_LINE()); + static Location CurrentWithoutFunctionName( + const char* file_name = __builtin_FILE(), + int line_number = __builtin_LINE()); + private: // Only initializes the file name and program counter, the source information // will be null for the strings, and -1 for the line number.
diff --git a/base/memory/discardable_shared_memory.cc b/base/memory/discardable_shared_memory.cc index ab04ee51..68be54a 100644 --- a/base/memory/discardable_shared_memory.cc +++ b/base/memory/discardable_shared_memory.cc
@@ -112,9 +112,14 @@ }; // Shared state is stored at offset 0 in shared memory segments. -SharedState* SharedStateFromSharedMemory( +const SharedState* SharedStateFromSharedMemory( const WritableSharedMemoryMapping& shared_memory) { DCHECK(shared_memory.IsValid()); + return shared_memory.GetMemoryAs<const SharedState>(); +} +SharedState* SharedStateFromSharedMemory( + WritableSharedMemoryMapping& shared_memory) { + DCHECK(shared_memory.IsValid()); return shared_memory.GetMemoryAs<SharedState>(); } @@ -354,12 +359,22 @@ last_known_usage_ = current_time; } -span<uint8_t> DiscardableSharedMemory::memory() const { +span<uint8_t> DiscardableSharedMemory::memory() { return shared_memory_mapping_.GetMemoryAsSpan<uint8_t>().subspan( AlignToPageSize(sizeof(SharedState))); } -span<uint8_t> DiscardableSharedMemory::mapped_memory() const { +span<const uint8_t> DiscardableSharedMemory::memory() const { + return shared_memory_mapping_.GetMemoryAsSpan<const uint8_t>().subspan( + AlignToPageSize(sizeof(SharedState))); +} + +span<uint8_t> DiscardableSharedMemory::mapped_memory() { + return shared_memory_mapping_.mapped_memory().subspan( + AlignToPageSize(sizeof(SharedState))); +} + +span<const uint8_t> DiscardableSharedMemory::mapped_memory() const { return shared_memory_mapping_.mapped_memory().subspan( AlignToPageSize(sizeof(SharedState))); }
diff --git a/base/memory/discardable_shared_memory.h b/base/memory/discardable_shared_memory.h index 7ed84f7..4571b3c1 100644 --- a/base/memory/discardable_shared_memory.h +++ b/base/memory/discardable_shared_memory.h
@@ -125,7 +125,8 @@ // requested. The actual mapped memory may be larger due to system alignment // requirements. See `SharedMemoryMapping::size()` vs // `SharedMemoryMapping::mapped_size()`. - span<uint8_t> memory() const; + span<uint8_t> memory(); + span<const uint8_t> memory() const; // Returns the last known usage time for DiscardableSharedMemory object. This // may be earlier than the "true" usage time when memory has been used by a @@ -177,7 +178,8 @@ // header. This may be larger than the region exposed through `memory()` due // to platform alignment requirements. Discardable memory must have been // mapped via Map(). - span<uint8_t> mapped_memory() const; + span<uint8_t> mapped_memory(); + span<const uint8_t> mapped_memory() const; // LockPages/UnlockPages are platform-native discardable page management // helper functions. Both expect |offset| to be specified relative to the
diff --git a/base/memory/shared_memory_mapping.h b/base/memory/shared_memory_mapping.h index ed18aa5..b45619d 100644 --- a/base/memory/shared_memory_mapping.h +++ b/base/memory/shared_memory_mapping.h
@@ -6,6 +6,7 @@ #define BASE_MEMORY_SHARED_MEMORY_MAPPING_H_ #include <cstddef> +#include <utility> #include "base/base_export.h" #include "base/check.h" @@ -142,11 +143,9 @@ template <typename T> requires subtle::AllowedOverSharedMemory<T> const T* GetMemoryAs() const { - if (!IsValid()) - return nullptr; - if (sizeof(T) > size()) - return nullptr; - return reinterpret_cast<const T*>(mapped_memory().data()); + return (IsValid() && sizeof(T) <= size()) + ? reinterpret_cast<const T*>(mapped_memory().data()) + : nullptr; } // Returns a span of const T. The number of elements is autodeduced from the @@ -158,10 +157,8 @@ template <typename T> requires subtle::AllowedOverSharedMemory<T> span<const T> GetMemoryAsSpan() const { - if (!IsValid()) - return span<const T>(); - size_t count = size() / sizeof(T); - return GetMemoryAsSpan<T>(count); + return IsValid() ? GetMemoryAsSpan<const T>(size() / sizeof(T)) + : span<const T>(); } // Returns a span of const T with |count| elements if the mapping is valid and @@ -170,16 +167,14 @@ template <typename T> requires subtle::AllowedOverSharedMemory<T> span<const T> GetMemoryAsSpan(size_t count) const { - if (!IsValid()) - return span<const T>(); - if (size() / sizeof(T) < count) - return span<const T>(); + const T* const ptr = GetMemoryAs<const T>(); // SAFETY: There is an internal invariant (enforced in the constructors) // that `size() <= mapped_memory().size()`. `count` is the number of objects - // of type T that fit within size(), so the pointer given to span() points - // to at least that many T objects. - return UNSAFE_BUFFERS( - span(reinterpret_cast<const T*>(mapped_memory().data()), count)); + // of type `T` that fit within `size()`, so the pointer given to `span()` + // points to at least that many `T` objects. + return (ptr && count <= size() / sizeof(T)) + ? UNSAFE_BUFFERS(span(ptr, count)) + : span<const T>(); } private: @@ -249,12 +244,15 @@ // enough to contain a T, or nullptr otherwise. template <typename T> requires subtle::AllowedOverSharedMemory<T> - T* GetMemoryAs() const { - if (!IsValid()) - return nullptr; - if (sizeof(T) > size()) - return nullptr; - return reinterpret_cast<T*>(mapped_memory().data()); + const T* GetMemoryAs() const { + return (IsValid() && sizeof(T) <= size()) + ? reinterpret_cast<T*>(mapped_memory().data()) + : nullptr; + } + template <typename T> + requires(!std::is_const_v<T> && subtle::AllowedOverSharedMemory<T>) + T* GetMemoryAs() { + return const_cast<T*>(std::as_const(*this).GetMemoryAs<const T>()); } // Returns a span of T. The number of elements is autodeduced from the size of @@ -264,11 +262,14 @@ // The first element, if any, is guaranteed to be page-aligned. template <typename T> requires subtle::AllowedOverSharedMemory<T> - span<T> GetMemoryAsSpan() const { - if (!IsValid()) - return span<T>(); - size_t count = size() / sizeof(T); - return GetMemoryAsSpan<T>(count); + span<const T> GetMemoryAsSpan() const { + return IsValid() ? GetMemoryAsSpan<const T>(size() / sizeof(T)) + : span<const T>(); + } + template <typename T> + requires(!std::is_const_v<T> && subtle::AllowedOverSharedMemory<T>) + span<T> GetMemoryAsSpan() { + return IsValid() ? GetMemoryAsSpan<T>(size() / sizeof(T)) : span<T>(); } // Returns a span of T with |count| elements if the mapping is valid and large @@ -276,17 +277,21 @@ // element, if any, is guaranteed to be page-aligned. template <typename T> requires subtle::AllowedOverSharedMemory<T> - span<T> GetMemoryAsSpan(size_t count) const { - if (!IsValid()) - return span<T>(); - if (size() / sizeof(T) < count) - return span<T>(); - // SAFETY: There is an internal invariant (enforced in the constructors) - // that `size() <= mapped_memory().size()`. `count` is the number of objects - // of type T that fit within size(), so the pointer given to span() points - // to at least that many T objects. - return UNSAFE_BUFFERS( - span(reinterpret_cast<T*>(mapped_memory().data()), count)); + span<const T> GetMemoryAsSpan(size_t count) const { + const T* const ptr = GetMemoryAs<const T>(); + // SAFETY: As in the ReadOnly code above. + return (ptr && count <= size() / sizeof(T)) + ? UNSAFE_BUFFERS(span(ptr, count)) + : span<const T>(); + } + template <typename T> + requires(!std::is_const_v<T> && subtle::AllowedOverSharedMemory<T>) + span<T> GetMemoryAsSpan(size_t count) { + T* const ptr = GetMemoryAs<T>(); + // SAFETY: As in the ReadOnly code above. + return (ptr && count <= size() / sizeof(T)) + ? UNSAFE_BUFFERS(span(ptr, count)) + : span<T>(); } private:
diff --git a/base/memory/shared_memory_mapping_unittest.cc b/base/memory/shared_memory_mapping_unittest.cc index 31dd519..8eebf26 100644 --- a/base/memory/shared_memory_mapping_unittest.cc +++ b/base/memory/shared_memory_mapping_unittest.cc
@@ -8,6 +8,8 @@ #include <atomic> #include <limits> +#include <memory> +#include <type_traits> #include "base/containers/span.h" #include "base/memory/read_only_shared_memory_region.h" @@ -19,6 +21,11 @@ namespace base { +namespace { +template <typename T> +using ElementType = std::pointer_traits<T>::element_type; +} + class SharedMemoryMappingTest : public ::testing::Test { protected: void CreateMapping(size_t size) { @@ -117,6 +124,86 @@ EXPECT_TRUE(read_mapping_.GetMemoryAsSpan<uint8_t>(0).empty()); } +TEST_F(SharedMemoryMappingTest, ConstCorrectness) { + // All memory accessors for read-only mappings should return const T. + ReadOnlySharedMemoryMapping ro; + + static_assert(std::is_const_v<ElementType<decltype(ro.data())>>); + static_assert(std::is_const_v<ElementType<decltype(ro.begin())>>); + static_assert(std::is_const_v<ElementType<decltype(ro.end())>>); + static_assert(std::is_const_v<ElementType<decltype(ro.memory())>>); + static_assert( + std::is_const_v<ElementType<decltype(ro.GetMemoryAs<uint8_t>())>>); + static_assert( + std::is_const_v<ElementType<decltype(ro.GetMemoryAs<const uint8_t>())>>); + static_assert( + std::is_const_v<decltype(ro.GetMemoryAsSpan<uint8_t>())::element_type>); + static_assert(std::is_const_v< + decltype(ro.GetMemoryAsSpan<const uint8_t>())::element_type>); + static_assert( + std::is_const_v<decltype(ro.GetMemoryAsSpan<uint8_t>(1))::element_type>); + static_assert(std::is_const_v<decltype(ro.GetMemoryAsSpan<const uint8_t>( + 1))::element_type>); + + // Making the mapping const should still allow all accessors to be called. + const ReadOnlySharedMemoryMapping cro; + static_assert(std::is_const_v<ElementType<decltype(cro.data())>>); + static_assert(std::is_const_v<ElementType<decltype(cro.begin())>>); + static_assert(std::is_const_v<ElementType<decltype(cro.end())>>); + static_assert(std::is_const_v<ElementType<decltype(cro.memory())>>); + static_assert( + std::is_const_v<ElementType<decltype(cro.GetMemoryAs<uint8_t>())>>); + static_assert( + std::is_const_v<ElementType<decltype(cro.GetMemoryAs<const uint8_t>())>>); + static_assert( + std::is_const_v<decltype(cro.GetMemoryAsSpan<uint8_t>())::element_type>); + static_assert(std::is_const_v< + decltype(cro.GetMemoryAsSpan<const uint8_t>())::element_type>); + static_assert( + std::is_const_v<decltype(cro.GetMemoryAsSpan<uint8_t>(1))::element_type>); + static_assert(std::is_const_v<decltype(cro.GetMemoryAsSpan<const uint8_t>( + 1))::element_type>); + + // Accessors for writable mappings should be non-const unless requested. + WritableSharedMemoryMapping rw; + static_assert(!std::is_const_v<ElementType<decltype(rw.data())>>); + static_assert(!std::is_const_v<ElementType<decltype(rw.begin())>>); + static_assert(!std::is_const_v<ElementType<decltype(rw.end())>>); + static_assert(!std::is_const_v<ElementType<decltype(rw.memory())>>); + static_assert( + !std::is_const_v<ElementType<decltype(rw.GetMemoryAs<uint8_t>())>>); + static_assert( + std::is_const_v<ElementType<decltype(rw.GetMemoryAs<const uint8_t>())>>); + static_assert( + !std::is_const_v<decltype(rw.GetMemoryAsSpan<uint8_t>())::element_type>); + static_assert(std::is_const_v< + decltype(rw.GetMemoryAsSpan<const uint8_t>())::element_type>); + static_assert( + !std::is_const_v<decltype(rw.GetMemoryAsSpan<uint8_t>(1))::element_type>); + static_assert(std::is_const_v<decltype(rw.GetMemoryAsSpan<const uint8_t>( + 1))::element_type>); + + // Making the mapping const should still allow all accessors to be called, but + // they should now return const T. + const WritableSharedMemoryMapping crw; + static_assert(std::is_const_v<ElementType<decltype(crw.data())>>); + static_assert(std::is_const_v<ElementType<decltype(crw.begin())>>); + static_assert(std::is_const_v<ElementType<decltype(crw.end())>>); + static_assert(std::is_const_v<ElementType<decltype(crw.memory())>>); + static_assert( + std::is_const_v<ElementType<decltype(crw.GetMemoryAs<uint8_t>())>>); + static_assert( + std::is_const_v<ElementType<decltype(crw.GetMemoryAs<const uint8_t>())>>); + static_assert( + std::is_const_v<decltype(crw.GetMemoryAsSpan<uint8_t>())::element_type>); + static_assert(std::is_const_v< + decltype(crw.GetMemoryAsSpan<const uint8_t>())::element_type>); + static_assert( + std::is_const_v<decltype(crw.GetMemoryAsSpan<uint8_t>(1))::element_type>); + static_assert(std::is_const_v<decltype(crw.GetMemoryAsSpan<const uint8_t>( + 1))::element_type>); +} + TEST_F(SharedMemoryMappingTest, TooBigScalar) { CreateMapping(sizeof(uint8_t));
diff --git a/base/memory/shared_memory_safety_checker.h b/base/memory/shared_memory_safety_checker.h index 51333ab3..ead0313 100644 --- a/base/memory/shared_memory_safety_checker.h +++ b/base/memory/shared_memory_safety_checker.h
@@ -58,7 +58,8 @@ }; template <typename T> -concept AllowedOverSharedMemory = SharedMemorySafetyChecker<T>::kIsAllowed; +concept AllowedOverSharedMemory = + SharedMemorySafetyChecker<std::remove_cvref_t<T>>::kIsAllowed; // Convenience alias for atomics that are safe to share across memory spaces. template <typename T>
diff --git a/base/memory/structured_shared_memory.h b/base/memory/structured_shared_memory.h index 12011c2b..4aefbee 100644 --- a/base/memory/structured_shared_memory.h +++ b/base/memory/structured_shared_memory.h
@@ -113,7 +113,7 @@ SharedMemoryMapper* mapper = nullptr); // Returns a pointer to the object stored in the mapped region. - T* WritablePtr() const { + T* WritablePtr() { CHECK(writable_mapping_.IsValid()); return writable_mapping_.GetMemoryAs<T>(); } @@ -123,7 +123,7 @@ } // Returns a reference to the object stored in the mapped region. - T& WritableRef() const LIFETIME_BOUND { + T& WritableRef() LIFETIME_BOUND { T* ptr = WritablePtr(); CHECK(ptr); return *ptr;
diff --git a/base/memory/unsafe_shared_memory_pool.h b/base/memory/unsafe_shared_memory_pool.h index e76b5678..2ba52f9 100644 --- a/base/memory/unsafe_shared_memory_pool.h +++ b/base/memory/unsafe_shared_memory_pool.h
@@ -42,6 +42,11 @@ Handle& operator=(const Handle&) = delete; const UnsafeSharedMemoryRegion& GetRegion() const LIFETIME_BOUND; + + WritableSharedMemoryMapping& GetMapping() LIFETIME_BOUND { + return const_cast<WritableSharedMemoryMapping&>( + std::as_const(*this).GetMapping()); + } const WritableSharedMemoryMapping& GetMapping() const LIFETIME_BOUND; private:
diff --git a/base/threading/hang_watcher.cc b/base/threading/hang_watcher.cc index 7c46ca54..b9fb189e 100644 --- a/base/threading/hang_watcher.cc +++ b/base/threading/hang_watcher.cc
@@ -765,12 +765,6 @@ hung_counts_per_thread_type[hang_count_index] = 0; } -#if BUILDFLAG(ENABLE_BASE_TRACING) - const PlatformThreadId thread_id = watch_state.get()->GetThreadID(); - const auto track = perfetto::Track::FromPointer( - this, perfetto::ThreadTrack::ForThread(thread_id)); -#endif - // Only copy hung threads. if (deadline <= now) { ++hung_counts_per_thread_type[hang_count_index]; @@ -784,11 +778,12 @@ // Emit trace events for monitored threads. if (ThreadTypeLoggingLevelGreaterOrEqual(watch_state.get()->thread_type(), LoggingLevel::kUmaOnly)) { - if (!watch_state.get()->TraceEventStarted()) { - TRACE_EVENT_BEGIN("latency", "HangWatcher::ThreadHung", track, - deadline - kMonitoringPeriod, "id", thread_id); - watch_state.get()->MarkTraceEventStarted(true); - } + const PlatformThreadId thread_id = watch_state.get()->GetThreadID(); + const auto track = perfetto::Track::FromPointer( + this, perfetto::ThreadTrack::ForThread(thread_id)); + TRACE_EVENT_BEGIN("latency", "HangWatcher::ThreadHung", track, + deadline); + TRACE_EVENT_END("latency", track, now); } #endif @@ -807,13 +802,6 @@ } else { all_threads_marked = false; } - } else { // For threads that are not hung. -#if BUILDFLAG(ENABLE_BASE_TRACING) - if (watch_state.get()->TraceEventStarted()) { - TRACE_EVENT_END("latency", track, now - kMonitoringPeriod); - watch_state.get()->MarkTraceEventStarted(false); - } -#endif } } @@ -1041,17 +1029,6 @@ // Thread should be registered to get unregistered. CHECK(it != watch_states_.end(), base::NotFatalUntil::M125); - // If a trace event was started it will never be finished if the thread - // unregisters so finish it now. -#if BUILDFLAG(ENABLE_BASE_TRACING) - const internal::HangWatchState& watch_state = *(it->get()); - if (watch_state.TraceEventStarted()) { - const auto track = perfetto::Track::FromPointer( - this, perfetto::ThreadTrack::ForThread(watch_state.GetThreadID())); - TRACE_EVENT_END("latency", track, base::TimeTicks::Now()); - } -#endif - watch_states_.erase(it); } @@ -1339,14 +1316,6 @@ #endif } -bool HangWatchState::TraceEventStarted() const { - return trace_event_started_; -} - -void HangWatchState::MarkTraceEventStarted(bool capturing) { - trace_event_started_ = capturing; -} - } // namespace internal } // namespace base
diff --git a/base/threading/hang_watcher.h b/base/threading/hang_watcher.h index 8220c67..a9802250 100644 --- a/base/threading/hang_watcher.h +++ b/base/threading/hang_watcher.h
@@ -651,12 +651,6 @@ // Returns the type of the thread under watch. HangWatcher::ThreadType thread_type() const { return thread_type_; } - // Functions used to coordinate capture of the trace event per hung thread. - // These functions need to evolve if HangWatcher starts logging more than one - // trace event per hung thread. - bool TraceEventStarted() const; - void MarkTraceEventStarted(bool capturing); - private: // The thread that creates the instance should be the class that updates // the deadline. @@ -686,8 +680,6 @@ // The type of the thread under watch. const HangWatcher::ThreadType thread_type_; - bool trace_event_started_ = false; - #if DCHECK_IS_ON() // Used to keep track of the current WatchHangsInScope and detect improper // usage. Scopes should always be destructed in reverse order from the one
diff --git a/base/tracing/stdlib/chrome/input.sql b/base/tracing/stdlib/chrome/input.sql index 75db2b1..4eeaccc 100644 --- a/base/tracing/stdlib/chrome/input.sql +++ b/base/tracing/stdlib/chrome/input.sql
@@ -148,11 +148,15 @@ ( ( SELECT slice_id AS id, * - FROM scroll_update_steps), + FROM scroll_update_steps + WHERE dur > 0 + ), ( SELECT slice_id AS id, * FROM chrome_input_pipeline_steps step - WHERE step = 'STEP_TOUCH_EVENT_HANDLED') + WHERE step = 'STEP_TOUCH_EVENT_HANDLED' + AND dur > 0 + ) ), (utid) ) AS ii @@ -177,11 +181,16 @@ ( ( SELECT slice_id AS id, * - FROM scroll_update_steps), + FROM scroll_update_steps + WHERE dur > 0 + ), ( SELECT slice_id AS id, * FROM chrome_input_pipeline_steps step - WHERE step = 'STEP_SEND_INPUT_EVENT_UI' AND input_type = 'TOUCH_MOVE_EVENT') + WHERE step = 'STEP_SEND_INPUT_EVENT_UI' + AND input_type = 'TOUCH_MOVE_EVENT' + AND dur > 0 + ) ), (utid) ) AS ii
diff --git a/cc/paint/display_item_list.cc b/cc/paint/display_item_list.cc index b7c796c..51d84e6e 100644 --- a/cc/paint/display_item_list.cc +++ b/cc/paint/display_item_list.cc
@@ -110,7 +110,7 @@ size_t rastered_op_count = 0; for (PaintOpBuffer::PlaybackFoldingIterator it(paint_op_buffer_, &offsets); it; ++it) { - rastered_op_count += 1 + it->AdditionalOpCount(); + rastered_op_count += 1 + PaintOp::OpAdditionalOpCount(*it); } TRACE_EVENT_END1("cc", "DisplayItemList::Raster", "rastered_op_count", rastered_op_count); @@ -161,13 +161,8 @@ size_t index = 0; for (const PaintOp& op : PaintOpBuffer::OffsetIterator(paint_op_buffer_, offsets)) { - if (op.GetType() == PaintOpType::kDrawTextBlob || - // Don't walk into the record because the visual rect is already the - // bounding box of the sub paint operations. This works for most paint - // results for text generated by blink. - (op.GetType() == PaintOpType::kDrawRecord && - static_cast<const DrawRecordOp&>(op).record.has_draw_text_ops())) { - area += static_cast<double>(rects[index].width()) * rects[index].height(); + if (PaintOp::OpHasDrawTextOps(op)) { + area += rects[index].size().Area64(); } ++index; }
diff --git a/cc/paint/paint_op.cc b/cc/paint/paint_op.cc index 99d1bd9..a16449b 100644 --- a/cc/paint/paint_op.cc +++ b/cc/paint/paint_op.cc
@@ -241,7 +241,8 @@ Rasterizer<T, T::kHasPaintFlags>::Raster(static_cast<const T*>(op), \ canvas, params); \ }, -static const RasterFunction g_raster_functions[kNumOpTypes] = {TYPES(M)}; +constexpr std::array<RasterFunction, kNumOpTypes> g_raster_functions = { + TYPES(M)}; #undef M using RasterWithFlagsFunction = void (*)(const PaintOp* op, @@ -254,8 +255,8 @@ Rasterizer<T, T::kHasPaintFlags>::RasterWithFlags( \ static_cast<const T*>(op), flags, canvas, params); \ }, -static const RasterWithFlagsFunction - g_raster_with_flags_functions[kNumOpTypes] = {TYPES(M)}; +constexpr std::array<RasterWithFlagsFunction, kNumOpTypes> + g_raster_with_flags_functions = {TYPES(M)}; #undef M using SerializeFunction = void (*)(const PaintOp& op, @@ -278,7 +279,8 @@ op_t.Serialize(writer, flags_to_serialize, current_ctm, original_ctm); } #define M(T) &Serialize<T>, -static const SerializeFunction g_serialize_functions[kNumOpTypes] = {TYPES(M)}; +constexpr std::array<SerializeFunction, kNumOpTypes> g_serialize_functions = { + TYPES(M)}; #undef M using DeserializeFunction = PaintOp* (*)(PaintOpReader& reader, @@ -298,8 +300,8 @@ return op; } #define M(T) &Deserialize<T>, -static const DeserializeFunction g_deserialize_functions[kNumOpTypes] = { - TYPES(M)}; +constexpr std::array<DeserializeFunction, kNumOpTypes> g_deserialize_functions = + {TYPES(M)}; #undef M using AreEqualForTestingFunction = bool (*)(const PaintOp&, const PaintOp&); @@ -309,8 +311,8 @@ static_cast<const T&>(b)); } #define M(T) &AreEqualForTesting<T>, -static const AreEqualForTestingFunction - g_equal_for_testing_functions[kNumOpTypes] = {TYPES(M)}; +constexpr std::array<AreEqualForTestingFunction, kNumOpTypes> + g_equal_for_testing_functions = {TYPES(M)}; #undef M // Most state ops (matrix, clip, save, restore) have a trivial destructor. @@ -321,7 +323,8 @@ !std::is_trivially_destructible<T>::value \ ? [](PaintOp* op) { static_cast<T*>(op)->~T(); } \ : static_cast<VoidFunction>(nullptr), -static const VoidFunction g_destructor_functions[kNumOpTypes] = {TYPES(M)}; +constexpr std::array<VoidFunction, kNumOpTypes> g_destructor_functions = { + TYPES(M)}; #undef M #define M(T) \ @@ -341,21 +344,23 @@ [](PaintOpBuffer* buffer, const PaintOp* op) { \ buffer->AnalyzeAddedOp(static_cast<const T*>(op)); \ }, -static const AnalyzeOpFunc g_analyze_op_functions[kNumOpTypes] = {TYPES(M)}; +constexpr std::array<AnalyzeOpFunc, kNumOpTypes> g_analyze_op_functions = { + TYPES(M)}; #undef M } // namespace #define M(T) PaintOpBuffer::ComputeOpAlignedSize<T>(), -uint16_t PaintOp::g_type_to_aligned_size[kNumOpTypes] = {TYPES(M)}; +const std::array<uint16_t, kNumOpTypes> PaintOp::g_type_to_aligned_size = { + TYPES(M)}; #undef M #define M(T) T::kIsDrawOp, -bool PaintOp::g_is_draw_op[kNumOpTypes] = {TYPES(M)}; +const std::array<bool, kNumOpTypes> PaintOp::g_is_draw_op = {TYPES(M)}; #undef M #define M(T) T::kHasPaintFlags, -bool PaintOp::g_has_paint_flags[kNumOpTypes] = {TYPES(M)}; +const std::array<bool, kNumOpTypes> PaintOp::g_has_paint_flags = {TYPES(M)}; #undef M const SkRect PaintOp::kUnsetRect = {SK_ScalarInfinity, 0, 0, 0}; @@ -402,6 +407,28 @@ } } +bool OpHasDrawTextOpsImpl(const PaintOp& op) { + switch (op.GetType()) { +#define M(T) \ + case T::kType: \ + return static_cast<const T&>(op).HasDrawTextOps(); + + TYPES(M) +#undef M + } +} + +size_t OpAdditionalOpCountImpl(const PaintOp& op) { + switch (op.GetType()) { +#define M(T) \ + case T::kType: \ + return static_cast<const T&>(op).AdditionalOpCount(); + + TYPES(M) +#undef M + } +} + #undef TYPES std::ostream& operator<<(std::ostream& os, PaintOpType type) { @@ -2320,6 +2347,16 @@ return OpHasDiscardableImagesImpl(op); } +// static +bool PaintOp::OpHasDrawTextOps(const PaintOp& op) { + return OpHasDrawTextOpsImpl(op); +} + +// static +size_t PaintOp::OpAdditionalOpCount(const PaintOp& op) { + return OpAdditionalOpCountImpl(op); +} + void PaintOp::DestroyThis() { auto func = g_destructor_functions[type]; if (func) @@ -2444,22 +2481,22 @@ return has_discardable_images; } -AnnotateOp::AnnotateOp() : PaintOp(kType) {} +AnnotateOp::AnnotateOp() : PaintOpBaseInternal(kType) {} AnnotateOp::AnnotateOp(PaintCanvas::AnnotationType annotation_type, const SkRect& rect, sk_sp<SkData> data) - : PaintOp(kType), + : PaintOpBaseInternal(kType), annotation_type(annotation_type), rect(rect), data(std::move(data)) {} AnnotateOp::~AnnotateOp() = default; -DrawImageOp::DrawImageOp() : PaintOpWithFlags(kType) {} +DrawImageOp::DrawImageOp() : PaintOpWithFlagsBaseInternal(kType) {} DrawImageOp::DrawImageOp(const PaintImage& image, SkScalar left, SkScalar top) - : PaintOpWithFlags(kType, PaintFlags()), + : PaintOpWithFlagsBaseInternal(kType, PaintFlags()), image(image), left(left), top(top) {} @@ -2469,7 +2506,7 @@ SkScalar top, const SkSamplingOptions& sampling, const PaintFlags* flags) - : PaintOpWithFlags(kType, flags ? *flags : PaintFlags()), + : PaintOpWithFlagsBaseInternal(kType, flags ? *flags : PaintFlags()), image(image), left(left), top(top), @@ -2486,13 +2523,13 @@ DrawImageOp::~DrawImageOp() = default; -DrawImageRectOp::DrawImageRectOp() : PaintOpWithFlags(kType) {} +DrawImageRectOp::DrawImageRectOp() : PaintOpWithFlagsBaseInternal(kType) {} DrawImageRectOp::DrawImageRectOp(const PaintImage& image, const SkRect& src, const SkRect& dst, SkCanvas::SrcRectConstraint constraint) - : PaintOpWithFlags(kType, PaintFlags()), + : PaintOpWithFlagsBaseInternal(kType, PaintFlags()), image(image), src(src), dst(dst), @@ -2504,7 +2541,7 @@ const SkSamplingOptions& sampling, const PaintFlags* flags, SkCanvas::SrcRectConstraint constraint) - : PaintOpWithFlags(kType, flags ? *flags : PaintFlags()), + : PaintOpWithFlagsBaseInternal(kType, flags ? *flags : PaintFlags()), image(image), src(src), dst(dst), @@ -2523,7 +2560,9 @@ DrawImageRectOp::~DrawImageRectOp() = default; DrawRecordOp::DrawRecordOp(PaintRecord record, bool local_ctm) - : PaintOp(kType), record(std::move(record)), local_ctm(local_ctm) {} + : PaintOpBaseInternal(kType), + record(std::move(record)), + local_ctm(local_ctm) {} DrawRecordOp::~DrawRecordOp() = default; @@ -2538,7 +2577,7 @@ DrawScrollingContentsOp::DrawScrollingContentsOp( ElementId scroll_element_id, scoped_refptr<DisplayItemList> display_item_list) - : PaintOp(kType), + : PaintOpBaseInternal(kType), scroll_element_id(scroll_element_id), display_item_list(std::move(display_item_list)) {} @@ -2552,14 +2591,14 @@ return display_item_list->TotalOpCount(); } -DrawVerticesOp::DrawVerticesOp() : PaintOpWithFlags(kType) {} +DrawVerticesOp::DrawVerticesOp() : PaintOpWithFlagsBaseInternal(kType) {} DrawVerticesOp::DrawVerticesOp( scoped_refptr<RefCountedBuffer<SkPoint>> vertices, scoped_refptr<RefCountedBuffer<SkPoint>> uvs, scoped_refptr<RefCountedBuffer<uint16_t>> indices, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), + : PaintOpWithFlagsBaseInternal(kType, flags), vertices(std::move(vertices)), uvs(std::move(uvs)), indices(std::move(indices)) {} @@ -2572,7 +2611,7 @@ SkottieFrameDataMap images, const SkottieColorMap& color_map, SkottieTextPropertyValueMap text_map) - : PaintOp(kType), + : PaintOpBaseInternal(kType), skottie(std::move(skottie)), dst(dst), t(t), @@ -2580,7 +2619,7 @@ color_map(color_map), text_map(std::move(text_map)) {} -DrawSkottieOp::DrawSkottieOp() : PaintOp(kType) {} +DrawSkottieOp::DrawSkottieOp() : PaintOpBaseInternal(kType) {} DrawSkottieOp::~DrawSkottieOp() = default; @@ -2598,20 +2637,23 @@ return true; } -DrawTextBlobOp::DrawTextBlobOp() : PaintOpWithFlags(kType) {} +DrawTextBlobOp::DrawTextBlobOp() : PaintOpWithFlagsBaseInternal(kType) {} DrawTextBlobOp::DrawTextBlobOp(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), blob(std::move(blob)), x(x), y(y) {} + : PaintOpWithFlagsBaseInternal(kType, flags), + blob(std::move(blob)), + x(x), + y(y) {} DrawTextBlobOp::DrawTextBlobOp(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y, NodeId node_id, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), + : PaintOpWithFlagsBaseInternal(kType, flags), blob(std::move(blob)), x(x), y(y), @@ -2619,19 +2661,21 @@ DrawTextBlobOp::~DrawTextBlobOp() = default; -DrawSlugOp::DrawSlugOp() : PaintOpWithFlags(kType) {} +DrawSlugOp::DrawSlugOp() : PaintOpWithFlagsBaseInternal(kType) {} DrawSlugOp::DrawSlugOp(sk_sp<sktext::gpu::Slug> slug, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), slug(std::move(slug)) {} + : PaintOpWithFlagsBaseInternal(kType, flags), slug(std::move(slug)) {} DrawSlugOp::~DrawSlugOp() = default; SaveLayerFiltersOp::SaveLayerFiltersOp( base::span<const sk_sp<PaintFilter>> filters, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), filters(filters.begin(), filters.end()) {} + : PaintOpWithFlagsBaseInternal(kType, flags), + filters(filters.begin(), filters.end()) {} -SaveLayerFiltersOp::SaveLayerFiltersOp() : PaintOpWithFlags(kType) {} +SaveLayerFiltersOp::SaveLayerFiltersOp() + : PaintOpWithFlagsBaseInternal(kType) {} SaveLayerFiltersOp::~SaveLayerFiltersOp() = default;
diff --git a/cc/paint/paint_op.h b/cc/paint/paint_op.h index 31c9b4c..c5c0a454 100644 --- a/cc/paint/paint_op.h +++ b/cc/paint/paint_op.h
@@ -130,13 +130,18 @@ class CC_PAINT_EXPORT PaintOp { public: + PaintOp(const PaintOp&) = delete; + PaintOp& operator=(const PaintOp&) = delete; + + // Run the destructor for the derived op type. Ops are usually contained in + // memory buffers and so don't have their destructors run automatically. + void DestroyThis(); + uint8_t type; using SerializeOptions = PaintOpBuffer::SerializeOptions; using DeserializeOptions = PaintOpBuffer::DeserializeOptions; - explicit PaintOp(PaintOpType type) : type(static_cast<uint8_t>(type)) {} - PaintOpType GetType() const { return static_cast<PaintOpType>(type); } // Subclasses should provide a static Raster() method which is called from @@ -212,12 +217,36 @@ // generated images. static bool OpHasDiscardableImages(const PaintOp& op); - // Gets the maximum content color usage of all images in this PaintOp. - gfx::ContentColorUsage GetContentColorUsage() const; + // Returns true if the op contains any draw text operations. + static bool OpHasDrawTextOps(const PaintOp& op); + + static size_t OpAdditionalOpCount(const PaintOp& op); // Returns true if the given op type has PaintFlags. static bool TypeHasFlags(PaintOpType type); + // kDrawColor is more restrictive on the blend modes that can be used. + static bool IsValidDrawColorSkBlendMode(SkBlendMode mode) { + return static_cast<uint32_t>(mode) <= + static_cast<uint32_t>(SkBlendMode::kLastCoeffMode); + } + + // PaintFlags can have more complex blend modes than kDrawColor. + static bool IsValidPaintFlagsSkBlendMode(SkBlendMode mode) { + return static_cast<uint32_t>(mode) <= + static_cast<uint32_t>(SkBlendMode::kLastMode); + } + + static constexpr size_t kNumOpTypes = + static_cast<size_t>(PaintOpType::kLastPaintOpType) + 1; + + static constexpr bool kIsDrawOp = false; + static constexpr bool kHasPaintFlags = false; + + protected: + explicit PaintOp(PaintOpType type) : type(static_cast<uint8_t>(type)) {} + ~PaintOp() = default; + int CountSlowPaths() const { return 0; } int CountSlowPathsFromFlags() const { return 0; } @@ -247,22 +276,6 @@ // Returns the number of ops in referenced sub records and display lists. size_t AdditionalOpCount() const { return 0; } - // Run the destructor for the derived op type. Ops are usually contained in - // memory buffers and so don't have their destructors run automatically. - void DestroyThis(); - - // kDrawColor is more restrictive on the blend modes that can be used. - static bool IsValidDrawColorSkBlendMode(SkBlendMode mode) { - return static_cast<uint32_t>(mode) <= - static_cast<uint32_t>(SkBlendMode::kLastCoeffMode); - } - - // PaintFlags can have more complex blend modes than kDrawColor. - static bool IsValidPaintFlagsSkBlendMode(SkBlendMode mode) { - return static_cast<uint32_t>(mode) <= - static_cast<uint32_t>(SkBlendMode::kLastMode); - } - static bool IsValidSkClipOp(SkClipOp op) { return static_cast<uint32_t>(op) <= static_cast<uint32_t>(SkClipOp::kMax_EnumValue); @@ -278,31 +291,18 @@ return IsUnsetRect(rect) || rect.isFinite(); } - static constexpr size_t kNumOpTypes = - static_cast<size_t>(PaintOpType::kLastPaintOpType) + 1; - static bool g_is_draw_op[kNumOpTypes]; - static bool g_has_paint_flags[kNumOpTypes]; - static uint16_t g_type_to_aligned_size[kNumOpTypes]; + static const std::array<bool, kNumOpTypes> g_is_draw_op; + static const std::array<bool, kNumOpTypes> g_has_paint_flags; + static const std::array<uint16_t, kNumOpTypes> g_type_to_aligned_size; - static constexpr bool kIsDrawOp = false; - static constexpr bool kHasPaintFlags = false; static const SkRect kUnsetRect; - - PaintOp(const PaintOp&) = delete; - PaintOp& operator=(const PaintOp&) = delete; - - protected: - ~PaintOp() = default; }; class CC_PAINT_EXPORT PaintOpWithFlags : public PaintOp { public: static constexpr bool kHasPaintFlags = true; - PaintOpWithFlags(PaintOpType type, const PaintFlags& flags) - : PaintOp(type), flags(flags) {} int CountSlowPathsFromFlags() const { return flags.getPathEffect() ? 1 : 0; } - bool HasNonAAPaint() const { return !flags.isAntiAlias(); } bool HasDiscardableImagesFromFlags( gfx::ContentColorUsage* content_color_usage) const; @@ -319,12 +319,43 @@ PaintFlags flags; protected: + PaintOpWithFlags(PaintOpType type, const PaintFlags& flags) + : PaintOp(type), flags(flags) {} + explicit PaintOpWithFlags(PaintOpType type) : PaintOp(type) {} ~PaintOpWithFlags() = default; - explicit PaintOpWithFlags(PaintOpType type) : PaintOp(type) {} + bool HasNonAAPaint() const { return !flags.isAntiAlias(); } }; -class CC_PAINT_EXPORT AnnotateOp final : public PaintOp { +// The internal types make the non-runtime-polymorphic functions (which are +// protected in PaintOp[WithFlags] to prevent bugs where the functions are +// incorrectly used outside of paint_op.{h,cc}) public in subclasses. + +#define INTERNAL_PAINTOP_BASE_TYPE(type, super) \ + class type : public super { \ + public: \ + using super::CountSlowPaths; \ + using super::CountSlowPathsFromFlags; \ + using super::HasNonAAPaint; \ + using super::HasDrawTextOps; \ + using super::HasSaveLayerOps; \ + using super::HasSaveLayerAlphaOps; \ + using super::HasEffectsPreventingLCDTextForSaveLayerAlpha; \ + using super::HasDiscardableImages; \ + using super::HasDiscardableImagesFromFlags; \ + using super::AdditionalBytesUsed; \ + using super::AdditionalOpCount; \ + \ + protected: \ + using super::super; \ + } + +INTERNAL_PAINTOP_BASE_TYPE(PaintOpBaseInternal, PaintOp); +INTERNAL_PAINTOP_BASE_TYPE(PaintOpWithFlagsBaseInternal, PaintOpWithFlags); + +#undef INTERNAL_PAINTOP_BASE_TYPE + +class CC_PAINT_EXPORT AnnotateOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kAnnotate; AnnotateOp(PaintCanvas::AnnotationType annotation_type, @@ -346,14 +377,14 @@ AnnotateOp(); }; -class CC_PAINT_EXPORT ClipPathOp final : public PaintOp { +class CC_PAINT_EXPORT ClipPathOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kClipPath; ClipPathOp(SkPath path, SkClipOp op, bool antialias, UsePaintCache use_paint_cache = UsePaintCache::kEnabled) - : PaintOp(kType), + : PaintOpBaseInternal(kType), path(path), op(op), antialias(antialias), @@ -373,14 +404,14 @@ UsePaintCache use_cache = UsePaintCache::kDisabled; private: - ClipPathOp() : PaintOp(kType) {} + ClipPathOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT ClipRectOp final : public PaintOp { +class CC_PAINT_EXPORT ClipRectOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kClipRect; ClipRectOp(const SkRect& rect, SkClipOp op, bool antialias) - : PaintOp(kType), rect(rect), op(op), antialias(antialias) {} + : PaintOpBaseInternal(kType), rect(rect), op(op), antialias(antialias) {} static void Raster(const ClipRectOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -393,14 +424,17 @@ bool antialias; private: - ClipRectOp() : PaintOp(kType) {} + ClipRectOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT ClipRRectOp final : public PaintOp { +class CC_PAINT_EXPORT ClipRRectOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kClipRRect; ClipRRectOp(const SkRRect& rrect, SkClipOp op, bool antialias) - : PaintOp(kType), rrect(rrect), op(op), antialias(antialias) {} + : PaintOpBaseInternal(kType), + rrect(rrect), + op(op), + antialias(antialias) {} static void Raster(const ClipRRectOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -414,13 +448,14 @@ bool antialias; private: - ClipRRectOp() : PaintOp(kType) {} + ClipRRectOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT ConcatOp final : public PaintOp { +class CC_PAINT_EXPORT ConcatOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kConcat; - explicit ConcatOp(const SkM44& matrix) : PaintOp(kType), matrix(matrix) {} + explicit ConcatOp(const SkM44& matrix) + : PaintOpBaseInternal(kType), matrix(matrix) {} static void Raster(const ConcatOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -431,13 +466,13 @@ SkM44 matrix; private: - ConcatOp() : PaintOp(kType) {} + ConcatOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT CustomDataOp final : public PaintOp { +class CC_PAINT_EXPORT CustomDataOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kCustomData; - explicit CustomDataOp(uint32_t id) : PaintOp(kType), id(id) {} + explicit CustomDataOp(uint32_t id) : PaintOpBaseInternal(kType), id(id) {} static void Raster(const CustomDataOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -449,15 +484,15 @@ uint32_t id; private: - CustomDataOp() : PaintOp(kType) {} + CustomDataOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT DrawColorOp final : public PaintOp { +class CC_PAINT_EXPORT DrawColorOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawColor; static constexpr bool kIsDrawOp = true; DrawColorOp(SkColor4f color, SkBlendMode mode) - : PaintOp(kType), color(color), mode(mode) {} + : PaintOpBaseInternal(kType), color(color), mode(mode) {} static void Raster(const DrawColorOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -469,17 +504,19 @@ SkBlendMode mode; private: - DrawColorOp() : PaintOp(kType) {} + DrawColorOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT DrawDRRectOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawDRRectOp final : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawDRRect; static constexpr bool kIsDrawOp = true; DrawDRRectOp(const SkRRect& outer, const SkRRect& inner, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), outer(outer), inner(inner) {} + : PaintOpWithFlagsBaseInternal(kType, flags), + outer(outer), + inner(inner) {} static void RasterWithFlags(const DrawDRRectOp* op, const PaintFlags* flags, SkCanvas* canvas, @@ -494,10 +531,10 @@ SkRRect inner; private: - DrawDRRectOp() : PaintOpWithFlags(kType) {} + DrawDRRectOp() : PaintOpWithFlagsBaseInternal(kType) {} }; -class CC_PAINT_EXPORT DrawImageOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawImageOp final : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawImage; static constexpr bool kIsDrawOp = true; @@ -535,7 +572,8 @@ SkSize scale_adjustment = SkSize::Make(1.f, 1.f); }; -class CC_PAINT_EXPORT DrawImageRectOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawImageRectOp final + : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawImageRect; static constexpr bool kIsDrawOp = true; @@ -578,12 +616,12 @@ SkSize scale_adjustment = SkSize::Make(1.f, 1.f); }; -class CC_PAINT_EXPORT DrawIRectOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawIRectOp final : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawIRect; static constexpr bool kIsDrawOp = true; DrawIRectOp(const SkIRect& rect, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), rect(rect) {} + : PaintOpWithFlagsBaseInternal(kType, flags), rect(rect) {} static void RasterWithFlags(const DrawIRectOp* op, const PaintFlags* flags, SkCanvas* canvas, @@ -596,10 +634,10 @@ SkIRect rect; private: - DrawIRectOp() : PaintOpWithFlags(kType) {} + DrawIRectOp() : PaintOpWithFlagsBaseInternal(kType) {} }; -class CC_PAINT_EXPORT DrawLineOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawLineOp final : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawLine; static constexpr bool kIsDrawOp = true; @@ -609,7 +647,7 @@ SkScalar y1, const PaintFlags& flags, bool draw_as_path = false) - : PaintOpWithFlags(kType, flags), + : PaintOpWithFlagsBaseInternal(kType, flags), x0(x0), y0(y0), x1(x1), @@ -635,11 +673,11 @@ bool draw_as_path; private: - DrawLineOp() : PaintOpWithFlags(kType) {} + DrawLineOp() : PaintOpWithFlagsBaseInternal(kType) {} }; // TODO(crbug.com/340122178): figure out a better way to unify types. -class CC_PAINT_EXPORT DrawLineLiteOp final : public PaintOp { +class CC_PAINT_EXPORT DrawLineLiteOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawLineLite; static constexpr bool kIsDrawOp = true; @@ -648,7 +686,7 @@ SkScalar x1, SkScalar y1, const CorePaintFlags& core_paint_flags) - : PaintOp(kType), + : PaintOpBaseInternal(kType), x0(x0), y0(y0), x1(x1), @@ -670,11 +708,11 @@ CorePaintFlags core_paint_flags; private: - DrawLineLiteOp() : PaintOp(kType) {} + DrawLineLiteOp() : PaintOpBaseInternal(kType) {} }; // TODO(crbug.com/340122178): figure out a better way to unify types. -class CC_PAINT_EXPORT DrawArcLiteOp final : public PaintOp { +class CC_PAINT_EXPORT DrawArcLiteOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawArcLite; static constexpr bool kIsDrawOp = true; @@ -682,7 +720,7 @@ SkScalar start_angle_degrees, SkScalar sweep_angle_degrees, const CorePaintFlags& core_paint_flags) - : PaintOp(kType), + : PaintOpBaseInternal(kType), oval(oval), start_angle_degrees(start_angle_degrees), sweep_angle_degrees(sweep_angle_degrees), @@ -704,10 +742,10 @@ CorePaintFlags core_paint_flags; private: - DrawArcLiteOp() : PaintOp(kType) {} + DrawArcLiteOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT DrawArcOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawArcOp final : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawArc; static constexpr bool kIsDrawOp = true; @@ -715,7 +753,7 @@ SkScalar start_angle_degrees, SkScalar sweep_angle_degrees, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), + : PaintOpWithFlagsBaseInternal(kType, flags), oval(oval), start_angle_degrees(start_angle_degrees), sweep_angle_degrees(sweep_angle_degrees) {} @@ -738,15 +776,15 @@ SkScalar sweep_angle_degrees; private: - DrawArcOp() : PaintOpWithFlags(kType) {} + DrawArcOp() : PaintOpWithFlagsBaseInternal(kType) {} }; -class CC_PAINT_EXPORT DrawOvalOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawOvalOp final : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawOval; static constexpr bool kIsDrawOp = true; DrawOvalOp(const SkRect& oval, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), oval(oval) {} + : PaintOpWithFlagsBaseInternal(kType, flags), oval(oval) {} static void RasterWithFlags(const DrawOvalOp* op, const PaintFlags* flags, SkCanvas* canvas, @@ -758,17 +796,17 @@ SkRect oval; private: - DrawOvalOp() : PaintOpWithFlags(kType) {} + DrawOvalOp() : PaintOpWithFlagsBaseInternal(kType) {} }; -class CC_PAINT_EXPORT DrawPathOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawPathOp final : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawPath; static constexpr bool kIsDrawOp = true; DrawPathOp(const SkPath& path, const PaintFlags& flags, UsePaintCache use_paint_cache = UsePaintCache::kEnabled) - : PaintOpWithFlags(kType, flags), + : PaintOpWithFlagsBaseInternal(kType, flags), path(path), sk_path_fill_type(static_cast<uint8_t>(path.getFillType())), use_cache(use_paint_cache) {} @@ -791,10 +829,10 @@ UsePaintCache use_cache = UsePaintCache::kDisabled; private: - DrawPathOp() : PaintOpWithFlags(kType) {} + DrawPathOp() : PaintOpWithFlagsBaseInternal(kType) {} }; -class CC_PAINT_EXPORT DrawRecordOp final : public PaintOp { +class CC_PAINT_EXPORT DrawRecordOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawRecord; static constexpr bool kIsDrawOp = true; @@ -829,12 +867,12 @@ bool local_ctm = true; }; -class CC_PAINT_EXPORT DrawRectOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawRectOp final : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawRect; static constexpr bool kIsDrawOp = true; DrawRectOp(const SkRect& rect, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), rect(rect) {} + : PaintOpWithFlagsBaseInternal(kType, flags), rect(rect) {} static void RasterWithFlags(const DrawRectOp* op, const PaintFlags* flags, SkCanvas* canvas, @@ -846,15 +884,15 @@ SkRect rect; private: - DrawRectOp() : PaintOpWithFlags(kType) {} + DrawRectOp() : PaintOpWithFlagsBaseInternal(kType) {} }; -class CC_PAINT_EXPORT DrawRRectOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawRRectOp final : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawRRect; static constexpr bool kIsDrawOp = true; DrawRRectOp(const SkRRect& rrect, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), rrect(rrect) {} + : PaintOpWithFlagsBaseInternal(kType, flags), rrect(rrect) {} static void RasterWithFlags(const DrawRRectOp* op, const PaintFlags* flags, SkCanvas* canvas, @@ -866,7 +904,7 @@ SkRRect rrect; private: - DrawRRectOp() : PaintOpWithFlags(kType) {} + DrawRRectOp() : PaintOpWithFlagsBaseInternal(kType) {} }; // This is used to draw non-composited scrolling contents. The display item @@ -875,7 +913,8 @@ // current clip of the canvas and the current scroll offset and will be applied // to the display item list. This PaintOp doesn't apply the overflow clip of // the scroller, but the client should emit ClipRectOp. -class CC_PAINT_EXPORT DrawScrollingContentsOp final : public PaintOp { +class CC_PAINT_EXPORT DrawScrollingContentsOp final + : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawScrollingContents; static constexpr bool kIsDrawOp = true; @@ -902,7 +941,8 @@ scoped_refptr<DisplayItemList> display_item_list; }; -class CC_PAINT_EXPORT DrawVerticesOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawVerticesOp final + : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawVertices; static constexpr bool kIsDrawOp = true; @@ -936,7 +976,7 @@ DrawVerticesOp(); }; -class CC_PAINT_EXPORT DrawSkottieOp final : public PaintOp { +class CC_PAINT_EXPORT DrawSkottieOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawSkottie; static constexpr bool kIsDrawOp = true; @@ -983,7 +1023,7 @@ DrawSkottieOp(); }; -class CC_PAINT_EXPORT DrawSlugOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawSlugOp final : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawSlug; static constexpr bool kIsDrawOp = true; @@ -1011,7 +1051,8 @@ DrawSlugOp(); }; -class CC_PAINT_EXPORT DrawTextBlobOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT DrawTextBlobOp final + : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kDrawTextBlob; static constexpr bool kIsDrawOp = true; @@ -1046,10 +1087,10 @@ DrawTextBlobOp(); }; -class CC_PAINT_EXPORT NoopOp final : public PaintOp { +class CC_PAINT_EXPORT NoopOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kNoop; - NoopOp() : PaintOp(kType) {} + NoopOp() : PaintOpBaseInternal(kType) {} static void Raster(const NoopOp* op, SkCanvas* canvas, const PlaybackParams& params) {} @@ -1058,10 +1099,10 @@ HAS_SERIALIZATION_FUNCTIONS(); }; -class CC_PAINT_EXPORT RestoreOp final : public PaintOp { +class CC_PAINT_EXPORT RestoreOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kRestore; - RestoreOp() : PaintOp(kType) {} + RestoreOp() : PaintOpBaseInternal(kType) {} static void Raster(const RestoreOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -1070,10 +1111,11 @@ HAS_SERIALIZATION_FUNCTIONS(); }; -class CC_PAINT_EXPORT RotateOp final : public PaintOp { +class CC_PAINT_EXPORT RotateOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kRotate; - explicit RotateOp(SkScalar degrees) : PaintOp(kType), degrees(degrees) {} + explicit RotateOp(SkScalar degrees) + : PaintOpBaseInternal(kType), degrees(degrees) {} static void Raster(const RotateOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -1084,13 +1126,13 @@ SkScalar degrees; private: - RotateOp() : PaintOp(kType) {} + RotateOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT SaveOp final : public PaintOp { +class CC_PAINT_EXPORT SaveOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kSave; - SaveOp() : PaintOp(kType) {} + SaveOp() : PaintOpBaseInternal(kType) {} static void Raster(const SaveOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -1099,13 +1141,13 @@ HAS_SERIALIZATION_FUNCTIONS(); }; -class CC_PAINT_EXPORT SaveLayerOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT SaveLayerOp final : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kSaveLayer; explicit SaveLayerOp(const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), bounds(kUnsetRect) {} + : PaintOpWithFlagsBaseInternal(kType, flags), bounds(kUnsetRect) {} SaveLayerOp(const SkRect& bounds, const PaintFlags& flags) - : PaintOpWithFlags(kType, flags), bounds(bounds) {} + : PaintOpWithFlagsBaseInternal(kType, flags), bounds(bounds) {} static void RasterWithFlags(const SaveLayerOp* op, const PaintFlags* flags, SkCanvas* canvas, @@ -1123,18 +1165,18 @@ SkRect bounds; private: - SaveLayerOp() : PaintOpWithFlags(kType) {} + SaveLayerOp() : PaintOpWithFlagsBaseInternal(kType) {} }; -class CC_PAINT_EXPORT SaveLayerAlphaOp final : public PaintOp { +class CC_PAINT_EXPORT SaveLayerAlphaOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kSaveLayerAlpha; template <class F, class = std::enable_if_t<std::is_same_v<F, float>>> explicit SaveLayerAlphaOp(F alpha) - : PaintOp(kType), bounds(kUnsetRect), alpha(alpha) {} + : PaintOpBaseInternal(kType), bounds(kUnsetRect), alpha(alpha) {} template <class F, class = std::enable_if_t<std::is_same_v<F, float>>> SaveLayerAlphaOp(const SkRect& bounds, F alpha) - : PaintOp(kType), bounds(bounds), alpha(alpha) {} + : PaintOpBaseInternal(kType), bounds(bounds), alpha(alpha) {} static void Raster(const SaveLayerAlphaOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -1148,10 +1190,11 @@ float alpha; private: - SaveLayerAlphaOp() : PaintOp(kType) {} + SaveLayerAlphaOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT SaveLayerFiltersOp final : public PaintOpWithFlags { +class CC_PAINT_EXPORT SaveLayerFiltersOp final + : public PaintOpWithFlagsBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kSaveLayerFilters; explicit SaveLayerFiltersOp(base::span<const sk_sp<PaintFilter>> filters, @@ -1174,10 +1217,11 @@ SaveLayerFiltersOp(); }; -class CC_PAINT_EXPORT ScaleOp final : public PaintOp { +class CC_PAINT_EXPORT ScaleOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kScale; - ScaleOp(SkScalar sx, SkScalar sy) : PaintOp(kType), sx(sx), sy(sy) {} + ScaleOp(SkScalar sx, SkScalar sy) + : PaintOpBaseInternal(kType), sx(sx), sy(sy) {} static void Raster(const ScaleOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -1189,13 +1233,14 @@ SkScalar sy; private: - ScaleOp() : PaintOp(kType) {} + ScaleOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT SetMatrixOp final : public PaintOp { +class CC_PAINT_EXPORT SetMatrixOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kSetMatrix; - explicit SetMatrixOp(const SkM44& matrix) : PaintOp(kType), matrix(matrix) {} + explicit SetMatrixOp(const SkM44& matrix) + : PaintOpBaseInternal(kType), matrix(matrix) {} // This is the only op that needs the original ctm of the SkCanvas // used for raster (since kSetMatrix is relative to the recording origin and // shouldn't clobber the SkCanvas raster origin). @@ -1212,13 +1257,14 @@ SkM44 matrix; private: - SetMatrixOp() : PaintOp(kType) {} + SetMatrixOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT SetNodeIdOp final : public PaintOp { +class CC_PAINT_EXPORT SetNodeIdOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kSetNodeId; - explicit SetNodeIdOp(int node_id) : PaintOp(kType), node_id(node_id) {} + explicit SetNodeIdOp(int node_id) + : PaintOpBaseInternal(kType), node_id(node_id) {} static void Raster(const SetNodeIdOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -1229,13 +1275,14 @@ int node_id; private: - SetNodeIdOp() : PaintOp(kType) {} + SetNodeIdOp() : PaintOpBaseInternal(kType) {} }; -class CC_PAINT_EXPORT TranslateOp final : public PaintOp { +class CC_PAINT_EXPORT TranslateOp final : public PaintOpBaseInternal { public: static constexpr PaintOpType kType = PaintOpType::kTranslate; - TranslateOp(SkScalar dx, SkScalar dy) : PaintOp(kType), dx(dx), dy(dy) {} + TranslateOp(SkScalar dx, SkScalar dy) + : PaintOpBaseInternal(kType), dx(dx), dy(dy) {} static void Raster(const TranslateOp* op, SkCanvas* canvas, const PlaybackParams& params); @@ -1247,7 +1294,7 @@ SkScalar dy; private: - TranslateOp() : PaintOp(kType) {} + TranslateOp() : PaintOpBaseInternal(kType) {} }; #undef HAS_SERIALIZATION_FUNCTIONS
diff --git a/cc/trees/frame_rate_estimator.cc b/cc/trees/frame_rate_estimator.cc index d2e4898..01d2203 100644 --- a/cc/trees/frame_rate_estimator.cc +++ b/cc/trees/frame_rate_estimator.cc
@@ -5,8 +5,10 @@ #include "cc/trees/frame_rate_estimator.h" #include "base/feature_list.h" +#include "base/strings/stringprintf.h" #include "base/task/sequenced_task_runner.h" #include "base/time/time.h" +#include "base/trace_event/trace_event.h" #include "cc/base/features.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" @@ -43,6 +45,15 @@ } void FrameRateEstimator::WillDraw(base::TimeTicks now) { + TRACE_EVENT1( + "cc,benchmark", "FrameRateEstimator::WillDraw", "Info", + base::StringPrintf("num_did_not_produce_frame_since_last_draw: %" PRIu64 + "\nin_video_conference_mode: %d\ninput_priority_mode: " + "%d\nkNumDidNotProduceFrameBeforeThrottle: %d", + num_did_not_produce_frame_since_last_draw_, + in_video_conference_mode_, input_priority_mode_, + features::kNumDidNotProduceFrameBeforeThrottle.Get())); + num_did_not_produce_frame_since_last_draw_ = 0u; if (!in_video_conference_mode_ || input_priority_mode_) { return;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 6f28150..a14c069 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -3381,6 +3381,23 @@ void LayerTreeHostImpl::DidNotProduceFrame(const viz::BeginFrameAck& ack, FrameSkippedReason reason) { + TRACE_EVENT2( + "cc,benchmark", "LayerTreeHostImpl::DidNotProduceFrame", + "FrameSkippedReason", + [](FrameSkippedReason reason) { + switch (reason) { + case FrameSkippedReason::kRecoverLatency: + return "kRecoverLatency"; + case FrameSkippedReason::kNoDamage: + return "kNoDamage"; + case FrameSkippedReason::kWaitingOnMain: + return "kWaitingOnMain"; + case FrameSkippedReason::kDrawThrottled: + return "kDrawThrottled"; + } + return ""; + }(reason), + "Frame Sequence Number", ack.frame_id.sequence_number); frame_rate_estimator_.DidNotProduceFrame(); if (layer_tree_frame_sink_) { static const bool feature_allowed = base::FeatureList::IsEnabled(
diff --git a/chrome/VERSION b/chrome/VERSION index 6904b33..7ee5af02 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=133 MINOR=0 -BUILD=6901 +BUILD=6902 PATCH=0
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 58b4b2f1..db76eaba 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -363,6 +363,7 @@ "junit/src/org/chromium/chrome/browser/sync/LocalDataDescriptionTest.java", "junit/src/org/chromium/chrome/browser/sync/SyncErrorNotifierTest.java", "junit/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageImpressionTrackerTest.java", + "junit/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardMediatorTest.java", "junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java", "junit/src/org/chromium/chrome/browser/tab/TabArchiveSettingsTest.java", "junit/src/org/chromium/chrome/browser/tab/TabAttributesTest.java",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java index 4e72982..996d356c 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java
@@ -189,13 +189,6 @@ resetTabStrip(); } - // TODO(crbug/41496693): Delete this logic once tab groups with one tab are - // launched. - @Override - public void willCloseTab(Tab tab, boolean didCloseAlone) { - resetTabStrip(); - } - @Override public void didAddTab( Tab tab,
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java index 5ce6299..1d65dca 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java
@@ -560,27 +560,6 @@ } @Test - public void tabClosure_NotLastTabInGroup_Selection_SingleTabGroupsDisabled() { - initAndAssertProperties(mTab2); - - doReturn(mTab3).when(mTabGroupModelFilter).getGroupLastShownTab(TAB2_ROOT_ID); - doReturn(false).when(mTabGroupModelFilter).isTabInTabGroup(mTab2); - doReturn(false).when(mTabGroupModelFilter).isTabInTabGroup(mTab3); - - // Mock closing tab 2, and tab 3 then gets selected. They are in the same group assume that - // that Tab 3 is the last tab in the group. - mTabModelObserverArgumentCaptor.getValue().willCloseTab(mTab2, true); - verifyResetStrip(false, null); - - mTabModelObserverArgumentCaptor - .getValue() - .didSelectTab(mTab3, TabSelectionType.FROM_CLOSE, TAB2_ID); - - // Strip should not be reset again. - verifyNeverReset(); - } - - @Test public void tabClosure_NotLastTabInGroup_Selection_SingleTabGroupsEnabled() { initAndAssertProperties(mTab2); @@ -591,7 +570,6 @@ // Mock closing tab 2, and tab 3 then gets selected. They are in the same group assume that // that Tab 3 is the last tab in the group, but tab groups of size 1 are supported. - mTabModelObserverArgumentCaptor.getValue().willCloseTab(mTab2, true); mTabModelObserverArgumentCaptor .getValue() .didSelectTab(mTab3, TabSelectionType.FROM_CLOSE, TAB2_ID); @@ -601,41 +579,10 @@ } @Test - public void tabClosure_NotLastTabInGroup_NoSelection_SingleTabGroupsDisabled() { - initAndAssertProperties(mTab2); - - doReturn(mTab2).when(mTabGroupModelFilter).getGroupLastShownTab(TAB3_ROOT_ID); - doReturn(false).when(mTabGroupModelFilter).isTabInTabGroup(mTab2); - doReturn(false).when(mTabGroupModelFilter).isTabInTabGroup(mTab3); - - // Mock closing tab 3, and tab 2 remains selected. - mTabModelObserverArgumentCaptor.getValue().willCloseTab(mTab3, true); - - // Strip should reset since since we don't have a group anymore. - verifyResetStrip(false, null); - } - - @Test - public void tabClosure_NotLastTabInGroup_NoSelection_SingleTabGroupsEnabled() { - initAndAssertProperties(mTab2); - - doReturn(mTab2).when(mTabGroupModelFilter).getGroupLastShownTab(TAB3_ROOT_ID); - doReturn(true).when(mTabGroupModelFilter).isTabInTabGroup(mTab2); - doReturn(false).when(mTabGroupModelFilter).isTabInTabGroup(mTab3); - - // Mock closing tab 3, and tab 2 remains selected. - mTabModelObserverArgumentCaptor.getValue().willCloseTab(mTab3, true); - - // Strip should not be reset since we are still in this group. - verifyNeverReset(); - } - - @Test public void tabClosure_LastTabInGroup_GroupUiNotVisible() { initAndAssertProperties(mTab1); // Mock closing tab 1, and tab 2 then gets selected. They are in different group. - mTabModelObserverArgumentCaptor.getValue().willCloseTab(mTab1, true); when(mTabModelSelector.getCurrentTab()).thenReturn(mTab2); mTabModelObserverArgumentCaptor .getValue() @@ -653,12 +600,10 @@ // Mock closing tab 2 and tab, then tab 1 gets selected. They are in different group. Right // now tab group UI is visible. - mTabModelObserverArgumentCaptor.getValue().willCloseTab(mTab2, true); mTabModelObserverArgumentCaptor .getValue() .didSelectTab(mTab3, TabSelectionType.FROM_CLOSE, TAB2_ID); doReturn(new ArrayList<>()).when(mTabGroupModelFilter).getRelatedTabList(TAB3_ID); - mTabModelObserverArgumentCaptor.getValue().willCloseTab(mTab3, true); mTabModelObserverArgumentCaptor .getValue() .didSelectTab(mTab1, TabSelectionType.FROM_CLOSE, TAB3_ID);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java index c21e722b..f032571 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.bookmarks; +import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.view.LayoutInflater; @@ -14,6 +15,7 @@ import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; +import androidx.lifecycle.LifecycleOwner; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView.ItemAnimator; import androidx.recyclerview.widget.RecyclerView.OnScrollListener; @@ -221,7 +223,9 @@ onScrollListener -> mRecyclerView.addOnScrollListener(onScrollListener); mMediator = new BookmarkManagerMediator( - context, + (Activity) context, + (LifecycleOwner) context, + mModalDialogManager, mBookmarkModel, mBookmarkOpener, mSelectableListLayout,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java index cb7d12f0..2f9a097 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java
@@ -6,6 +6,7 @@ import static org.chromium.components.browser_ui.widget.BrowserUiListMenuUtils.buildMenuListItem; +import android.app.Activity; import android.content.Context; import android.text.TextUtils; @@ -14,6 +15,7 @@ import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.VisibleForTesting; +import androidx.lifecycle.LifecycleOwner; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView.OnScrollListener; @@ -60,6 +62,7 @@ import org.chromium.ui.accessibility.AccessibilityState; import org.chromium.ui.listmenu.ListMenu; import org.chromium.ui.listmenu.ListMenuItemProperties; +import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modelutil.MVCListAdapter.ListItem; import org.chromium.ui.modelutil.MVCListAdapter.ModelList; import org.chromium.ui.modelutil.PropertyModel; @@ -156,7 +159,7 @@ // local bookmarks. if (mBookmarkBatchUploadCardCoordinator != null) { mBookmarkBatchUploadCardCoordinator - .hideBatchUploadCardAndUpdate(); + .immediatelyHideBatchUploadCardAndUpdateItsVisibility(); } } } @@ -390,7 +393,9 @@ private boolean mShoppingFilterAvailable; BookmarkManagerMediator( - Context context, + Activity activity, + LifecycleOwner lifecycleOwner, + ModalDialogManager modalDialogManager, BookmarkModel bookmarkModel, BookmarkOpener bookmarkOpener, SelectableListLayout<BookmarkId> selectableListLayout, @@ -410,7 +415,7 @@ BooleanSupplier canShowSigninPromo, Consumer<OnScrollListener> onScrollListenerConsumer, BookmarkMoveSnackbarManager bookmarkMoveSnackbarManager) { - mContext = context; + mContext = activity; mBookmarkModel = bookmarkModel; mBookmarkModel.addObserver(mBookmarkModelObserver); mBookmarkOpener = bookmarkOpener; @@ -441,7 +446,9 @@ if (ChromeFeatureList.isEnabled(ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP)) { mBookmarkBatchUploadCardCoordinator = new BookmarkBatchUploadCardCoordinator( - mContext, + activity, + lifecycleOwner, + modalDialogManager, mProfile.getOriginalProfile(), mSnackbarManager, this::updateBatchUploadCard);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java index 6276e49..ec85fe0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java
@@ -29,6 +29,7 @@ import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; import org.chromium.chrome.R; +import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.bookmarks.BookmarkModel; import org.chromium.chrome.browser.bookmarks.BookmarkModelObserver; @@ -181,6 +182,8 @@ mRemainingTaskCount = 1; mBookmarkModel = BookmarkModel.getForProfile(ProfileManager.getLastUsedRegularProfile()); + mBookmarkModel.setPartnerBookmarkIteratorSupplier( + () -> AppHooks.get().getPartnerBookmarkIterator()); mBookmarkModel.finishLoadingBookmarkModel( new Runnable() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ReorderDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ReorderDelegate.java index 221a748..c7ba57b7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ReorderDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ReorderDelegate.java
@@ -68,9 +68,6 @@ // Reorder State. private final ObservableSupplierImpl<Boolean> mInReorderModeSupplier = new ObservableSupplierImpl<>(/* initialValue= */ false); - // TODO(crbug.com/381285152): Cleanup mReorderingForTabDrop - duplicate of - // ReorderType.EXTERNAL_VIEW_IN_STRIP. - private boolean mReorderingForTabDrop; @IntDef({ReorderType.VIEW_IN_STRIP, ReorderType.VIEW_DRAG, ReorderType.EXTERNAL_VIEW_IN_STRIP}) @Retention(RetentionPolicy.SOURCE) @@ -104,7 +101,8 @@ private ReorderStrategy mActiveStrategy; private final TabReorderStrategy mTabStrategy = new TabReorderStrategy(); private final GroupReorderStrategy mGroupStrategy = new GroupReorderStrategy(); - @Nullable private SourceViewDragDropReorderStrategy mDragDropStrategy; + @Nullable private SourceViewDragDropReorderStrategy mSourceViewDragDropReorderStrategy; + @Nullable private ExternalViewDragDropReorderStrategy mExternalViewDragDropReorderStrategy; // Auto-scroll State. private long mLastReorderScrollTime; @@ -123,14 +121,7 @@ } boolean getReorderingForTabDrop() { - return mReorderingForTabDrop; - } - - void setReorderingForTabDrop(boolean reorderingForTabDrop) { - if (mReorderingForTabDrop != reorderingForTabDrop) { - mReorderingForTabDrop = reorderingForTabDrop; - if (mReorderingForTabDrop) onReorderingForTabDrop(); - } + return getInReorderMode() && mActiveStrategy == mExternalViewDragDropReorderStrategy; } float getLastReorderX() { @@ -156,10 +147,14 @@ private ReorderStrategy getReorderStrategy( StripLayoutView interactingView, @ReorderType int reorderType) { - if (mDragDropStrategy != null + if (mSourceViewDragDropReorderStrategy != null && interactingView instanceof StripLayoutTab && reorderType == ReorderType.VIEW_DRAG) { - return mDragDropStrategy; + return mSourceViewDragDropReorderStrategy; + } else if (interactingView instanceof StripLayoutTab + && reorderType == ReorderType.EXTERNAL_VIEW_IN_STRIP) { + assert mExternalViewDragDropReorderStrategy != null; + return mExternalViewDragDropReorderStrategy; } else if (interactingView instanceof StripLayoutTab) { return mTabStrategy; } else if (interactingView instanceof StripLayoutGroupTitle) { @@ -172,25 +167,25 @@ // TODO(crbug.com/381285152): Remove get/set viewBeingDragged once DragDropReorderStrategy is // complete. StripLayoutView getViewBeingDragged() { - if (mDragDropStrategy == null) return null; - return mDragDropStrategy.mViewBeingDragged; + if (mSourceViewDragDropReorderStrategy == null) return null; + return mSourceViewDragDropReorderStrategy.mViewBeingDragged; } void setViewBeingDragged(StripLayoutView view) { - if (mDragDropStrategy == null) return; - mDragDropStrategy.mViewBeingDragged = view; + if (mSourceViewDragDropReorderStrategy == null) return; + mSourceViewDragDropReorderStrategy.mViewBeingDragged = view; } // TODO(crbug.com/381285152): Remove get/set dragLastOffsetX once DragDropReorderStrategy is // complete. float getDragLastOffsetX() { - if (mDragDropStrategy == null) return 0f; - return mDragDropStrategy.mLastOffsetX; + if (mSourceViewDragDropReorderStrategy == null) return 0f; + return mSourceViewDragDropReorderStrategy.mLastOffsetX; } void setDragLastOffsetX(float offsetX) { - if (mDragDropStrategy == null) return; - mDragDropStrategy.mLastOffsetX = offsetX; + if (mSourceViewDragDropReorderStrategy == null) return; + mSourceViewDragDropReorderStrategy.mLastOffsetX = offsetX; } // ============================================================================================ @@ -224,9 +219,10 @@ mContainerView = containerView; mModel = mTabGroupModelFilter.getTabModel(); - if (tabDragSource != null) { - mDragDropStrategy = new SourceViewDragDropReorderStrategy(tabDragSource); + mSourceViewDragDropReorderStrategy = + new SourceViewDragDropReorderStrategy(tabDragSource); + mExternalViewDragDropReorderStrategy = new ExternalViewDragDropReorderStrategy(); } mInitialized = true; } @@ -235,7 +231,11 @@ // Reorder API // ============================================================================================ - /** See {@link ReorderStrategy#startReorderMode} */ + /** + * See {@link ReorderStrategy#startReorderMode}. Additional params: + * + * @param reorderType The type {@link ReorderType} of reorder to start. + */ void startReorderMode( StripLayoutTab[] stripTabs, StripLayoutGroupTitle[] stripGroupTitles, @@ -388,6 +388,19 @@ return true; } + private void setTrailingMarginForTab( + StripLayoutTab stripTab, + StripLayoutGroupTitle[] groupTitles, + boolean shouldHaveTrailingMargin, + @NonNull ArrayList<Animator> animationList) { + final Tab tab = mModel.getTabById(stripTab.getTabId()); + if (tab == null) return; + final StripLayoutGroupTitle groupTitle = + StripLayoutUtils.findGroupTitle(groupTitles, tab.getRootId()); + + setTrailingMarginForTab(stripTab, groupTitle, shouldHaveTrailingMargin, animationList); + } + private void resetTabGroupMargins( StripLayoutGroupTitle[] groupTitles, StripLayoutTab[] stripTabs, @@ -398,13 +411,8 @@ // don't use trailing margins to demarcate tab group bounds. for (int i = 0; i < stripTabs.length; i++) { final StripLayoutTab stripTab = stripTabs[i]; - final Tab tab = mModel.getTabById(stripTab.getTabId()); - if (tab == null) continue; - final StripLayoutGroupTitle groupTitle = - StripLayoutUtils.findGroupTitle(groupTitles, tab.getRootId()); - setTrailingMarginForTab( - stripTab, groupTitle, /* shouldHaveTrailingMargin= */ false, animationList); + stripTab, groupTitles, /* shouldHaveTrailingMargin= */ false, animationList); } mScrollDelegate.setReorderStartMargin(/* newStartMargin= */ 0.f); } @@ -454,8 +462,6 @@ StripLayoutGroupTitle[] groupTitles, StripLayoutTab[] stripTabs, float deltaX) { - if (!getInReorderMode() || mInteractingTab == null || mReorderingForTabDrop) return; - int curIndex = StripLayoutUtils.findIndexForTab(stripTabs, mInteractingTab.getTabId()); if (curIndex == TabModel.INVALID_TAB_INDEX) return; @@ -507,47 +513,7 @@ @Override public void stopReorderMode( StripLayoutGroupTitle[] groupTitles, StripLayoutTab[] stripTabs) { - assert getInReorderMode() - : "Tried to stop reorder mode, without first starting reorder mode."; - ArrayList<Animator> animationList = new ArrayList<>(); - - // 1. Reset the state variables. - mReorderScrollState = REORDER_SCROLL_NONE; - setInReorderMode(false); - - // 2. Reset the interacting view (clear any offset and reattach the container). - mAnimationHost.finishAnimationsAndPushTabUpdates(); - if (mInteractingTab != null) { - // TODO(crbug.com/372546700): mInteractingTab may be null if reordering for tab - // drop. - animationList.add( - CompositorAnimator.ofFloatProperty( - mAnimationHost.getAnimationHandler(), - mInteractingTab, - StripLayoutView.X_OFFSET, - mInteractingTab.getOffsetX(), - 0f, - ANIM_TAB_MOVE_MS)); - - // Skip reattachment for tab drop to avoid exposing bottom indicator underneath the - // tab container. - if (!mReorderingForTabDrop || !mInteractingTab.getFolioAttached()) { - updateTabAttachState(mInteractingTab, /* attached= */ true, animationList); - } - } - - // 3. Clear any tab group margins. - resetTabGroupMargins(groupTitles, stripTabs, animationList); - - // 4. Clear the interacting view. - setInteractingTab(null); - - // 5. Reset the tab drop state. Must occur after the rest of the state is reset, since - // some logic depends on these values. - mReorderingForTabDrop = false; - - // 6. Start animations. - mAnimationHost.startAnimations(animationList, /* listener= */ null); + handleStopReorderMode(groupTitles, stripTabs); } @Override @@ -556,6 +522,44 @@ } } + private void handleStopReorderMode( + StripLayoutGroupTitle[] groupTitles, StripLayoutTab[] stripTabs) { + assert getInReorderMode() + : "Tried to stop reorder mode, without first starting reorder mode."; + ArrayList<Animator> animationList = new ArrayList<>(); + + // 1. Reset the state variables. + mReorderScrollState = REORDER_SCROLL_NONE; + setInReorderMode(false); + + // 2. Reset the interacting view (clear any offset and reattach the container). + mAnimationHost.finishAnimationsAndPushTabUpdates(); + // mInteractingTab may be null if reordering for external view drag drop. + if (mInteractingTab != null) { + animationList.add( + CompositorAnimator.ofFloatProperty( + mAnimationHost.getAnimationHandler(), + mInteractingTab, + StripLayoutView.X_OFFSET, + mInteractingTab.getOffsetX(), + 0f, + ANIM_TAB_MOVE_MS)); + + if (!mInteractingTab.getFolioAttached()) { + updateTabAttachState(mInteractingTab, /* attached= */ true, animationList); + } + } + + // 3. Clear any tab group margins. + resetTabGroupMargins(groupTitles, stripTabs, animationList); + + // 4. Clear the interacting view. + setInteractingTab(null); + + // 5. Start animations. + mAnimationHost.startAnimations(animationList, /* listener= */ null); + } + void prepareStripForReorder(float effectiveTabWidth, float startX) { mAnimationHost.finishAnimationsAndPushTabUpdates(); mLastReorderScrollTime = INVALID_TIME; @@ -870,21 +874,9 @@ } // ============================================================================================ - // Drag and drop reorder - drag external view onto / out of and within strip. - // ============================================================================================ - - void onReorderingForTabDrop() { - // TODO(crbug.com/381285152): Implement separate strategy for Drag and Drop on destination - // tab strip. This is only needed because we reuse the TabReorderStrategy#stopReorder for - // DnD, but can likely be replaced by implementing a DnD-specific ReorderStrategy. - mActiveStrategy = mTabStrategy; - } - - // ============================================================================================ // Drag and drop reorder - start dragging strip view. Subsequently drag out of, // within and back onto strip. // ============================================================================================ - private class SourceViewDragDropReorderStrategy implements ReorderStrategy { // Drag helpers private final TabDragSource mTabDragSource; @@ -964,6 +956,63 @@ } // ============================================================================================ + // Drag and drop reorder - drag external view onto / out-of strip and reorder within strip. + // ============================================================================================ + private class ExternalViewDragDropReorderStrategy implements ReorderStrategy { + + /** + * Initiate reorder when external view is dragged onto strip. interactingView here is the + * view on the strip being hovered on by the dragged view. + */ + @Override + public void startReorderMode( + StripLayoutTab[] stripTabs, + StripLayoutGroupTitle[] stripGroupTitles, + @NonNull StripLayoutView interactingView, + float effectiveTabWidth, + PointF startPoint, + @ReorderType int reorderType) { + // 1. Set initial state and add edge margins. + setInteractingTab((StripLayoutTab) interactingView); + setInReorderMode(true); + prepareStripForReorder(effectiveTabWidth, startPoint.x); + setEdgeMarginsForReorder(stripTabs[0], stripTabs[stripTabs.length - 1]); + + // 2. Add a trailing margin to the interacting tab to indicate where the tab will be + // inserted should the drag be dropped. + ArrayList<Animator> animationList = new ArrayList<>(); + setTrailingMarginForTab( + (StripLayoutTab) interactingView, + stripGroupTitles, + /* shouldHaveTrailingMargin= */ true, + animationList); + + // 3. Kick-off animations and request an update. + mAnimationHost.startAnimations(animationList, null); + } + + @Override + public void updateReorderPosition( + StripLayoutView[] stripViews, + StripLayoutGroupTitle[] groupTitles, + StripLayoutTab[] stripTabs, + float deltaX) { + // TODO(crbug.com/381285152): Implement. + } + + @Override + public void stopReorderMode( + StripLayoutGroupTitle[] groupTitles, StripLayoutTab[] stripTabs) { + handleStopReorderMode(groupTitles, stripTabs); + } + + @Override + public StripLayoutView getInteractingView() { + return mInteractingTab; + } + } + + // ============================================================================================ // Animation helpers // ============================================================================================
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 287c817c..0f9f31c 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
@@ -1851,7 +1851,8 @@ // Intentionally start the reorder at the initial long-press x. The difference from // the current event (accumulatedDeltaX in step 3) will then "snap" the interacting // view to its expected position. - startDragOrReorder(mDelayedReorderInitialX, y, mDelayedReorderView); + startReorderMode( + mDelayedReorderInitialX, y, mDelayedReorderView, ReorderType.VIEW_DRAG); } } @@ -1992,7 +1993,7 @@ } else { resetResizeTimeout(false); - startDragOrReorder(x, y, clickedTab); + startReorderMode(x, y, clickedTab, ReorderType.VIEW_DRAG); } } else { StripLayoutGroupTitle groupTitle = (StripLayoutGroupTitle) stripView; @@ -2003,7 +2004,7 @@ } else if (ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_STRIP_GROUP_REORDER)) { // Should be obsolete, since context menu has launched. Code path will be // unreachable, then removed once the context menu flag has been cleaned up. - startDragOrReorder(x, y, groupTitle); + startReorderMode(x, y, groupTitle, ReorderType.VIEW_IN_STRIP); } } } @@ -2121,10 +2122,28 @@ anchorRectProvider.getRect().offset(xOffset, toolbarCoordinates[1]); } - private void startDragOrReorder(float x, float y, StripLayoutView clickedView) { - if (clickedView != null) { - // Attempt to initiate drag-drop, fallback to reorder within strip. - startReorderMode(x, y, clickedView, ReorderType.VIEW_DRAG); + private void startReorderMode( + float x, float y, StripLayoutView interactingView, @ReorderType int reorderType) { + // Allow the user to drag the selected tab out of the tab strip. + if (interactingView != null) { + if (mReorderDelegate.getInReorderMode()) return; + // Attempt to start reordering. If the interacting view is a StripLayoutTab, + // only continue if it is valid (non-null, non-dying, non-placeholder) and + // the tab state is initialized. + if (interactingView instanceof StripLayoutTab interactingTab + && (interactingTab.isDying() + || interactingTab.getTabId() == Tab.INVALID_TAB_ID + || !mTabStateInitialized)) { + return; + } + + mReorderDelegate.startReorderMode( + mStripTabs, + mStripGroupTitles, + interactingView, + getEffectiveTabWidth(), + new PointF(x, y), + reorderType); } else { // Broadcast to start moving the window instance as the user has long pressed on the // open space of the tab strip. @@ -3860,53 +3879,6 @@ startReorderMode(x, 0, getTabAtPosition(x), ReorderType.VIEW_IN_STRIP); } - private void startReorderMode( - float x, float y, StripLayoutView interactingView, @ReorderType int reorderType) { - if (mReorderDelegate.getInReorderMode() || interactingView == null) return; - - // Attempt to start reordering. If the interacting view is a StripLayoutTab, only continue - // if it is valid (non-null, non-dying, non-placeholder) and the tab state is initialized. - if (interactingView instanceof StripLayoutTab interactingTab - && (interactingTab.isDying() - || interactingTab.getTabId() == Tab.INVALID_TAB_ID - || !mTabStateInitialized)) { - return; - } - mReorderDelegate.startReorderMode( - mStripTabs, - mStripGroupTitles, - interactingView, - getEffectiveTabWidth(), - new PointF(x, y), - reorderType); - } - - void updateStripForExternalTabDrop(float startX) { - // 1. StartX indicates the position where the tab drag entered the destination tab strip. - // Adjust by a half tab-width so that we target the nearest tab gap. - startX = adjustXForTabDrop(startX); - - // 2. Mark the "interacting" tab. This is not the DnD dragged tab, but rather the tab in the - // strip that is currently being hovered by the DnD drag. - StripLayoutTab hoveredTab = getTabAtPosition(startX); - if (hoveredTab == null) hoveredTab = mStripTabs[mStripTabs.length - 1]; - mReorderDelegate.setInteractingTab(hoveredTab); - - // 3. Set initial state. - mReorderDelegate.setInReorderMode(true); - mReorderDelegate.setReorderingForTabDrop(true); - mReorderDelegate.prepareStripForReorder(getEffectiveTabWidth(), startX); - mReorderDelegate.setEdgeMarginsForReorder(mStripTabs[0], mStripTabs[mStripTabs.length - 1]); - - // 4. Add a tab group margin to the "interacting" tab to indicate where the tab will be - // inserted should the drag be dropped. - ArrayList<Animator> animationList = new ArrayList<>(); - setTrailingMarginForTab(hoveredTab, /* shouldHaveTrailingMargin= */ true, animationList); - - // 5. Kick-off animations and request an update. - startAnimations(animationList); - } - void stopReorderModeForTesting() { mReorderDelegate.stopReorderMode(mStripGroupTitles, mStripTabs); } @@ -4521,15 +4493,25 @@ } void prepareForTabDrop( - long time, - float currX, - float lastX, - boolean isSourceStrip, - boolean draggedTabIncognito) { + float currX, float lastX, boolean isSourceStrip, boolean draggedTabIncognito) { if (isSourceStrip) { dragActiveClickedTabOntoStrip(lastX, /* startReorder= */ true); - } else if (mIncognito == draggedTabIncognito) { - updateStripForExternalTabDrop(currX); + } else { + // Destination strip (ie: view dragged onto another strip) + // 1. If strip model does not match dragged view's, no-op. + if (mIncognito != draggedTabIncognito) return; + + // 2. StartX indicates where the external drag enters the tab strip. + // Adjust by a half tab-width so that we target the nearest tab gap. + float startX = adjustXForTabDrop(currX); + + // 3. Mark the "interacting" view. This is not the DnD dragged tab, but rather the tab + // in the strip that is currently being hovered by the DnD drag. + StripLayoutTab hoveredTab = getTabAtPosition(startX); + if (hoveredTab == null) hoveredTab = mStripTabs[mStripTabs.length - 1]; + + // 4. Start reorder - prepare strip to indicate drop target. + startReorderMode(startX, /* y= */ 0.f, hoveredTab, ReorderType.EXTERNAL_VIEW_IN_STRIP); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java index 958c115..7d76faec 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java
@@ -362,12 +362,7 @@ } mStripLayoutHelperSupplier .get() - .prepareForTabDrop( - LayoutManagerImpl.time(), - xPx * mPxToDp, - mLastXDp, - isDragSource, - isDraggedTabIncognito()); + .prepareForTabDrop(xPx * mPxToDp, mLastXDp, isDragSource, isDraggedTabIncognito()); return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java index cda9ff57..99feb2e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
@@ -5,6 +5,8 @@ package org.chromium.chrome.browser.ntp; import android.content.Context; +import android.view.View; +import android.view.ViewGroup; import org.chromium.base.ResettersForTesting; import org.chromium.base.metrics.RecordHistogram; @@ -32,6 +34,8 @@ import org.chromium.chrome.browser.ui.signin.SyncPromoController; import org.chromium.chrome.browser.ui.signin.SyncPromoController.SyncPromoState; import org.chromium.chrome.browser.ui.signin.account_picker.AccountPickerBottomSheetStrings; +import org.chromium.chrome.browser.ui.signin.signin_promo.RecentTabsSigninPromoDelegate; +import org.chromium.chrome.browser.ui.signin.signin_promo.SigninPromoCoordinator; import org.chromium.components.signin.AccountManagerFacadeProvider; import org.chromium.components.signin.AccountsChangeObserver; import org.chromium.components.signin.identitymanager.ConsentLevel; @@ -63,6 +67,7 @@ private final Tab mActiveTab; private final TabModelSelector mTabModelSelector; private final Runnable mShowHistoryManager; + private final SigninPromoCoordinator mSigninPromoCoordinator; private TabModel mTabModel; private @SyncPromoState int mPromoState = SyncPromoState.NO_PROMO; @@ -74,6 +79,7 @@ private RecentlyClosedTabManager mRecentlyClosedTabManager; private SigninManager mSignInManager; private UpdatedCallback mUpdatedCallback; + private View mSigninPromoView; private boolean mIsDestroyed; private final ProfileDataCache mProfileDataCache; @@ -130,6 +136,19 @@ SigninAccessPoint.RECENT_TABS, SyncConsentActivityLauncherImpl.get(), SigninAndHistorySyncActivityLauncherImpl.get()); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP)) { + mSigninPromoCoordinator = + new SigninPromoCoordinator( + context, + profile, + new RecentTabsSigninPromoDelegate( + context, + profile, + SigninAndHistorySyncActivityLauncherImpl.get(), + this::updatePromoState)); + } else { + mSigninPromoCoordinator = null; + } mSyncService = SyncServiceFactory.getForProfile(mProfile); mRecentlyClosedTabManager.setEntriesUpdatedRunnable(this::updateRecentlyClosedEntries); @@ -143,7 +162,11 @@ mSignInManager.addSignInStateObserver(this); mProfileDataCache.addObserver(this); AccountManagerFacadeProvider.getInstance().addObserver(this); - updatePromoState(); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP)) { + updatePromoState(); + } else { + updatePromoStateLegacy(); + } SessionsInvalidationManager.get(mProfile).onRecentTabsPageOpened(); } @@ -184,6 +207,9 @@ recordEntries("Bulk", mBulkSessionIdsRestored); mSyncService.removeSyncStateChangedListener(this); + if (mSigninPromoCoordinator != null) { + mSigninPromoCoordinator.destroy(); + } mSignInManager.removeSignInStateObserver(this); mSignInManager = null; @@ -432,6 +458,11 @@ } private @SyncPromoState int calculatePromoState() { + if (ChromeFeatureList.isEnabled(ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP)) { + return mSigninPromoCoordinator.canShowPromo() + ? SyncPromoState.PROMO_FOR_SIGNED_OUT_STATE + : SyncPromoState.NO_PROMO; + } if (ChromeFeatureList.isEnabled( ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS)) { // If ReplaceSyncPromosWithSignInPromos is enabled, there's only one promo type. @@ -469,7 +500,10 @@ return SyncPromoState.PROMO_FOR_SYNC_TURNED_OFF_STATE; } - private void updatePromoState() { + private void updatePromoStateLegacy() { + if (ChromeFeatureList.isEnabled(ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP)) { + return; + } final @SyncPromoState int newState = calculatePromoState(); if (newState == mPromoState) return; @@ -489,6 +523,14 @@ mSyncPromoController.setUpSyncPromoView(mProfileDataCache, view, null); } + View getSigninPromoView(ViewGroup parent) { + if (mSigninPromoView == null) { + mSigninPromoView = mSigninPromoCoordinator.buildPromoView(parent); + mSigninPromoCoordinator.setView(mSigninPromoView); + } + return mSigninPromoView; + } + // SignInStateObserver implementation. @Override public void onSignedIn() { @@ -525,12 +567,21 @@ } private void update() { - updatePromoState(); + updatePromoStateLegacy(); if (mIsDestroyed) return; updateForeignSessions(); onUpdateDone(); } + private void updatePromoState() { + final @SyncPromoState int newState = calculatePromoState(); + if (newState == mPromoState) return; + mPromoState = newState; + + if (mIsDestroyed) return; + onUpdateDone(); + } + private TabModel getTabModel() { // When RecentTabsManager is created for a new tab then {@link mActiveTab} is being // created and will not be present in a {@link TabModel} of {@link mTabModelSelector}.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java index d64b154..f6a4475 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
@@ -487,6 +487,20 @@ } } + /** A group containing the personalized sync promo. */ + class SigninPromoGroup extends PromoGroup { + @Override + public @ChildType int getChildType() { + return ChildType.PERSONALIZED_SIGNIN_PROMO; + } + + @Override + View getChildView( + int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { + return mRecentTabsManager.getSigninPromoView(parent); + } + } + /** A group containing the sync promo. */ class SyncPromoGroup extends PromoGroup { @Override @@ -1066,7 +1080,11 @@ } break; case SyncPromoState.PROMO_FOR_SIGNED_OUT_STATE: - addGroup(new PersonalizedSyncPromoGroup(ChildType.PERSONALIZED_SIGNIN_PROMO)); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP)) { + addGroup(new SigninPromoGroup()); + } else { + addGroup(new PersonalizedSyncPromoGroup(ChildType.PERSONALIZED_SIGNIN_PROMO)); + } break; case SyncPromoState.PROMO_FOR_SIGNED_IN_STATE: addGroup(new PersonalizedSyncPromoGroup(ChildType.PERSONALIZED_SYNC_PROMO));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java index 72844b8..d2f1a5bc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java
@@ -152,8 +152,6 @@ // not great to dynamically remove the preference in this way. case SiteSettingsCategory.Type.ADS: return SiteSettingsCategory.adsCategoryEnabled(); - case SiteSettingsCategory.Type.ANTI_ABUSE: - return ChromeFeatureList.isEnabled(ChromeFeatureList.PRIVATE_STATE_TOKENS); case SiteSettingsCategory.Type.AUTO_DARK_WEB_CONTENT: return ChromeFeatureList.isEnabled( ChromeFeatureList.DARKEN_WEBSITES_CHECKBOX_IN_THEMES_SETTING);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardCoordinator.java index 9a96e6a..90ce828 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardCoordinator.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.sync.ui.bookmark_batch_upload_card; import android.app.Activity; -import android.content.Context; import android.view.View; import androidx.lifecycle.LifecycleOwner; @@ -14,7 +13,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.ui.UiUtils; -import org.chromium.ui.modaldialog.ModalDialogManagerHolder; +import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; @@ -25,7 +24,9 @@ private PropertyModelChangeProcessor mPropertyModelChangeProcessor; public BookmarkBatchUploadCardCoordinator( - Context context, + Activity activity, + LifecycleOwner lifecycleOwner, + ModalDialogManager modalDialogManager, Profile profile, SnackbarManager snackbarManager, Runnable batchUploadCardChangeAction) { @@ -38,16 +39,16 @@ .with( BookmarkBatchUploadCardProperties.ICON, UiUtils.getTintedDrawable( - context, + activity, R.drawable.ic_cloud_upload_24dp, R.color.default_icon_color_accent1_tint_list)) .build(); mMediator = new BookmarkBatchUploadCardMediator( - (Activity) context, - (LifecycleOwner) context, - (ModalDialogManagerHolder) context, + activity, + lifecycleOwner, + modalDialogManager, profile, mModel, snackbarManager, @@ -68,8 +69,8 @@ mModel, view, BookmarkBatchUploadCardBinder::bind); } - public void hideBatchUploadCardAndUpdate() { - mMediator.hideBatchUploadCardAndUpdate(); + public void immediatelyHideBatchUploadCardAndUpdateItsVisibility() { + mMediator.immediatelyHideBatchUploadCardAndUpdateItsVisibility(); } public boolean shouldShowBatchUploadCard() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardMediator.java index 30ed8d8..47f230d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardMediator.java
@@ -28,7 +28,6 @@ import org.chromium.components.sync.SyncService; import org.chromium.components.sync.TransportState; import org.chromium.ui.modaldialog.ModalDialogManager; -import org.chromium.ui.modaldialog.ModalDialogManagerHolder; import org.chromium.ui.modelutil.PropertyModel; import java.util.HashMap; @@ -40,7 +39,7 @@ new DefaultLifecycleObserver() { @Override public void onResume(LifecycleOwner lifecycleOwner) { - hideBatchUploadCardAndUpdate(); + immediatelyHideBatchUploadCardAndUpdateItsVisibility(); } @Override @@ -65,8 +64,7 @@ * @param activity The {@link Activity} associated with the card. * @param lifecycleOwner {@link LifecycleOwner} that can be used to listen for activity * destruction. - * @param modalDialogManagerHolder {@link ModalDialogManagerHolder} that can be used to display - * the dialog. + * @param modalDialogManager {@link ModalDialogManager} that can be used to display the dialog. * @param profile {@link Profile} that is associated with the card. * @param model {@link PropertyModel} that is associated with the card. * @param snackbarManager {@link SnackbarManager} used to display snackbars. @@ -75,7 +73,7 @@ public BookmarkBatchUploadCardMediator( Activity activity, LifecycleOwner lifecycleOwner, - ModalDialogManagerHolder modalDialogManagerHolder, + ModalDialogManager modalDialogManager, Profile profile, PropertyModel model, SnackbarManager snackbarManager, @@ -93,7 +91,7 @@ mReauthenticatorBridge = ReauthenticatorBridge.create( activity, mProfile, DeviceAuthSource.BOOKMARK_BATCH_UPLOAD); - mDialogManager = modalDialogManagerHolder.getModalDialogManager(); + mDialogManager = modalDialogManager; lifecycleOwner.getLifecycle().addObserver(mLifeCycleObserver); @@ -114,10 +112,12 @@ return mShouldBeVisible; } - /** Hides the batch upload card and updates the batch upload card view. */ - public void hideBatchUploadCardAndUpdate() { - // Temporarily hide, it will become visible again once getLocalDataDescriptions() completes, - // which is triggered from updateBatchUploadCard(). + /** + * To ensure a smooth user experience, the batch upload card is immediately hidden before any + * asynchronous updates occur. This prevents a potential delay in hiding the card if the updated + * visibility state is set to 'off', which could lead to an inconsistent UI. + */ + public void immediatelyHideBatchUploadCardAndUpdateItsVisibility() { mShouldBeVisible = false; mBatchUploadCardChangeAction.run(); updateBatchUploadCard(); @@ -162,7 +162,7 @@ Snackbar.TYPE_ACTION, Snackbar.UMA_BOOKMARK_BATCH_UPLOAD) .setSingleLine(false)); - hideBatchUploadCardAndUpdate(); + immediatelyHideBatchUploadCardAndUpdateItsVisibility(); } private void updateBatchUploadCard() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlagsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlagsTest.java index 96b7f93e..223241a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlagsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlagsTest.java
@@ -61,7 +61,6 @@ ChromeFeatureList.sDrawKeyNativeEdgeToEdge, ChromeFeatureList.sEdgeToEdgeBottomChin, ChromeFeatureList.sEdgeToEdgeWebOptIn, - ChromeFeatureList.sNewTabPageAndroidTriggerForPrerender2, ChromeFeatureList.sPostGetMyMemoryStateToBackground, ChromeFeatureList.sPrefetchBrowserInitiatedTriggers, ChromeFeatureList.sSafetyHubMagicStack,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java index 87ae5f1..2ed7f1bf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RecentTabsPageTest.java
@@ -81,7 +81,10 @@ /** Instrumentation tests for {@link RecentTabsPage}. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@EnableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS}) +@EnableFeatures({ + ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS, + ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP +}) public class RecentTabsPageTest { private static final int COLOR_ID = TabGroupColorId.YELLOW; private static final int COLOR_ID_2 = TabGroupColorId.RED; @@ -485,6 +488,16 @@ } @Test + @MediumTest + @Feature({"RecentTabsPage", "RenderTest"}) + public void testSigninPromoView() throws Exception { + mSigninTestRule.addAccount(TestAccounts.ACCOUNT1); + mPage = loadRecentTabsPage(); + + mRenderTestRule.render(mPage.getView(), "signin_promo"); + } + + @Test @SmallTest @DisableFeatures(ChromeFeatureList.TAB_STRIP_LAYOUT_OPTIMIZATION) public void testTabStripHeightChangeCallback() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/BottomSheetSigninAndHistorySyncIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/BottomSheetSigninAndHistorySyncIntegrationTest.java index fb253db..1d27308 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/BottomSheetSigninAndHistorySyncIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/BottomSheetSigninAndHistorySyncIntegrationTest.java
@@ -240,10 +240,10 @@ verifyCollapsedBottomSheetAndSignin(TestAccounts.AADC_ADULT_ACCOUNT); // Verify that the history opt-in dialog is shown and decline. - onViewWaiting(withId(R.id.history_sync_illustration)).check(matches(isDisplayed())); + onViewWaiting(withId(R.id.history_sync_illustration), /* checkRootDialog= */ true) + .check(matches(isDisplayed())); // The user has just signed in, so the footer shouldn't show the email. - onViewWaiting(withId(R.id.history_sync_footer)) - .inRoot(isDialog()) + onViewWaiting(withId(R.id.history_sync_footer), /* checkRootDialog= */ true) .check( matches( allOf(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java index 36b9e01..82955e8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
@@ -1235,24 +1235,11 @@ settingsActivity.finish(); } - /** Test that showing the Site Settings menu does not contain the "Anti-abuse" row. */ - @Test - @SmallTest - @Feature({"Preferences"}) - @DisableFeatures(ChromeFeatureList.PRIVATE_STATE_TOKENS) - public void testSiteSettingsMenuWithPrivateStateTokensDisabled() { - final SettingsActivity settingsActivity = SiteSettingsTestUtils.startSiteSettingsMenu(""); - SiteSettings websitePreferences = (SiteSettings) settingsActivity.getMainFragment(); - assertNull(websitePreferences.findPreference("anti_abuse")); - settingsActivity.finish(); - } - /** Test that showing the Site Settings menu contains the "Anti-abuse" row. */ @Test @SmallTest @Feature({"Preferences"}) - @EnableFeatures(ChromeFeatureList.PRIVATE_STATE_TOKENS) - public void testSiteSettingsMenuWithPrivateStateTokensEnabled() { + public void testSiteSettingsMenuForAntiAbuse() { final SettingsActivity settingsActivity = SiteSettingsTestUtils.startSiteSettingsMenu(""); SiteSettings websitePreferences = (SiteSettings) settingsActivity.getMainFragment(); assertNotNull(websitePreferences.findPreference("anti_abuse")); @@ -1296,7 +1283,6 @@ @Test @SmallTest @Feature({"Preferences"}) - @EnableFeatures(ChromeFeatureList.PRIVATE_STATE_TOKENS) public void testOnlyExpectedPreferencesAntiAbuse() { testExpectedPreferences( SiteSettingsCategory.Type.ANTI_ABUSE,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java index 10197c7d..0d72d04 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java
@@ -10,6 +10,7 @@ import static androidx.test.espresso.intent.Intents.intended; import static androidx.test.espresso.intent.Intents.intending; import static androidx.test.espresso.matcher.RootMatchers.isDialog; +import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant; import static androidx.test.espresso.matcher.ViewMatchers.hasSibling; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withId; @@ -42,6 +43,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.PopupMenu; import androidx.fragment.app.FragmentTransaction; @@ -272,9 +274,10 @@ } @Test - @SmallTest - @Feature({"Sync"}) - public void testSyncAccountDataTypes() { + @LargeTest + @EnableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS}) + @DisableFeatures({ChromeFeatureList.LINKED_SERVICES_SETTING}) + public void testAccountSettingsView() { // The types that should be default-enabled in transport mode depend on various flags. Set<String> expectedEnabledTypes = new HashSet<>( @@ -296,6 +299,7 @@ mSyncTestRule.setUpAccountAndSignInForTesting(); ManageSyncSettings fragment = startManageSyncPreferences(); + Collection<ChromeSwitchPreference> dataTypes = getAccountDataTypes(fragment).values(); for (ChromeSwitchPreference dataType : dataTypes) { Assert.assertEquals( @@ -304,6 +308,38 @@ dataType.isChecked()); Assert.assertTrue(dataType.isEnabled()); } + + onView(withText(R.string.account_section_header)).check(matches(isDisplayed())); + + scrollToAndVerifyPresence(R.string.account_section_history_toggle); + + scrollToAndVerifyPresence(R.string.account_section_bookmarks_toggle); + + scrollToAndVerifyPresence(R.string.account_section_reading_list_toggle); + + scrollToAndVerifyPresence(R.string.account_section_addresses_toggle); + + scrollToAndVerifyPresence(R.string.account_section_passwords_toggle); + + scrollToAndVerifyPresence(R.string.account_section_payments_toggle); + + scrollToAndVerifyPresence(R.string.account_section_settings_toggle); + + scrollToAndVerifyPresence(R.string.account_section_footer); + + scrollToAndVerifyPresence(R.string.sign_in_google_activity_controls_title); + onView(withText(R.string.account_advanced_header)).check(matches(isDisplayed())); + onView(withText(R.string.sign_in_google_activity_controls_summary)) + .check(matches(isDisplayed())); + + scrollToAndVerifyPresence(R.string.sync_encryption); + + scrollToAndVerifyPresence(R.string.account_data_dashboard_title); + onView(withText(R.string.account_data_dashboard_subtitle)).check(matches(isDisplayed())); + + scrollToAndVerifyPresence(R.string.manage_your_google_account); + + scrollToAndVerifyPresence(R.string.account_android_device_accounts); } @Test @@ -2184,4 +2220,10 @@ ChromeRenderTestRule.sanitize(fragment.getView()); mRenderTestRule.render(fragment.getView(), skiaGoldId); } + + private void scrollToAndVerifyPresence(@StringRes int textId) { + onView(withId(R.id.recycler_view)) + .perform(RecyclerViewActions.scrollTo(hasDescendant(withText(textId)))); + onView(withText(textId)).check(matches(isDisplayed())); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java index 36287cf..ff678a4 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinatorTest.java
@@ -23,6 +23,7 @@ import org.mockito.junit.MockitoRule; import org.robolectric.annotation.Config; +import org.chromium.base.Promise; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Features; @@ -104,6 +105,7 @@ doReturn(mIdentityManager).when(mSigninManager).getIdentityManager(); doReturn(mIdentityManager).when(mIdentityServicesProvider).getIdentityManager(any()); AccountManagerFacadeProvider.setInstanceForTests(mAccountManagerFacade); + doReturn(new Promise<>()).when(mAccountManagerFacade).getCoreAccountInfos(); BookmarkModel.setInstanceForTesting(mBookmarkModel); ShoppingServiceFactory.setShoppingServiceForTesting(mShoppingService); ReauthenticatorBridge.setInstanceForTesting(mReauthenticatorMock); @@ -149,4 +151,18 @@ assertNotNull(BookmarkManagerCoordinator.buildVisualImprovedBookmarkRow(parent)); assertNotNull(mCoordinator.buildSearchBoxRow(parent)); } + + @Test + @EnableFeatures(ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP) + public void testCreateViewUNOPhase2FollowUpEnabled() { + FrameLayout parent = new FrameLayout(mActivity); + assertNotNull(mCoordinator.buildPersonalizedPromoView(parent)); + assertNotNull(mCoordinator.buildLegacyPromoView(parent)); + assertNotNull(mCoordinator.buildBatchUploadCardView(parent)); + assertNotNull(mCoordinator.buildSectionHeaderView(parent)); + assertNotNull(BookmarkManagerCoordinator.buildDividerView(parent)); + assertNotNull(BookmarkManagerCoordinator.buildCompactImprovedBookmarkRow(parent)); + assertNotNull(BookmarkManagerCoordinator.buildVisualImprovedBookmarkRow(parent)); + assertNotNull(mCoordinator.buildSearchBoxRow(parent)); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java index 3fc6f2a..ba16028 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediatorTest.java
@@ -38,6 +38,7 @@ import androidx.annotation.ColorInt; import androidx.annotation.StringRes; +import androidx.lifecycle.LifecycleOwner; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView.OnScrollListener; import androidx.test.ext.junit.rules.ActivityScenarioRule; @@ -57,6 +58,7 @@ import org.robolectric.shadows.ShadowLooper; import org.chromium.base.Callback; +import org.chromium.base.Promise; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.task.TaskTraits; import org.chromium.base.task.test.ShadowPostTask; @@ -77,6 +79,7 @@ import org.chromium.chrome.browser.commerce.PriceTrackingUtilsJni; import org.chromium.chrome.browser.commerce.ShoppingServiceFactory; import org.chromium.chrome.browser.commerce.ShoppingServiceFactoryJni; +import org.chromium.chrome.browser.device_reauth.BiometricStatus; import org.chromium.chrome.browser.device_reauth.ReauthenticatorBridge; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -114,6 +117,8 @@ import org.chromium.components.signin.AccountManagerFacade; import org.chromium.components.signin.AccountManagerFacadeProvider; import org.chromium.components.signin.identitymanager.IdentityManager; +import org.chromium.components.sync.DataType; +import org.chromium.components.sync.LocalDataDescription; import org.chromium.components.sync.SyncFeatureMap; import org.chromium.components.sync.SyncService; import org.chromium.components.sync.SyncService.SyncStateChangedListener; @@ -123,6 +128,7 @@ import org.chromium.ui.base.TestActivity; import org.chromium.ui.listmenu.BasicListMenu; import org.chromium.ui.listmenu.ListMenuItemProperties; +import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modelutil.ListObservable; import org.chromium.ui.modelutil.MVCListAdapter.ListItem; import org.chromium.ui.modelutil.MVCListAdapter.ModelList; @@ -133,7 +139,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Set; import java.util.function.BooleanSupplier; import java.util.function.Consumer; @@ -159,6 +167,7 @@ @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.LENIENT); + @Mock private ModalDialogManager mModalDialogManager; @Mock private BookmarkModel mBookmarkModel; @Mock private BookmarkOpener mBookmarkOpener; @Mock private SelectableListLayout<BookmarkId> mSelectableListLayout; @@ -425,6 +434,7 @@ doReturn(mIdentityManager).when(mSigninManager).getIdentityManager(); doReturn(mIdentityManager).when(mIdentityServicesProvider).getIdentityManager(any()); AccountManagerFacadeProvider.setInstanceForTests(mAccountManagerFacade); + doReturn(new Promise<>()).when(mAccountManagerFacade).getCoreAccountInfos(); // Setup image fetching. doAnswer( @@ -489,6 +499,8 @@ mMediator = new BookmarkManagerMediator( mActivity, + (LifecycleOwner) mActivity, + mModalDialogManager, mBookmarkModel, mBookmarkOpener, mSelectableListLayout, @@ -1618,6 +1630,225 @@ R.string.local_bookmarks_section_header, entry.getSectionHeaderData().titleRes); } + @Test + @EnableFeatures(ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP) + public void testRootLevelFolders_batchUploadCardPresentWhenLocalBookmarksExist() { + doReturn(true).when(mBookmarkModel).areAccountBookmarkFoldersActive(); + BookmarkId accountReadingListId = new BookmarkId(mId++, BookmarkType.READING_LIST); + BookmarkItem accountReadingListItem = + new BookmarkItem( + accountReadingListId, + "Reading list", + null, + /* isFolder= */ true, + mRootFolderId, + /* isEditable= */ false, + /* isManaged= */ false, + /* dateAdded= */ 0, + /* read= */ false, + /* dateLastOpened= */ 0, + /* isAccountBookmark= */ true); + doReturn(accountReadingListItem).when(mBookmarkModel).getBookmarkById(accountReadingListId); + doReturn( + Arrays.asList( + accountReadingListId, + mDesktopFolderId, + mMobileFolderId, + mOtherFolderId, + mReadingListFolderId)) + .when(mBookmarkModel) + .getTopLevelFolderIds(); + + doAnswer( + args -> { + HashMap<Integer, LocalDataDescription> localDataDescription = + new HashMap<>(); + localDataDescription.put( + DataType.PASSWORDS, + new LocalDataDescription(0, new String[] {}, 0)); + localDataDescription.put( + DataType.BOOKMARKS, + new LocalDataDescription(1, new String[] {"example.com"}, 1)); + localDataDescription.put( + DataType.READING_LIST, + new LocalDataDescription(0, new String[] {}, 0)); + args.getArgument(1, Callback.class).onResult(localDataDescription); + return null; + }) + .when(mSyncService) + .getLocalDataDescriptions( + eq(Set.of(DataType.BOOKMARKS, DataType.PASSWORDS, DataType.READING_LIST)), + any(Callback.class)); + mMediator + .getBookmarkBatchUploadCardCoordinator() + .immediatelyHideBatchUploadCardAndUpdateItsVisibility(); + + mBookmarkUiPrefs.setBookmarkRowSortOrder(BookmarkRowSortOrder.ALPHABETICAL); + finishLoading(); + + mMediator.openFolder(mRootFolderId); + + assertEquals(9, mModelList.size()); + verifyCurrentBookmarkIds( + null, // Search bar + null, // Account heading + accountReadingListId, + null, // Local heading. + null, // batch upload card + mDesktopFolderId, + mMobileFolderId, + mOtherFolderId, + mReadingListFolderId); + + assertEquals(ViewType.BATCH_UPLOAD_CARD, mModelList.get(4).type); + } + + @Test + @EnableFeatures(ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP) + public void testRootLevelFolders_batchUploadCardPresentWhenLocalReadingListItemsExist() { + doReturn(true).when(mBookmarkModel).areAccountBookmarkFoldersActive(); + BookmarkId accountReadingListId = new BookmarkId(mId++, BookmarkType.READING_LIST); + BookmarkItem accountReadingListItem = + new BookmarkItem( + accountReadingListId, + "Reading list", + null, + /* isFolder= */ true, + mRootFolderId, + /* isEditable= */ false, + /* isManaged= */ false, + /* dateAdded= */ 0, + /* read= */ false, + /* dateLastOpened= */ 0, + /* isAccountBookmark= */ true); + doReturn(accountReadingListItem).when(mBookmarkModel).getBookmarkById(accountReadingListId); + doReturn( + Arrays.asList( + accountReadingListId, + mDesktopFolderId, + mMobileFolderId, + mOtherFolderId, + mReadingListFolderId)) + .when(mBookmarkModel) + .getTopLevelFolderIds(); + + doAnswer( + args -> { + HashMap<Integer, LocalDataDescription> localDataDescription = + new HashMap<>(); + localDataDescription.put( + DataType.PASSWORDS, + new LocalDataDescription(0, new String[] {}, 0)); + localDataDescription.put( + DataType.BOOKMARKS, + new LocalDataDescription(0, new String[] {}, 0)); + localDataDescription.put( + DataType.READING_LIST, + new LocalDataDescription(1, new String[] {"example.com"}, 1)); + args.getArgument(1, Callback.class).onResult(localDataDescription); + return null; + }) + .when(mSyncService) + .getLocalDataDescriptions( + eq(Set.of(DataType.BOOKMARKS, DataType.PASSWORDS, DataType.READING_LIST)), + any(Callback.class)); + mMediator + .getBookmarkBatchUploadCardCoordinator() + .immediatelyHideBatchUploadCardAndUpdateItsVisibility(); + + mBookmarkUiPrefs.setBookmarkRowSortOrder(BookmarkRowSortOrder.ALPHABETICAL); + finishLoading(); + + mMediator.openFolder(mRootFolderId); + + assertEquals(9, mModelList.size()); + verifyCurrentBookmarkIds( + null, // Search bar + null, // Account heading + accountReadingListId, + null, // Local heading. + null, // batch upload card + mDesktopFolderId, + mMobileFolderId, + mOtherFolderId, + mReadingListFolderId); + + assertEquals(ViewType.BATCH_UPLOAD_CARD, mModelList.get(4).type); + } + + @Test + @EnableFeatures(ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP) + public void testRootLevelFolders_batchUploadCardDoesNotPresentWhenOnlyLocalPasswordsExist() { + doReturn(true).when(mBookmarkModel).areAccountBookmarkFoldersActive(); + BookmarkId accountReadingListId = new BookmarkId(mId++, BookmarkType.READING_LIST); + BookmarkItem accountReadingListItem = + new BookmarkItem( + accountReadingListId, + "Reading list", + null, + /* isFolder= */ true, + mRootFolderId, + /* isEditable= */ false, + /* isManaged= */ false, + /* dateAdded= */ 0, + /* read= */ false, + /* dateLastOpened= */ 0, + /* isAccountBookmark= */ true); + doReturn(accountReadingListItem).when(mBookmarkModel).getBookmarkById(accountReadingListId); + doReturn( + Arrays.asList( + accountReadingListId, + mDesktopFolderId, + mMobileFolderId, + mOtherFolderId, + mReadingListFolderId)) + .when(mBookmarkModel) + .getTopLevelFolderIds(); + + when(mReauthenticatorMock.getBiometricAvailabilityStatus()) + .thenReturn(BiometricStatus.BIOMETRICS_AVAILABLE); + doAnswer( + args -> { + HashMap<Integer, LocalDataDescription> localDataDescription = + new HashMap<>(); + localDataDescription.put( + DataType.PASSWORDS, + new LocalDataDescription(1, new String[] {"example.com"}, 1)); + localDataDescription.put( + DataType.BOOKMARKS, + new LocalDataDescription(0, new String[] {}, 0)); + localDataDescription.put( + DataType.READING_LIST, + new LocalDataDescription(0, new String[] {}, 0)); + args.getArgument(1, Callback.class).onResult(localDataDescription); + return null; + }) + .when(mSyncService) + .getLocalDataDescriptions( + eq(Set.of(DataType.BOOKMARKS, DataType.PASSWORDS, DataType.READING_LIST)), + any(Callback.class)); + mMediator + .getBookmarkBatchUploadCardCoordinator() + .immediatelyHideBatchUploadCardAndUpdateItsVisibility(); + + mBookmarkUiPrefs.setBookmarkRowSortOrder(BookmarkRowSortOrder.ALPHABETICAL); + finishLoading(); + + mMediator.openFolder(mRootFolderId); + + assertEquals(8, mModelList.size()); + // Make sure that batch upload card does not present. + verifyCurrentBookmarkIds( + null, // Search bar + null, // Account heading + accountReadingListId, + null, // Local heading. + mDesktopFolderId, + mMobileFolderId, + mOtherFolderId, + mReadingListFolderId); + } + // Tests directly related to a regression. @Test
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 71e6cbb..9ff923f 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
@@ -2183,7 +2183,7 @@ StripLayoutTab[] tabs = mStripLayoutHelper.getStripLayoutTabsForTesting(); // Start reorder for tab drop between the 2nd and 3rd tab. - mStripLayoutHelper.updateStripForExternalTabDrop(300.f); + mStripLayoutHelper.prepareForTabDrop(/* currX= */ 300.f, /* lastX= */ 0f, false, false); // Test tab outline should show for the foregrounded tab in destination window during tab // drop. @@ -2764,7 +2764,7 @@ mStripLayoutHelper.updateLayout(TIMESTAMP); // Start reorder for tab drop between the 1st and 2nd tab. - mStripLayoutHelper.updateStripForExternalTabDrop(150.f); + mStripLayoutHelper.prepareForTabDrop(/* currX= */ 150.f, /* lastX= */ 0f, false, false); float expectedEndWidth = expectedStartWidth @@ -2786,7 +2786,7 @@ ReorderDelegate reorderDelegateSpy = spy(mStripLayoutHelper.getReorderDelegateForTesting()); // Start and stop reorder mode for tab drop. - mStripLayoutHelper.updateStripForExternalTabDrop(10.f); + mStripLayoutHelper.prepareForTabDrop(/* currX= */ 10.f, /* lastX= */ 0f, false, false); mStripLayoutHelper.stopReorderModeForTesting(); // Verify: folio reattachment animation does not run for tab drop. @@ -4434,7 +4434,7 @@ float expectedOffsetX = 123.45f; mStripLayoutHelper.setActiveClickedTabAtIndexForTesting(0); mStripLayoutHelper.setLastOffsetXForTesting(expectedOffsetX); - mStripLayoutHelper.prepareForTabDrop(TIMESTAMP, 0f, 0f, true, false); + mStripLayoutHelper.prepareForTabDrop(0f, 0f, true, false); // Verify we continue reorder mode with the correct x-offset. assertFalse( @@ -4460,7 +4460,7 @@ // Drag tab out of strip. float expectedOffsetX = 123.45f; mStripLayoutHelper.setActiveClickedTabAtIndexForTesting(0); - mStripLayoutHelper.prepareForTabDrop(TIMESTAMP, 0f, 0f, true, false); + mStripLayoutHelper.prepareForTabDrop(0f, 0f, true, false); StripLayoutTab draggedTab = mStripLayoutHelper.getInteractingTabForTesting(); draggedTab.setOffsetX(expectedOffsetX); mStripLayoutHelper.clearForTabDrop(TIMESTAMP, true, false); @@ -4497,7 +4497,7 @@ // Drag tab out of strip. StripLayoutTab[] tabs = mStripLayoutHelper.getStripLayoutTabsForTesting(); mStripLayoutHelper.setTabAtPositionForTesting(tabs[1]); - mStripLayoutHelper.prepareForTabDrop(TIMESTAMP, 0f, 0f, true, false); + mStripLayoutHelper.prepareForTabDrop(0f, 0f, true, false); mStripLayoutHelper.clearForTabDrop(TIMESTAMP, true, false); mStripLayoutHelper.updateLayout(TIMESTAMP); @@ -4571,7 +4571,7 @@ mStripLayoutHelper.updateLayout(TIMESTAMP); // Prepare for tab drop. - mStripLayoutHelper.prepareForTabDrop(TIMESTAMP, 0.f, 0.f, false, false); + mStripLayoutHelper.prepareForTabDrop(0.f, 0.f, false, false); // Start gap will be tabWidth(265) / 2 = 132.5 mStripLayoutHelper.setScrollOffsetForTesting(-132); @@ -4624,7 +4624,7 @@ groupTabs(1, 3); // Prepare for tab drop. - mStripLayoutHelper.prepareForTabDrop(TIMESTAMP, 0.f, 0.f, false, false); + mStripLayoutHelper.prepareForTabDrop(0.f, 0.f, false, false); // Verify. StripLayoutTab[] tabs = mStripLayoutHelper.getStripLayoutTabsForTesting(); @@ -4660,7 +4660,7 @@ mStripLayoutHelper.updateLayout(TIMESTAMP); // Prepare for tab drop. - mStripLayoutHelper.prepareForTabDrop(TIMESTAMP, 0.f, 0.f, false, false); + mStripLayoutHelper.prepareForTabDrop(0.f, 0.f, false, false); mStripLayoutHelper.finishAnimations(); // Verify initial trailing margins before hover. StripLayoutTab[] tabs = mStripLayoutHelper.getStripLayoutTabsForTesting(); @@ -4703,7 +4703,7 @@ mStripLayoutHelper.updateLayout(TIMESTAMP); // Prepare for tab drop. - mStripLayoutHelper.prepareForTabDrop(TIMESTAMP, 0.f, 0.f, false, false); + mStripLayoutHelper.prepareForTabDrop(0.f, 0.f, false, false); // Start gap will be tabWidth(265) / 2 = 132.5 mStripLayoutHelper.setScrollOffsetForTesting(-132); mStripLayoutHelper.finishAnimations(); @@ -4745,7 +4745,7 @@ SCREEN_WIDTH, SCREEN_HEIGHT, false, TIMESTAMP, PADDING_LEFT, PADDING_RIGHT); // Prepare and verify no interaction. - mStripLayoutHelper.prepareForTabDrop(TIMESTAMP, 0.f, 0.f, false, !isIncognito); + mStripLayoutHelper.prepareForTabDrop(0.f, 0.f, false, !isIncognito); assertFalse( "Shouldn't start reorder when dragged tab Incognito state is different.", mStripLayoutHelper.getInReorderModeForTesting());
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 4fd11ac8..bf11110 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
@@ -551,7 +551,7 @@ // Verify appropriate events are generated. // Strip prepares for drop on drag enter. verify(mSourceStripLayoutHelper, times(1)) - .prepareForTabDrop(anyLong(), anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); + .prepareForTabDrop(anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); // Stop reorder on drop. verify(mSourceStripLayoutHelper, times(1)).onUpOrCancel(anyLong()); // Verify tab is not moved. @@ -589,7 +589,7 @@ // Verify appropriate events are generated. // Strip prepares for drop on drag enter. verify(mSourceStripLayoutHelper, times(1)) - .prepareForTabDrop(anyLong(), anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); + .prepareForTabDrop(anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); // Strip clears state for drop on drag exit. verify(mSourceStripLayoutHelper, times(1)) .clearForTabDrop(anyLong(), anyBoolean(), anyBoolean()); @@ -620,7 +620,7 @@ // Verify appropriate events are generated. // Strip prepares for drop on drag enter. verify(mSourceStripLayoutHelper, times(1)) - .prepareForTabDrop(anyLong(), anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); + .prepareForTabDrop(anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); // Strip clears state for drop on drag exit. verify(mSourceStripLayoutHelper, times(1)) .clearForTabDrop(anyLong(), anyBoolean(), anyBoolean()); @@ -671,7 +671,7 @@ // Verify appropriate events are generated. // Strip prepares for drop on drag enter. verify(mSourceStripLayoutHelper, times(1)) - .prepareForTabDrop(anyLong(), anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); + .prepareForTabDrop(anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); // Strip clears state for drop on drag exit. verify(mSourceStripLayoutHelper, times(1)) .clearForTabDrop(anyLong(), anyBoolean(), anyBoolean()); @@ -829,7 +829,7 @@ verify(mSourceStripLayoutHelper, times(1)).clearTabDragState(); // Verify destination strip calls. verify(mDestStripLayoutHelper) - .prepareForTabDrop(anyLong(), anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); + .prepareForTabDrop(anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); verify(mDestStripLayoutHelper).onUpOrCancel(anyLong()); assertNull(ShadowToast.getLatestToast()); @@ -915,13 +915,13 @@ // Verify appropriate events are generated. // Source strip prepares for drop on drag enter. verify(mSourceStripLayoutHelper, times(1)) - .prepareForTabDrop(anyLong(), anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); + .prepareForTabDrop(anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); // Source strip clears state for drop on drag exit. verify(mSourceStripLayoutHelper, times(1)) .clearForTabDrop(anyLong(), anyBoolean(), anyBoolean()); // Destination strip prepares for drop on drag enter. verify(mDestStripLayoutHelper, times(1)) - .prepareForTabDrop(anyLong(), anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); + .prepareForTabDrop(anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); // Destination strip clears state for drop on drag exit. verify(mDestStripLayoutHelper, times(1)) .clearForTabDrop(anyLong(), anyBoolean(), anyBoolean()); @@ -957,7 +957,7 @@ // Verify appropriate events are generated. // Strip prepares for drop on drag enter. Entered twice. verify(mSourceStripLayoutHelper, times(2)) - .prepareForTabDrop(anyLong(), anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); + .prepareForTabDrop(anyFloat(), anyFloat(), anyBoolean(), anyBoolean()); // Stop reorder on drop. verify(mSourceStripLayoutHelper, times(1)).onUpOrCancel(anyLong()); // Verify tab is not moved.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardMediatorTest.java new file mode 100644 index 0000000..6095643f --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/sync/ui/bookmark_batch_upload_card/BookmarkBatchUploadCardMediatorTest.java
@@ -0,0 +1,202 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.sync.ui.bookmark_batch_upload_card; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; + +import android.app.Activity; + +import androidx.lifecycle.LifecycleOwner; +import androidx.test.ext.junit.rules.ActivityScenarioRule; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import org.chromium.base.Callback; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.Features.EnableFeatures; +import org.chromium.chrome.browser.device_reauth.ReauthenticatorBridge; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; +import org.chromium.chrome.browser.sync.SyncServiceFactory; +import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; +import org.chromium.components.signin.identitymanager.IdentityManager; +import org.chromium.components.sync.DataType; +import org.chromium.components.sync.LocalDataDescription; +import org.chromium.components.sync.SyncFeatureMap; +import org.chromium.components.sync.SyncService; +import org.chromium.ui.base.TestActivity; +import org.chromium.ui.modaldialog.ModalDialogManager; +import org.chromium.ui.modelutil.PropertyModel; + +import java.util.HashMap; +import java.util.Set; + +/** Unit tests for {@link BookmarkBatchUploadCardMediator}. */ +@RunWith(BaseRobolectricTestRunner.class) +@EnableFeatures({ + SyncFeatureMap.SYNC_ENABLE_BOOKMARKS_IN_TRANSPORT_MODE, + ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS, + ChromeFeatureList.UNO_PHASE_2_FOLLOW_UP +}) +public class BookmarkBatchUploadCardMediatorTest { + @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule(); + + @Rule + public ActivityScenarioRule<TestActivity> mActivityScenarioRule = + new ActivityScenarioRule<>(TestActivity.class); + + @Mock private ModalDialogManager mModalDialogManager; + @Mock private Profile mProfile; + @Mock private PropertyModel mModel; + @Mock private SnackbarManager mSnackbarManager; + @Mock private ReauthenticatorBridge mReauthenticatorMock; + @Mock private SyncService mSyncService; + @Mock private IdentityServicesProvider mIdentityServicesProvider; + @Mock private IdentityManager mIdentityManager; + + private Activity mActivity; + private BookmarkBatchUploadCardMediator mMediator; + + @Before + public void setUp() { + // Setup service mocks. + IdentityServicesProvider.setInstanceForTests(mIdentityServicesProvider); + SyncServiceFactory.setInstanceForTesting(mSyncService); + ReauthenticatorBridge.setInstanceForTesting(mReauthenticatorMock); + doReturn(mProfile).when(mProfile).getOriginalProfile(); + doReturn(mIdentityManager).when(mIdentityServicesProvider).getIdentityManager(any()); + } + + @Test + public void testBatchUploadCardDoesNotPresentWhenLocalBookmarksExist() { + doAnswer( + args -> { + HashMap<Integer, LocalDataDescription> localDataDescription = + new HashMap<>(); + localDataDescription.put( + DataType.PASSWORDS, + new LocalDataDescription(0, new String[] {}, 0)); + localDataDescription.put( + DataType.BOOKMARKS, + new LocalDataDescription(0, new String[] {}, 0)); + localDataDescription.put( + DataType.READING_LIST, + new LocalDataDescription(0, new String[] {}, 0)); + args.getArgument(1, Callback.class).onResult(localDataDescription); + return null; + }) + .when(mSyncService) + .getLocalDataDescriptions( + eq(Set.of(DataType.BOOKMARKS, DataType.PASSWORDS, DataType.READING_LIST)), + any(Callback.class)); + + mActivityScenarioRule + .getScenario() + .onActivity( + (activity) -> { + mMediator = + new BookmarkBatchUploadCardMediator( + activity, + (LifecycleOwner) activity, + mModalDialogManager, + mProfile, + mModel, + mSnackbarManager, + () -> {}); + }); + Assert.assertFalse(mMediator.shouldBeVisible()); + } + + @Test + public void testBatchUploadCardPresentWhenLocalBookmarksExist() { + doAnswer( + args -> { + HashMap<Integer, LocalDataDescription> localDataDescription = + new HashMap<>(); + localDataDescription.put( + DataType.PASSWORDS, + new LocalDataDescription(0, new String[] {}, 0)); + localDataDescription.put( + DataType.BOOKMARKS, + new LocalDataDescription(1, new String[] {"example.com"}, 1)); + localDataDescription.put( + DataType.READING_LIST, + new LocalDataDescription(0, new String[] {}, 0)); + args.getArgument(1, Callback.class).onResult(localDataDescription); + return null; + }) + .when(mSyncService) + .getLocalDataDescriptions( + eq(Set.of(DataType.BOOKMARKS, DataType.PASSWORDS, DataType.READING_LIST)), + any(Callback.class)); + + mActivityScenarioRule + .getScenario() + .onActivity( + (activity) -> { + mMediator = + new BookmarkBatchUploadCardMediator( + activity, + (LifecycleOwner) activity, + mModalDialogManager, + mProfile, + mModel, + mSnackbarManager, + () -> {}); + }); + Assert.assertTrue(mMediator.shouldBeVisible()); + } + + @Test + public void testBatchUploadCardPresentWhenLocalReadingListEntriesExist() { + doAnswer( + args -> { + HashMap<Integer, LocalDataDescription> localDataDescription = + new HashMap<>(); + localDataDescription.put( + DataType.PASSWORDS, + new LocalDataDescription(0, new String[] {}, 0)); + localDataDescription.put( + DataType.BOOKMARKS, + new LocalDataDescription(0, new String[] {}, 0)); + localDataDescription.put( + DataType.READING_LIST, + new LocalDataDescription(1, new String[] {"example.com"}, 1)); + args.getArgument(1, Callback.class).onResult(localDataDescription); + return null; + }) + .when(mSyncService) + .getLocalDataDescriptions( + eq(Set.of(DataType.BOOKMARKS, DataType.PASSWORDS, DataType.READING_LIST)), + any(Callback.class)); + + mActivityScenarioRule + .getScenario() + .onActivity( + (activity) -> { + mMediator = + new BookmarkBatchUploadCardMediator( + activity, + (LifecycleOwner) activity, + mModalDialogManager, + mProfile, + mModel, + mSnackbarManager, + () -> {}); + }); + Assert.assertTrue(mMediator.shouldBeVisible()); + } +}
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index 7bd839a..49170ad 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -842,12 +842,12 @@ other {These extensions are no longer supported. Chromium recommends that you remove them.}} </message> <message name="IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_DISABLED_SUBTITLE" desc="Subtitle text displayed in the manifest v2 deprecation message for a specific extension during the disabled stage."> - Chromium recommends that you remove it. <ph name="BEGIN_LINK"><a href="$1" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph> + Chromium recommends that you remove it. <ph name="BEGIN_LINK"><a href="$1" aria-description="$2" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph> </message> <message name="IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_DISABLED_SUBTITLE" desc="Subtitle text displayed in the manifest v2 deprecation panel for the disabled stage."> {NUM_EXTENSIONS, plural, - =1 {Chromium recommends that you remove it. <ph name="BEGIN_LINK"><a href="$1" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph>} - other {Chromium recommends that you remove them. <ph name="BEGIN_LINK"><a href="$1" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph>} + =1 {Chromium recommends that you remove it. <ph name="BEGIN_LINK"><a href="$1" aria-description="$2" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph>} + other {Chromium recommends that you remove them. <ph name="BEGIN_LINK"><a href="$1" aria-description="$2" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph>} } </message> <message name="IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_REMOVE_BUTTON_ACC_LABEL" desc="The (accessible) label for the button to remove an extension.">
diff --git a/chrome/app/chromium_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_DISABLED_SUBTITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_DISABLED_SUBTITLE.png.sha1 index f1ce84eb..cfbdd2be 100644 --- a/chrome/app/chromium_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_DISABLED_SUBTITLE.png.sha1 +++ b/chrome/app/chromium_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_DISABLED_SUBTITLE.png.sha1
@@ -1 +1 @@ -51109250ee9a597255bee808eec128056ffcbd3b \ No newline at end of file +3f74352f1dca03d122fe6d76cbafc9c56b9d3e20 \ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_DISABLED_SUBTITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_DISABLED_SUBTITLE.png.sha1 index 40bcb35..41fd2a4 100644 --- a/chrome/app/chromium_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_DISABLED_SUBTITLE.png.sha1 +++ b/chrome/app/chromium_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_DISABLED_SUBTITLE.png.sha1
@@ -1 +1 @@ -03a18e35b9c9240c115fd21b4bd198d5d1043a00 \ No newline at end of file +5dad491f9445f728fb9889b8df0948f5b0c238ca \ No newline at end of file
diff --git a/chrome/app/extensions_strings.grdp b/chrome/app/extensions_strings.grdp index 87701e4..7549a62 100644 --- a/chrome/app/extensions_strings.grdp +++ b/chrome/app/extensions_strings.grdp
@@ -616,8 +616,8 @@ </message> <message name="IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_WARNING_SUBTITLE" desc="Subtitle text displayed in the manifest v2 deprecation panel for the warning stage."> {NUM_EXTENSIONS, plural, - =1 {Remove or replace it with similar extensions from the <ph name="BEGIN_LINK"><a href="$1" target="_blank"></ph>Chrome Web Store<ph name="END_LINK"></a></ph>.} - other {Remove or replace them with similar extensions from the <ph name="BEGIN_LINK"><a href="$1" target="_blank"></ph>Chrome Web Store<ph name="END_LINK"></a></ph>} + =1 {Remove or replace it with similar extensions from the <ph name="BEGIN_LINK"><a href="$1" aria-description="$2" target="_blank"></ph>Chrome Web Store<ph name="END_LINK"></a></ph>.} + other {Remove or replace them with similar extensions from the <ph name="BEGIN_LINK"><a href="$1" aria-description="$2" target="_blank"></ph>Chrome Web Store<ph name="END_LINK"></a></ph>} } </message> <message name="IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_DISABLED_HEADER" desc="Header text displayed in the manifest v2 deprecation panel for the disabled stage."> @@ -630,7 +630,7 @@ This extension may soon no longer be supported </message> <message name="IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_WARNING_SUBTITLE" desc="Subtitle text displayed in the manifest v2 deprecation message for a specific extension during the warning stage."> - Remove or replace it with similar extensions from the <ph name="BEGIN_LINK"><a href="$1" target="_blank"></ph>Chrome Web Store<ph name="END_LINK"></a></ph> + Remove or replace it with similar extensions from the <ph name="BEGIN_LINK"><a href="$1" aria-description="$2" target="_blank"></ph>Chrome Web Store<ph name="END_LINK"></a></ph> </message> <message name="IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_DISABLED_HEADER" desc="Header text displayed in the manifest v2 deprecation message for a specific extension during the disabled stage."> This extension was turned off because it is no longer supported
diff --git a/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_WARNING_SUBTITLE.png.sha1 b/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_WARNING_SUBTITLE.png.sha1 index 64ee341..ac03adeb 100644 --- a/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_WARNING_SUBTITLE.png.sha1 +++ b/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_WARNING_SUBTITLE.png.sha1
@@ -1 +1 @@ -bb129a1552f68c320d75411ffd7894db6f775090 \ No newline at end of file +900c2a4208ad2fac571bfb55b8848dddf4bac822 \ No newline at end of file
diff --git a/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_WARNING_SUBTITLE.png.sha1 b/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_WARNING_SUBTITLE.png.sha1 index ad2ca8d9..0d76a95 100644 --- a/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_WARNING_SUBTITLE.png.sha1 +++ b/chrome/app/extensions_strings_grdp/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_WARNING_SUBTITLE.png.sha1
@@ -1 +1 @@ -f8da40787e3b7451de3ecc2c81152309ea16c00b \ No newline at end of file +9d48a07784a56cb7520a07d18f7bf20180b85384 \ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index ac7e239..059f686 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -9047,6 +9047,12 @@ <message name="IDS_BOOKMARKS_ALL_BOOKMARKS_OPEN_SIDE_PANEL" desc="The bookmarks bar menu item which opens the side panel"> Open Side Panel to see All Bookmarks </message> + <message name="IDS_BOOKMARKS_ACCOUNT_BOOKMARKS" desc="The header used for account bookmarks"> + In your Google Account + </message> + <message name="IDS_BOOKMARKS_DEVICE_BOOKMARKS" desc="The header used for device bookmarks"> + Only on this device + </message> <message name="IDS_BOOKMARKS_LABEL_TRACKED_PRODUCTS" desc="Label on a button within the bookmarks side panel for filtering bookmarks by price tracking data."> Tracked products </message>
diff --git a/chrome/app/generated_resources_grd/IDS_BOOKMARKS_ACCOUNT_BOOKMARKS.png.sha1 b/chrome/app/generated_resources_grd/IDS_BOOKMARKS_ACCOUNT_BOOKMARKS.png.sha1 new file mode 100644 index 0000000..7ce1058 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_BOOKMARKS_ACCOUNT_BOOKMARKS.png.sha1
@@ -0,0 +1 @@ +2d3850a07d3e002a7ed83b79e6bc0563aacdf8b0 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_BOOKMARKS_DEVICE_BOOKMARKS.png.sha1 b/chrome/app/generated_resources_grd/IDS_BOOKMARKS_DEVICE_BOOKMARKS.png.sha1 new file mode 100644 index 0000000..7ce1058 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_BOOKMARKS_DEVICE_BOOKMARKS.png.sha1
@@ -0,0 +1 @@ +2d3850a07d3e002a7ed83b79e6bc0563aacdf8b0 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index 34d54eb..9f8fc4d 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -821,12 +821,12 @@ other {These extensions are no longer supported. Chrome recommends that you remove them.}} </message> <message name="IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_DISABLED_SUBTITLE" desc="Subtitle text displayed in the manifest v2 deprecation message for a specific extension during the disabled stage."> - Chrome recommends that you remove it. <ph name="BEGIN_LINK"><a href="$1" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph> + Chrome recommends that you remove it. <ph name="BEGIN_LINK"><a href="$1" aria-description="$2" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph> </message> <message name="IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_DISABLED_SUBTITLE" desc="Subtitle text displayed in the manifest v2 deprecation panel for the disabled stage."> {NUM_EXTENSIONS, plural, - =1 {Chrome recommends that you remove it. <ph name="BEGIN_LINK"><a href="$1" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph>} - other {Chrome recommends that you remove them. <ph name="BEGIN_LINK"><a href="$1" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph>} + =1 {Chrome recommends that you remove it. <ph name="BEGIN_LINK"><a href="$1" aria-description="$2" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph>} + other {Chrome recommends that you remove them. <ph name="BEGIN_LINK"><a href="$1" aria-description="$2" target="_blank"></ph>Learn more about supported extensions<ph name="END_LINK"></a></ph>} } </message> <message name="IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_REMOVE_BUTTON_ACC_LABEL" desc="The (accessible) label for the button to remove an extension.">
diff --git a/chrome/app/google_chrome_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_DISABLED_SUBTITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_DISABLED_SUBTITLE.png.sha1 index f1ce84eb..cfbdd2be 100644 --- a/chrome/app/google_chrome_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_DISABLED_SUBTITLE.png.sha1 +++ b/chrome/app/google_chrome_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_MESSAGE_DISABLED_SUBTITLE.png.sha1
@@ -1 +1 @@ -51109250ee9a597255bee808eec128056ffcbd3b \ No newline at end of file +3f74352f1dca03d122fe6d76cbafc9c56b9d3e20 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_DISABLED_SUBTITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_DISABLED_SUBTITLE.png.sha1 index 726efdc..41fd2a4 100644 --- a/chrome/app/google_chrome_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_DISABLED_SUBTITLE.png.sha1 +++ b/chrome/app/google_chrome_strings_grd/IDS_EXTENSIONS_MV2_DEPRECATION_PANEL_DISABLED_SUBTITLE.png.sha1
@@ -1 +1 @@ -f96407801d32947cdd8f677ddcc91a713d9a2de6 \ No newline at end of file +5dad491f9445f728fb9889b8df0948f5b0c238ca \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index cb71845f..7b82313 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3493,6 +3493,10 @@ "accessibility/embedded_a11y_extension_loader.h", "accessibility/invert_bubble_prefs.cc", "accessibility/invert_bubble_prefs.h", + "accessibility/live_caption/live_caption_controller_factory.cc", + "accessibility/live_caption/live_caption_controller_factory.h", + "accessibility/live_caption/live_caption_speech_recognition_host.cc", + "accessibility/live_caption/live_caption_speech_recognition_host.h", "accessibility/live_translate_controller_factory.cc", "accessibility/live_translate_controller_factory.h", "accessibility/phrase_segmentation/dependency_parser_model_loader.cc", @@ -3702,6 +3706,8 @@ "lifetime/application_lifetime_desktop.h", "lifetime/browser_close_manager.cc", "lifetime/browser_close_manager.h", + "media/audio_ducker.cc", + "media/audio_ducker.h", "media/cast_mirroring_service_host.cc", "media/cast_mirroring_service_host.h", "media/cast_mirroring_service_host_factory.cc", @@ -4514,15 +4520,6 @@ [ "//chrome/browser/ui/webui/signin:profile_impl" ] } - if (!is_chromeos_lacros) { - sources += [ - "accessibility/live_caption/live_caption_controller_factory.cc", - "accessibility/live_caption/live_caption_controller_factory.h", - "accessibility/live_caption/live_caption_speech_recognition_host.cc", - "accessibility/live_caption/live_caption_speech_recognition_host.h", - ] - } - if (!is_win) { # On Windows, the hashes are embedded in //chrome:chrome_initial rather # than here in :chrome_dll. @@ -5795,8 +5792,6 @@ if (is_chromeos_lacros) { sources += [ - "accessibility/live_caption/live_caption_surface.cc", - "accessibility/live_caption/live_caption_surface.h", "apps/digital_goods/digital_goods_factory_stub.cc", "apps/digital_goods/digital_goods_factory_stub.h", "apps/digital_goods/digital_goods_lacros.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 17ecd3717..19c4936 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -307,7 +307,6 @@ #include "chromeos/ash/components/assistant/buildflags.h" #include "chromeos/ash/components/memory/swap_configuration.h" #include "chromeos/ash/components/standalone_browser/channel_util.h" -#include "chromeos/ash/components/standalone_browser/lacros_availability.h" #include "chromeos/ash/components/standalone_browser/lacros_selection.h" #include "chromeos/ash/components/standalone_browser/standalone_browser_features.h" #include "chromeos/ash/services/assistant/public/cpp/features.h" @@ -1021,8 +1020,6 @@ std::size(kZinkEnableRecommended), nullptr}, {"for all apps", kZinkEnableAll, std::size(kZinkEnableAll), nullptr}}; -const char kLacrosAvailabilityIgnoreInternalName[] = - "lacros-availability-ignore"; const char kLacrosWaylandLoggingInternalName[] = "lacros-wayland-logging"; const char kArcEnableVirtioBlkForDataInternalName[] = "arc-enable-virtio-blk-for-data"; @@ -1044,19 +1041,6 @@ const char kLacrosSelectionPolicyIgnoreInternalName[] = "lacros-selection-ignore"; -const FeatureEntry::Choice kLacrosAvailabilityPolicyChoices[] = { - {flags_ui::kGenericExperimentChoiceDefault, "", ""}, - {ash::standalone_browser::kLacrosAvailabilityPolicyUserChoice, - ash::standalone_browser::kLacrosAvailabilityPolicySwitch, - ash::standalone_browser::kLacrosAvailabilityPolicyUserChoice}, - {ash::standalone_browser::kLacrosAvailabilityPolicyLacrosDisabled, - ash::standalone_browser::kLacrosAvailabilityPolicySwitch, - ash::standalone_browser::kLacrosAvailabilityPolicyLacrosDisabled}, - {ash::standalone_browser::kLacrosAvailabilityPolicyLacrosOnly, - ash::standalone_browser::kLacrosAvailabilityPolicySwitch, - ash::standalone_browser::kLacrosAvailabilityPolicyLacrosOnly}, -}; - const char kArcEnableAttestationFlag[] = "arc-enable-attestation"; #endif // BUILDFLAG(IS_CHROMEOS) @@ -4793,9 +4777,6 @@ FEATURE_VALUE_TYPE(ash::features::kEnableBrightnessControlInSettings), }, // Used to carry the policy value crossing the Chrome process lifetime. - {ash::standalone_browser::kLacrosAvailabilityPolicyInternalName, "", "", - kOsCrOS, MULTI_VALUE_TYPE(kLacrosAvailabilityPolicyChoices)}, - // Used to carry the policy value crossing the Chrome process lifetime. {kLacrosWaylandLoggingInternalName, flag_descriptions::kLacrosWaylandLoggingName, flag_descriptions::kLacrosWaylandLoggingDescription, kOsCrOS, @@ -4816,10 +4797,6 @@ flag_descriptions::kLacrosSelectionPolicyIgnoreName, flag_descriptions::kLacrosSelectionPolicyIgnoreDescription, kOsCrOS, SINGLE_VALUE_TYPE(ash::switches::kLacrosSelectionPolicyIgnore)}, - {kLacrosAvailabilityIgnoreInternalName, - flag_descriptions::kLacrosAvailabilityIgnoreName, - flag_descriptions::kLacrosAvailabilityIgnoreDescription, kOsCrOS, - SINGLE_VALUE_TYPE(ash::switches::kLacrosAvailabilityIgnore)}, {"list-all-display-modes", flag_descriptions::kListAllDisplayModesName, flag_descriptions::kListAllDisplayModesDescription, kOsCrOS, FEATURE_VALUE_TYPE(display::features::kListAllDisplayModes)}, @@ -6989,16 +6966,6 @@ #endif // BUILDFLAG(IS_ANDROID) #if !BUILDFLAG(IS_ANDROID) - {"shopping-icon-color-variant", - commerce::flag_descriptions::kShoppingIconColorVariantName, - commerce::flag_descriptions::kShoppingIconColorVariantDescription, - kOsDesktop, FEATURE_VALUE_TYPE(commerce::kShoppingIconColorVariant)}, - - {"price-tracking-icon-colors", - commerce::flag_descriptions::kPriceTrackingIconColorsDescription, - commerce::flag_descriptions::kPriceTrackingIconColorsDescription, - kOsDesktop, FEATURE_VALUE_TYPE(commerce::kPriceTrackingIconColors)}, - {"enable-retail-coupons", flag_descriptions::kRetailCouponsName, flag_descriptions::kRetailCouponsDescription, kOsDesktop, FEATURE_VALUE_TYPE(commerce::kRetailCoupons)}, @@ -8938,6 +8905,10 @@ flag_descriptions::kFedCmButtonModeDescription, kOsAll, FEATURE_VALUE_TYPE(features::kFedCmButtonMode)}, + {"fedcm-delegation", flag_descriptions::kFedCmDelegationName, + flag_descriptions::kFedCmDelegationDescription, kOsAll, + FEATURE_VALUE_TYPE(features::kFedCmDelegation)}, + {"fedcm-idp-registration", flag_descriptions::kFedCmIdPRegistrationName, flag_descriptions::kFedCmIdPRegistrationDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kFedCmIdPRegistration)}, @@ -9575,6 +9546,11 @@ flag_descriptions::kProjectorGm3Description, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kProjectorGm3)}, + {"projector-use-dvs-playback-endpoint", + flag_descriptions::kProjectorUseDVSPlaybackEndpointName, + flag_descriptions::kProjectorUseDVSPlaybackEndpointDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kProjectorUseDVSPlaybackEndpoint)}, + {"enable-annotator-mode", flag_descriptions::kAnnotatorModeName, flag_descriptions::kAnnotatorModeDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kAnnotatorMode)}, @@ -11990,13 +11966,6 @@ return true; } - // Skip lacros-availability-policy always. This is a pseudo entry - // and used to carry the policy value crossing the Chrome's lifetime. - if (!strcmp(ash::standalone_browser::kLacrosAvailabilityPolicyInternalName, - entry.internal_name)) { - return true; - } - // Skip lacros-selection if it is controlled by LacrosSelection policy. if (!strcmp(kLacrosSelectionInternalName, entry.internal_name)) { return ash::standalone_browser::GetCachedLacrosSelectionPolicy() !=
diff --git a/chrome/browser/accessibility/live_caption/live_caption_surface.cc b/chrome/browser/accessibility/live_caption/live_caption_surface.cc deleted file mode 100644 index f2181a8..0000000 --- a/chrome/browser/accessibility/live_caption/live_caption_surface.cc +++ /dev/null
@@ -1,116 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/accessibility/live_caption/live_caption_surface.h" - -#include <optional> - -#include "base/functional/callback_forward.h" -#include "base/unguessable_token.h" -#include "build/build_config.h" -#include "chrome/browser/accessibility/caption_bubble_context_browser.h" -#include "chrome/browser/accessibility/live_caption/live_caption_controller_factory.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "components/live_caption/live_caption_controller.h" -#include "components/live_caption/views/caption_bubble_model.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/page.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" -#include "ui/views/widget/widget.h" - -namespace captions { - -WEB_CONTENTS_USER_DATA_KEY_IMPL(LiveCaptionSurface); - -// static -LiveCaptionSurface* LiveCaptionSurface::GetOrCreateForWebContents( - content::WebContents* web_contents) { - // No-op if a surface is already attached. - CreateForWebContents(web_contents); - - return FromWebContents(web_contents); -} - -LiveCaptionSurface::LiveCaptionSurface(content::WebContents* web_contents) - : content::WebContentsUserData<LiveCaptionSurface>(*web_contents), - content::WebContentsObserver(web_contents), - session_id_(base::UnguessableToken::Create()) {} - -LiveCaptionSurface::~LiveCaptionSurface() = default; - -void LiveCaptionSurface::BindToSurfaceClient( - mojo::PendingReceiver<media::mojom::SpeechRecognitionSurface> receiver, - mojo::PendingRemote<media::mojom::SpeechRecognitionSurfaceClient> remote) { - receivers_.Add(this, std::move(receiver)); - clients_.Add(std::move(remote)); -} - -void LiveCaptionSurface::Activate() { - if (!web_contents()) { - return; - } - - // Activate the web contents and the browser window that the web contents is - // in. Order matters: web contents needs to be active in order for the widget - // getter to work. - Browser* browser = chrome::FindBrowserWithTab(web_contents()); - if (!browser) { - return; - } - - TabStripModel* tab_strip_model = browser->tab_strip_model(); - DCHECK(tab_strip_model); - - const int index = tab_strip_model->GetIndexOfWebContents(web_contents()); - if (index == TabStripModel::kNoTab) { - return; - } - - tab_strip_model->ActivateTabAt(index); - views::Widget* context_widget = views::Widget::GetTopLevelWidgetForNativeView( - web_contents()->GetNativeView()); - if (context_widget) { - context_widget->Activate(); - } -} - -void LiveCaptionSurface::GetBounds(GetBoundsCallback callback) { - if (!web_contents()) { - std::move(callback).Run(std::nullopt); - return; - } - - views::Widget* context_widget = views::Widget::GetTopLevelWidgetForNativeView( - web_contents()->GetNativeView()); - if (!context_widget) { - std::move(callback).Run(std::nullopt); - return; - } - - std::move(callback).Run(context_widget->GetClientAreaBoundsInScreen()); -} - -void LiveCaptionSurface::MediaEffectivelyFullscreenChanged( - bool /*is_fullscreen*/) { - for (const auto& client : clients_) { - client->OnFullscreenToggled(); - } -} - -void LiveCaptionSurface::PrimaryPageChanged(content::Page& /*page*/) { - for (const auto& client : clients_) { - client->OnSessionEnded(); - } -} - -base::UnguessableToken LiveCaptionSurface::session_id() const { - return session_id_; -} - -} // namespace captions
diff --git a/chrome/browser/accessibility/live_caption/live_caption_surface.h b/chrome/browser/accessibility/live_caption/live_caption_surface.h deleted file mode 100644 index 592dc3e..0000000 --- a/chrome/browser/accessibility/live_caption/live_caption_surface.h +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ACCESSIBILITY_LIVE_CAPTION_LIVE_CAPTION_SURFACE_H_ -#define CHROME_BROWSER_ACCESSIBILITY_LIVE_CAPTION_LIVE_CAPTION_SURFACE_H_ - -#include "base/unguessable_token.h" -#include "build/build_config.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" -#include "media/mojo/mojom/speech_recognition.mojom.h" -#include "mojo/public/cpp/bindings/pending_receiver.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "mojo/public/cpp/bindings/receiver_set.h" -#include "mojo/public/cpp/bindings/remote_set.h" - -namespace content { -class Page; -class WebContents; -} // namespace content - -namespace captions { - -// Represents the document as a user-facing surface that produces live captions. -// This interface allows remote processes to manipulate the document as required -// for live caption rendering (e.g. by bringing it into focus). -// -// An instance of this object is owned by a `WebContents` and its lifetime is -// bound to the `WebContents`' lifetime. Up to one instance of this class can -// be instantiated for a single `WebContents`. -class LiveCaptionSurface - : public media::mojom::SpeechRecognitionSurface, - public content::WebContentsUserData<LiveCaptionSurface>, - public content::WebContentsObserver { - public: - LiveCaptionSurface(const LiveCaptionSurface&) = delete; - LiveCaptionSurface& operator=(const LiveCaptionSurface&) = delete; - ~LiveCaptionSurface() override; - - // static - static LiveCaptionSurface* GetOrCreateForWebContents( - content::WebContents* web_contents); - - // Set up coordintation with a new surface client in Ash. - void BindToSurfaceClient( - mojo::PendingReceiver<media::mojom::SpeechRecognitionSurface> receiver, - mojo::PendingRemote<media::mojom::SpeechRecognitionSurfaceClient> remote); - - // media::mojom::SpeechRecognitionSurface: - void Activate() override; - void GetBounds(GetBoundsCallback callback) override; - - // content::WebContentsObserver: - void MediaEffectivelyFullscreenChanged(bool is_fullscreen) override; - void PrimaryPageChanged(content::Page& page) override; - - // Returns a unique identifier for the current web contents. - base::UnguessableToken session_id() const; - - private: - friend content::WebContentsUserData<LiveCaptionSurface>; - WEB_CONTENTS_USER_DATA_KEY_DECL(); - - explicit LiveCaptionSurface(content::WebContents* web_contents); - - const base::UnguessableToken session_id_; - - mojo::ReceiverSet<media::mojom::SpeechRecognitionSurface> receivers_; - mojo::RemoteSet<media::mojom::SpeechRecognitionSurfaceClient> clients_; -}; - -} // namespace captions - -#endif // CHROME_BROWSER_ACCESSIBILITY_LIVE_CAPTION_LIVE_CAPTION_SURFACE_H_
diff --git a/chrome/browser/ai/ai_language_model.cc b/chrome/browser/ai/ai_language_model.cc index 2721c788..7881008 100644 --- a/chrome/browser/ai/ai_language_model.cc +++ b/chrome/browser/ai/ai_language_model.cc
@@ -9,6 +9,7 @@ #include <sstream> #include "base/check_op.h" +#include "base/feature_list.h" #include "base/functional/bind.h" #include "base/functional/callback_forward.h" #include "base/notreached.h" @@ -30,6 +31,23 @@ #include "third_party/blink/public/mojom/ai/ai_manager.mojom-shared.h" #include "third_party/blink/public/mojom/ai/model_streaming_responder.mojom.h" +namespace features { + +// Indicates the streaming behavior of this session. +// If it's true, each streaming response will contain the full content that's +// generated so far. e.g. +// - This is +// - This is a test +// - This is a test response. +// If it's false, the response will be streamed back chunk by chunk. e.g. +// - This is +// - a test +// - response. +BASE_FEATURE(kAILanguageModelForceStreamingFullResponse, + "AILanguageModelForceStreamingFullResponse", + base::FEATURE_DISABLED_BY_DEFAULT); + +} // namespace features namespace { using optimization_guide::proto::PromptApiMetadata; @@ -177,7 +195,8 @@ &AIContextBoundObject::RemoveFromSet, base::Unretained(this))); auto metadata = ParseMetadata(session_->GetOnDeviceFeatureMetadata()); - is_streaming_chunk_by_chunk_ = metadata.is_streaming_chunk_by_chunk(); + is_on_device_session_streaming_chunk_by_chunk_ = + metadata.is_streaming_chunk_by_chunk(); if (context.has_value()) { // If the context is provided, it will be used in this session. @@ -286,14 +305,26 @@ auto response = optimization_guide::ParsedAnyMetadata< optimization_guide::proto::StringValue>(result.response->response); - if (is_streaming_chunk_by_chunk_) { + std::string streaming_result = response->value(); + bool should_stream_full_response = base::FeatureList::IsEnabled( + features::kAILanguageModelForceStreamingFullResponse); + if (is_on_device_session_streaming_chunk_by_chunk_) { + // We need this for the context adding. current_response_ += response->value(); + if (should_stream_full_response) { + // Adapting the chunk-by-chunk mode to the current-response mode. + streaming_result = current_response_; + } } else { + if (!should_stream_full_response) { + // Adapting the current-response mode to the chunk-by-chunk mode. + streaming_result = response->value().substr(current_response_.size()); + } current_response_ = response->value(); } if (response->has_value()) { - responder->OnStreaming(current_response_); + responder->OnStreaming(streaming_result); } if (result.response->is_complete) { // TODO(crbug.com/351935390): instead of calculating this from the
diff --git a/chrome/browser/ai/ai_language_model.h b/chrome/browser/ai/ai_language_model.h index 4664b6c..80c43942 100644 --- a/chrome/browser/ai/ai_language_model.h +++ b/chrome/browser/ai/ai_language_model.h
@@ -8,6 +8,7 @@ #include <deque> #include <optional> +#include "base/feature_list.h" #include "base/functional/callback_forward.h" #include "base/memory/weak_ptr.h" #include "base/types/expected.h" @@ -23,6 +24,12 @@ #include "third_party/blink/public/mojom/ai/ai_manager.mojom-forward.h" #include "third_party/blink/public/mojom/ai/model_streaming_responder.mojom-forward.h" +namespace features { + +BASE_DECLARE_FEATURE(kAILanguageModelForceStreamingFullResponse); + +} // namespace features + class AIManager; // The implementation of `blink::mojom::AILanguageModel`, which exposes the APIs @@ -172,7 +179,7 @@ base::raw_ref<AIContextBoundObjectSet> context_bound_object_set_; base::raw_ref<AIManager> ai_manager_; - bool is_streaming_chunk_by_chunk_; + bool is_on_device_session_streaming_chunk_by_chunk_; // The accumulated current response to simulate the old streaming behavior // that always returns all the response generated so far. std::string current_response_;
diff --git a/chrome/browser/ai/ai_language_model_unittest.cc b/chrome/browser/ai/ai_language_model_unittest.cc index 98b8eeed..d2b37832 100644 --- a/chrome/browser/ai/ai_language_model_unittest.cc +++ b/chrome/browser/ai/ai_language_model_unittest.cc
@@ -159,8 +159,9 @@ } // namespace class AILanguageModelTest : public AITestUtils::AITestBase, - public testing::WithParamInterface< - /*is_model_streaming_chunk_by_chunk=*/bool> { + public testing::WithParamInterface<testing::tuple< + /*is_model_streaming_chunk_by_chunk=*/bool, + /*is_api_streaming_chunk_by_chunk=*/bool>> { public: struct Options { blink::mojom::AILanguageModelSamplingParamsPtr sampling_params = nullptr; @@ -176,16 +177,26 @@ }; void SetUp() override { - AITestUtils::AITestBase::SetUp(); - scoped_feature_list_.InitWithFeaturesAndParameters( - {base::test::FeatureRefAndParams( + std::vector<base::test::FeatureRefAndParams> enabled_features{ + base::test::FeatureRefAndParams( features::kAILanguageModelOverrideConfiguration, - {{"max_top_k", base::NumberToString(kOverrideMaxTopK)}})}, - {}); + {{"max_top_k", base::NumberToString(kOverrideMaxTopK)}})}; + std::vector<base::test::FeatureRef> disabled_features{}; + if (IsAPIStreamingChunkByChunk()) { + disabled_features.push_back( + features::kAILanguageModelForceStreamingFullResponse); + } else { + enabled_features.push_back(base::test::FeatureRefAndParams( + features::kAILanguageModelForceStreamingFullResponse, {})); + } + AITestUtils::AITestBase::SetUp(); + scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features, + disabled_features); } protected: - bool IsModelStreamingChunkByChunk() { return GetParam(); } + bool IsModelStreamingChunkByChunk() { return std::get<0>(GetParam()); } + bool IsAPIStreamingChunkByChunk() { return std::get<1>(GetParam()); } // The helper function that creates a `AILanguageModel` and executes the // prompt. @@ -261,6 +272,7 @@ EXPECT_THAT(ToString(request_metadata), options.expected_context); }); + EXPECT_CALL(*session, ExecuteModel(_, _)) .WillOnce( [&](const google::protobuf::MessageLite& request_metadata, @@ -269,8 +281,7 @@ callback) { EXPECT_THAT(ToString(request_metadata), options.expected_prompt); - callback.Run(CreateExecutionResult(kTestResponse, - /*is_complete=*/true)); + StreamResponse(callback); }); return session; }) @@ -298,8 +309,7 @@ callback) { EXPECT_THAT(ToString(request_metadata), options.expected_prompt); - callback.Run(CreateExecutionResult(kTestResponse, - /*is_complete=*/true)); + StreamResponse(callback); }); return session; }); @@ -436,15 +446,46 @@ }); } + void StreamResponse( + optimization_guide::OptimizationGuideModelExecutionResultStreamingCallback + callback) { + std::string responses[3]; + std::string response = std::string(kTestResponse); + if (IsModelStreamingChunkByChunk()) { + responses[0] = response.substr(0, 1); + responses[1] = response.substr(1); + responses[2] = ""; + } else { + responses[0] = response.substr(0, 1); + responses[1] = kTestResponse; + responses[2] = kTestResponse; + } + callback.Run(CreateExecutionResult(responses[0], + /*is_complete=*/false)); + callback.Run(CreateExecutionResult(responses[1], + /*is_complete=*/false)); + callback.Run(CreateExecutionResult(responses[2], + /*is_complete=*/true)); + } + void TestPromptCall(mojo::Remote<blink::mojom::AILanguageModel>& mock_session, std::string& prompt, bool should_overflow_context) { AITestUtils::MockModelStreamingResponder mock_responder; base::RunLoop responder_run_loop; + std::string response = std::string(kTestResponse); EXPECT_CALL(mock_responder, OnStreaming(_)) + .Times(3) .WillOnce(testing::Invoke([&](const std::string& text) { - EXPECT_THAT(text, kTestResponse); + EXPECT_THAT(text, response.substr(0, 1)); + })) + .WillOnce(testing::Invoke([&](const std::string& text) { + EXPECT_THAT(text, IsAPIStreamingChunkByChunk() ? response.substr(1) + : kTestResponse); + })) + .WillOnce(testing::Invoke([&](const std::string& text) { + EXPECT_THAT(text, IsAPIStreamingChunkByChunk() ? "" : kTestResponse); })); EXPECT_CALL(mock_responder, OnCompletion(_)) @@ -460,14 +501,21 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -INSTANTIATE_TEST_SUITE_P(All, - AILanguageModelTest, - testing::Bool(), - [](const testing::TestParamInfo<bool>& info) { - return info.param - ? "IsModelStreamingChunkByChunk" - : "IsModelStreamingWithCurrentResponse"; - }); +INSTANTIATE_TEST_SUITE_P( + All, + AILanguageModelTest, + testing::Combine(testing::Bool(), testing::Bool()), + [](const testing::TestParamInfo<testing::tuple<bool, bool>>& info) { + std::string description = ""; + description += std::get<0>(info.param) + ? "IsModelStreamingChunkByChunk" + : "IsModelStreamingWithCurrentResponse"; + description += "_"; + description += std::get<1>(info.param) + ? "IsAPIStreamingChunkByChunk" + : "IsAPIStreamingWithCurrentResponse"; + return description; + }); TEST_P(AILanguageModelTest, PromptDefaultSession) { RunPromptTest(AILanguageModelTest::Options{
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index 2a72d77c..15cf1cfe 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -367,7 +367,6 @@ testonly = true deps = [ - "//chrome/browser/ash/accessibility/live_caption:interactive_ui_tests", "//chrome/browser/ash/app_list:interactive_ui_tests", "//chrome/browser/ash/child_accounts:interactive_ui_tests", "//chrome/browser/ash/file_manager:interactive_ui_tests",
diff --git a/chrome/browser/ash/accessibility/live_caption/BUILD.gn b/chrome/browser/ash/accessibility/live_caption/BUILD.gn index bc1369b..52e5ba1 100644 --- a/chrome/browser/ash/accessibility/live_caption/BUILD.gn +++ b/chrome/browser/ash/accessibility/live_caption/BUILD.gn
@@ -50,33 +50,3 @@ "//components/live_caption:constants", ] } - -if (!is_chromeos_device) { - source_set("interactive_ui_tests") { - testonly = true - - defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] - - sources = [ "live_caption_ui_remote_driver_browsertest.cc" ] - - deps = [ - "//ash/constants", - "//base", - "//base/test:test_support", - "//chrome/browser", - "//chrome/browser/profiles:profile", - "//chrome/browser/ui", - "//chrome/test:test_support_ui", - "//components/live_caption", - "//components/live_caption:constants", - "//components/soda", - "//content/test:test_support", - "//mojo/public/cpp/bindings", - "//testing/gmock", - "//testing/gtest", - "//ui/events", - "//ui/gfx", - "//ui/views", - ] - } -}
diff --git a/chrome/browser/ash/accessibility/live_caption/live_caption_ui_remote_driver_browsertest.cc b/chrome/browser/ash/accessibility/live_caption/live_caption_ui_remote_driver_browsertest.cc deleted file mode 100644 index 5d2c2cf..0000000 --- a/chrome/browser/ash/accessibility/live_caption/live_caption_ui_remote_driver_browsertest.cc +++ /dev/null
@@ -1,392 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This test lives in ::ash (v.s. the live_caption component) because it -// exercises as much of the UI stack as possible, which includes e.g. enabling -// Ash-specific features. - -#include "components/live_caption/live_caption_ui_remote_driver.h" - -#include "ash/constants/ash_features.h" -#include "base/memory/raw_ptr.h" -#include "base/run_loop.h" -#include "base/test/bind.h" -#include "base/test/scoped_feature_list.h" -#include "chrome/browser/accessibility/live_caption/live_caption_controller_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "components/live_caption/caption_bubble_controller.h" -#include "components/live_caption/live_caption_controller.h" -#include "components/live_caption/pref_names.h" -#include "components/live_caption/views/caption_bubble.h" -#include "components/live_caption/views/caption_bubble_controller_views.h" -#include "components/soda/soda_installer.h" -#include "content/public/test/browser_test.h" -#include "media/mojo/mojom/speech_recognition_result.h" -#include "mojo/public/cpp/bindings/pending_receiver.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "mojo/public/cpp/bindings/receiver.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "mojo/public/cpp/bindings/self_owned_receiver.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/events/base_event_utils.h" -#include "ui/events/event.h" -#include "ui/events/event_constants.h" -#include "ui/events/types/event_type.h" -#include "ui/gfx/geometry/insets.h" -#include "ui/gfx/geometry/point.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/widget/widget.h" - -namespace ash { -namespace { - -using media::mojom::SpeechRecognitionRecognizerClient; -using media::mojom::SpeechRecognitionSurface; -using media::mojom::SpeechRecognitionSurfaceClient; -using testing::_; - -class MockSurface : public SpeechRecognitionSurface { - public: - MockSurface() = default; - ~MockSurface() override = default; - - MockSurface(const MockSurface&) = delete; - MockSurface& operator=(const MockSurface&) = delete; - - // Establish ourselves as the implementation of the surface, and grab a handle - // to the remote surface client. For good measure, hold the given recognizer - // client remote, since its self-owned implementation will destroy itself - // unless we do. - void Bind(mojo::PendingReceiver<SpeechRecognitionSurface> receiver, - mojo::PendingRemote<SpeechRecognitionSurfaceClient> surface_client, - mojo::PendingRemote<SpeechRecognitionRecognizerClient> - recognizer_client) { - receiver_.Bind(std::move(receiver)); - surface_client_.Bind(std::move(surface_client)); - recognizer_client_.Bind(std::move(recognizer_client)); - } - - mojo::Remote<SpeechRecognitionRecognizerClient>& remote_recognizer_client() { - return recognizer_client_; - } - - // media::mojom::SpeechRecognitionSurface: - MOCK_METHOD(void, Activate, (), (override)); - MOCK_METHOD(void, - GetBounds, - (SpeechRecognitionSurface::GetBoundsCallback), - (override)); - - private: - mojo::Receiver<SpeechRecognitionSurface> receiver_{this}; - mojo::Remote<SpeechRecognitionSurfaceClient> surface_client_; - - // Must hold this to keep the UI driver alive. - mojo::Remote<SpeechRecognitionRecognizerClient> recognizer_client_; -}; - -class LiveCaptionUiRemoteDriverTest : public InProcessBrowserTest { - public: - LiveCaptionUiRemoteDriverTest() - : scoped_feature_list_(features::kOnDeviceSpeechRecognition) {} - ~LiveCaptionUiRemoteDriverTest() override = default; - - LiveCaptionUiRemoteDriverTest(const LiveCaptionUiRemoteDriverTest&) = delete; - LiveCaptionUiRemoteDriverTest& operator=( - const LiveCaptionUiRemoteDriverTest&) = delete; - - void SetUpOnMainThread() override { - InProcessBrowserTest::SetUpOnMainThread(); - - browser()->profile()->GetPrefs()->SetBoolean(prefs::kLiveCaptionEnabled, - true); - - // Don't actually try to download SODA. - speech::SodaInstaller::GetInstance()->NeverDownloadSodaForTesting(); - - // Create bubble UI and grab a handle to it. - controller_ = captions::LiveCaptionControllerFactory::GetForProfile( - browser()->profile()); - base::RunLoop().RunUntilIdle(); - } - - // Test-only getters. - - captions::CaptionBubbleControllerViews* bubble_controller() const { - return static_cast<captions::CaptionBubbleControllerViews*>( - controller_->caption_bubble_controller_for_testing()); - } - - captions::CaptionBubble* bubble() { - return bubble_controller()->GetCaptionBubbleForTesting(); - } - - bool IsWidgetVisible() const { - return bubble_controller() && - bubble_controller()->IsWidgetVisibleForTesting(); - } - - std::string GetBubbleText() const { - return bubble_controller() - ? bubble_controller()->GetBubbleLabelTextForTesting() - : ""; - } - - // Create a new UI driver that communicates with the provided mock surface. - // The driver will destroy itself its connection to the surface drops. - captions::LiveCaptionUiRemoteDriver* NewUiDriverForSurface( - MockSurface* surface, - bool stub_bounds) { - // Bind the fake lacros ends of the Mojo pipes. - mojo::PendingReceiver<media::mojom::SpeechRecognitionRecognizerClient> - client_receiver; - mojo::PendingReceiver<media::mojom::SpeechRecognitionSurfaceClient> - surface_client_receiver; - mojo::PendingRemote<media::mojom::SpeechRecognitionSurface> surface_remote; - surface->Bind(surface_remote.InitWithNewPipeAndPassReceiver(), - surface_client_receiver.InitWithNewPipeAndPassRemote(), - client_receiver.InitWithNewPipeAndPassRemote()); - - // Sending an initial transcription will trigger a bounds query that must be - // replied to. The expectation is optionally added here since it is used in - // many tests. - if (stub_bounds) { - EXPECT_CALL(*surface, GetBounds(_)) - .WillOnce( - [&](auto cb) { std::move(cb).Run(gfx::Rect(1, 1, 600, 800)); }) - .RetiresOnSaturation(); - } - - // Create a driver and bind the Ash ends of the Mojo pipes. - auto driver = std::make_unique<captions::LiveCaptionUiRemoteDriver>( - controller_, std::move(surface_client_receiver), - std::move(surface_remote), "session-id"); - captions::LiveCaptionUiRemoteDriver* raw_driver = driver.get(); - - mojo::MakeSelfOwnedReceiver(std::move(driver), std::move(client_receiver)); - return raw_driver; - } - - // Emulate new transcriptions being generated for the given surface and wait - // until the recognizer client has responded. - bool EmitTranscribedText(MockSurface* surface, const std::string& text) { - bool result = false; - surface->remote_recognizer_client()->OnSpeechRecognitionRecognitionEvent( - media::SpeechRecognitionResult(text, /*is_final=*/false), - base::BindLambdaForTesting([&](bool r) { result = r; })); - base::RunLoop().RunUntilIdle(); - return result; - } - - // Emulate clicking the given button with the mouse. - void ClickButton(views::Button* button) { - button->OnMousePressed(ui::MouseEvent( - ui::EventType::kMousePressed, gfx::Point(0, 0), gfx::Point(0, 0), - ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0)); - button->OnMouseReleased(ui::MouseEvent( - ui::EventType::kMouseReleased, gfx::Point(0, 0), gfx::Point(0, 0), - ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0)); - } - - protected: - raw_ptr<captions::LiveCaptionController, DanglingUntriaged> controller_; - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - -// Test that captions sent from lacros are shown in the bubble. -IN_PROC_BROWSER_TEST_F(LiveCaptionUiRemoteDriverTest, DisplaysText) { - MockSurface surface; - NewUiDriverForSurface(&surface, /*stub_bounds=*/true); - - // Emitting text should cause the bubble to appear. - EXPECT_TRUE(EmitTranscribedText(&surface, "Test text")); - EXPECT_TRUE(IsWidgetVisible()); - EXPECT_EQ("Test text", GetBubbleText()); - - // Emitting empty text should cause the bubble to disappear. - EXPECT_TRUE(EmitTranscribedText(&surface, "")); - EXPECT_FALSE(IsWidgetVisible()); - - // Bubble should be shown again when non-empty text is emitted. - EXPECT_TRUE(EmitTranscribedText(&surface, "Test text 2")); - EXPECT_TRUE(IsWidgetVisible()); - EXPECT_EQ("Test text 2", GetBubbleText()); -} - -// Test that two media sources are both handled by the bubble. -IN_PROC_BROWSER_TEST_F(LiveCaptionUiRemoteDriverTest, MultipleSources) { - MockSurface surface_1; - NewUiDriverForSurface(&surface_1, /*stub_bounds=*/true); - - MockSurface surface_2; - NewUiDriverForSurface(&surface_2, /*stub_bounds=*/false); - - // Text from surface 1 should be shown. - EXPECT_TRUE(EmitTranscribedText(&surface_1, "Surface 1 text")); - EXPECT_TRUE(IsWidgetVisible()); - EXPECT_EQ("Surface 1 text", GetBubbleText()); - - // Text from surface 2 should replace surface 1's text because it is newer. - EXPECT_TRUE(EmitTranscribedText(&surface_2, "Surface 2 text")); - EXPECT_TRUE(IsWidgetVisible()); - EXPECT_EQ("Surface 2 text", GetBubbleText()); - - // Back to surface 1. - EXPECT_TRUE(EmitTranscribedText(&surface_1, "More surface 1 text")); - EXPECT_TRUE(IsWidgetVisible()); - EXPECT_EQ("More surface 1 text", GetBubbleText()); -} - -// Test that bubble is placed in correct position. -IN_PROC_BROWSER_TEST_F(LiveCaptionUiRemoteDriverTest, BubblePosition) { - MockSurface surface; - NewUiDriverForSurface(&surface, /*stub_bounds=*/false); - - // Set browser window to a known size and have the surface report the size. - const gfx::Rect window_bounds(10, 10, 800, 600); - browser()->window()->SetBounds(window_bounds); - EXPECT_CALL(surface, GetBounds(_)) - .WillOnce([&](auto cb) { std::move(cb).Run(window_bounds); }) - .RetiresOnSaturation(); - base::RunLoop().RunUntilIdle(); - const gfx::Rect context_rect = views::Widget::GetWidgetForNativeWindow( - browser()->window()->GetNativeWindow()) - ->GetClientAreaBoundsInScreen(); - - // Trigger positioning via first emission of text. - EXPECT_TRUE(EmitTranscribedText(&surface, "Test text")); - EXPECT_TRUE(IsWidgetVisible()); - - // Reuses the positioning logic from - // `CaptionBubbleControllerViewsTest::BubblePositioning`. - const int bubble_width = 536; - const int bubble_y_offset = 20; - const gfx::Insets bubble_margins(6); - const gfx::Rect bubble_bounds = bubble_controller() - ->GetCaptionWidgetForTesting() - ->GetWindowBoundsInScreen(); - - // There may be some rounding errors as we do floating point math with ints. - // Check that points are almost the same. - EXPECT_LT( - abs(bubble_bounds.CenterPoint().x() - context_rect.CenterPoint().x()), 2); - EXPECT_EQ(bubble_bounds.bottom(), context_rect.bottom() - bubble_y_offset); - EXPECT_EQ(bubble()->GetBoundsInScreen().width(), bubble_width); - EXPECT_EQ(bubble()->margins(), bubble_margins); -} - -// Test that an error is shown when reported by the surface. -IN_PROC_BROWSER_TEST_F(LiveCaptionUiRemoteDriverTest, DisplaysError) { - MockSurface surface; - NewUiDriverForSurface(&surface, /*stub_bounds=*/true); - - // Bubble should be shown initially. - EXPECT_TRUE(EmitTranscribedText(&surface, "Test text")); - EXPECT_TRUE(IsWidgetVisible()); - ASSERT_NE(nullptr, bubble_controller()); - EXPECT_FALSE(bubble_controller()->IsGenericErrorMessageVisibleForTesting()); - - // Error should trigger error message. - surface.remote_recognizer_client()->OnSpeechRecognitionError(); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(IsWidgetVisible()); - ASSERT_NE(nullptr, bubble_controller()); - EXPECT_TRUE(bubble_controller()->IsGenericErrorMessageVisibleForTesting()); - - // Receiving new text during an error should cause the error to disappear. - EXPECT_TRUE(EmitTranscribedText(&surface, "More test text")); - EXPECT_TRUE(IsWidgetVisible()); - ASSERT_NE(nullptr, bubble_controller()); - EXPECT_FALSE(bubble_controller()->IsGenericErrorMessageVisibleForTesting()); -} - -// Test that the bubble is hidden when a stream end is reported. -IN_PROC_BROWSER_TEST_F(LiveCaptionUiRemoteDriverTest, StreamEnd) { - MockSurface surface; - NewUiDriverForSurface(&surface, /*stub_bounds=*/true); - - // Emitting text should cause the bubble to appear. - EXPECT_TRUE(EmitTranscribedText(&surface, "Test text")); - EXPECT_TRUE(IsWidgetVisible()); - - // Send stream end signal. - surface.remote_recognizer_client()->OnSpeechRecognitionStopped(); - base::RunLoop().RunUntilIdle(); - - // Bubble should have disappeared. - ASSERT_NE(nullptr, bubble_controller()); - EXPECT_FALSE(IsWidgetVisible()); -} - -// Test that closing the bubble ends transcription until a navigation. -IN_PROC_BROWSER_TEST_F(LiveCaptionUiRemoteDriverTest, CloseBubble) { - MockSurface surface_1, surface_2, surface_3; - auto* driver_1 = NewUiDriverForSurface(&surface_1, /*stub_bounds=*/true); - NewUiDriverForSurface(&surface_2, /*stub_bounds=*/false); - NewUiDriverForSurface(&surface_3, /*stub_bounds=*/false); - - // Emitting text should cause the bubble to appear. - EXPECT_TRUE(EmitTranscribedText(&surface_1, "Test text")); - EXPECT_TRUE(IsWidgetVisible()); - - // Close the bubble. - ASSERT_NE(nullptr, bubble()); - ClickButton(bubble()->GetCloseButtonForTesting()); - EXPECT_FALSE(IsWidgetVisible()); - - // Emitting further text should fail. - EXPECT_FALSE(EmitTranscribedText(&surface_1, "More test text")); - EXPECT_FALSE(IsWidgetVisible()); - - // Emitting text from a different stream in the same closed session should - // also fail. - EXPECT_FALSE(EmitTranscribedText(&surface_2, "Surface 2 text")); - EXPECT_FALSE(IsWidgetVisible()); - - // Emulate a navigation (i.e. session end). - driver_1->OnSessionEnded(); - - // Text from a new page should not cause the bubble to reappear because - // closing the bubble disables the feature. - EXPECT_FALSE(EmitTranscribedText(&surface_3, "New page text")); - EXPECT_FALSE(IsWidgetVisible()); -} - -// Test that the back to tab message is delivered. -IN_PROC_BROWSER_TEST_F(LiveCaptionUiRemoteDriverTest, BackToTab) { - MockSurface surface_1; - MockSurface surface_2; - NewUiDriverForSurface(&surface_1, /*stub_bounds=*/true); - NewUiDriverForSurface(&surface_2, /*stub_bounds=*/false); - - // We expect these activate calls when we toggle back and forth. - EXPECT_CALL(surface_1, Activate()).Times(2).RetiresOnSaturation(); - EXPECT_CALL(surface_2, Activate()).RetiresOnSaturation(); - - // Emit text from surface 1 to activate its model. Then use the "back to tab" - // UI. - EXPECT_TRUE(EmitTranscribedText(&surface_1, "Surface 1 text")); - ClickButton(bubble()->GetBackToTabButtonForTesting()); - - // Emit text from surface 2 to activate its model. - EXPECT_TRUE(EmitTranscribedText(&surface_2, "Surface 2 text")); - ClickButton(bubble()->GetBackToTabButtonForTesting()); - - // Emit text from surface 1 again to reactivate its model. - EXPECT_TRUE(EmitTranscribedText(&surface_1, "More surface 1 text")); - ClickButton(bubble()->GetBackToTabButtonForTesting()); - - // Surface 1 should be activated twice, and surface 2 once. - base::RunLoop().RunUntilIdle(); -} - -} // namespace -} // namespace ash
diff --git a/chrome/browser/ash/crosapi/BUILD.gn b/chrome/browser/ash/crosapi/BUILD.gn index a28b88a..d5559c4 100644 --- a/chrome/browser/ash/crosapi/BUILD.gn +++ b/chrome/browser/ash/crosapi/BUILD.gn
@@ -180,8 +180,6 @@ "remoting_ash.h", "resource_manager_ash.cc", "resource_manager_ash.h", - "rootfs_lacros_loader.cc", - "rootfs_lacros_loader.h", "screen_ai_downloader_ash.cc", "screen_ai_downloader_ash.h", "screen_manager_ash.cc", @@ -604,7 +602,6 @@ sources = [ "audio_service_ash_unittest.cc", - "browser_loader_unittest.cc", "browser_util_unittest.cc", "cec_private_ash_unittest.cc", "cert_provisioning_ash_unittest.cc", @@ -633,7 +630,6 @@ "parent_access_ash_unittest.cc", "payment_app_instance_ash_unittest.cc", "primary_profile_creation_waiter_unittest.cc", - "rootfs_lacros_loader_unittest.cc", "screen_ai_downloader_ash_unittest.cc", "search_controller_ash_unittest.cc", "stateful_lacros_loader_unittest.cc",
diff --git a/chrome/browser/ash/crosapi/browser_loader.cc b/chrome/browser/ash/crosapi/browser_loader.cc index 321028f..8ae9df0 100644 --- a/chrome/browser/ash/crosapi/browser_loader.cc +++ b/chrome/browser/ash/crosapi/browser_loader.cc
@@ -14,25 +14,17 @@ #include "base/files/file_util.h" #include "base/functional/bind.h" #include "base/logging.h" -#include "base/metrics/histogram_functions.h" #include "base/ranges/algorithm.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task/task_traits.h" -#include "base/task/thread_pool.h" #include "base/values.h" #include "chrome/browser/ash/crosapi/lacros_selection_loader.h" #include "chrome/browser/ash/crosapi/lacros_selection_loader_factory.h" -#include "chrome/browser/ash/crosapi/rootfs_lacros_loader.h" #include "chrome/browser/ash/crosapi/stateful_lacros_loader.h" -#include "chrome/browser/browser_process.h" #include "chromeos/ash/components/cryptohome/system_salt_getter.h" #include "components/component_updater/ash/component_manager_ash.h" namespace crosapi { namespace { -// There are 2 lacros selections, rootfs lacros and stateful lacros. -constexpr size_t kLacrosSelectionTypes = 2; class LacrosSelectionLoaderFactoryImpl : public LacrosSelectionLoaderFactory { public: @@ -47,10 +39,6 @@ ~LacrosSelectionLoaderFactoryImpl() override = default; - std::unique_ptr<LacrosSelectionLoader> CreateRootfsLacrosLoader() override { - return std::make_unique<RootfsLacrosLoader>(); - } - std::unique_ptr<LacrosSelectionLoader> CreateStatefulLacrosLoader() override { return std::make_unique<StatefulLacrosLoader>(component_manager_); } @@ -59,10 +47,6 @@ scoped_refptr<component_updater::ComponentManagerAsh> component_manager_; }; -bool IsUnloading(LacrosSelectionLoader* loader) { - return loader && loader->IsUnloading(); -} - } // namespace BrowserLoader::BrowserLoader( @@ -75,362 +59,22 @@ BrowserLoader::~BrowserLoader() = default; -BrowserLoader::LacrosSelectionVersion::LacrosSelectionVersion( - LacrosSelection selection, - base::Version version) - : selection(selection), version(std::move(version)) { - CHECK_NE(selection, LacrosSelection::kDeployedLocally); -} - -// static. -bool BrowserLoader::WillLoadStatefulComponentBuilds() { - // If the lacros chrome path is specified BrowserLoader will always attempt to - // load lacros from this path and component manager builds are ignored. - const base::FilePath lacros_chrome_path = - base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( - ash::switches::kLacrosChromePath); - if (!lacros_chrome_path.empty()) - return false; - - // If the lacros selection is forced by the user or by policy to rootfs it - // will always be loaded and stateful component manager builds are ignored. - std::optional<ash::standalone_browser::LacrosSelection> lacros_selection = - ash::standalone_browser::DetermineLacrosSelection(); - if (lacros_selection == ash::standalone_browser::LacrosSelection::kRootfs) { - return false; - } - - return true; -} - -void BrowserLoader::SelectRootfsLacros(LoadCompletionCallback callback, - LacrosSelectionSource source) { - CHECK(rootfs_lacros_loader_); - - LOG(WARNING) << "rootfs lacros is selected by " << source; - - rootfs_lacros_loader_->Load( - base::BindOnce(&BrowserLoader::OnLoadComplete, weak_factory_.GetWeakPtr(), - std::move(callback), LacrosSelection::kRootfs), - source == LacrosSelectionSource::kForced); -} - -void BrowserLoader::SelectStatefulLacros(LoadCompletionCallback callback, - LacrosSelectionSource source) { - CHECK(stateful_lacros_loader_); - - LOG(WARNING) << "stateful lacros is selected by " << source; - - stateful_lacros_loader_->Load( - base::BindOnce(&BrowserLoader::OnLoadComplete, weak_factory_.GetWeakPtr(), - std::move(callback), LacrosSelection::kStateful), - source == LacrosSelectionSource::kForced); - - // Unmount the rootfs lacros-chrome when using stateful lacros-chrome. - // This will keep stateful lacros-chrome only mounted and not hold the rootfs - // lacros-chrome mount until an `Unload`. - if (rootfs_lacros_loader_) { - rootfs_lacros_loader_->Unload( - base::BindOnce(&BrowserLoader::OnUnloadCompleted, - weak_factory_.GetWeakPtr(), LacrosSelection::kRootfs)); - } -} - -void BrowserLoader::Load(LoadCompletionCallback callback) { - // Load should NOT be called after Unload is requested to BrowserLoader. - CHECK(!is_unload_requested_); - - // If either of rootfs or stateful lacros loader is still unloading, wait - // until the unload completion. - if (IsUnloading(rootfs_lacros_loader_.get()) || - IsUnloading(stateful_lacros_loader_.get())) { - LOG(WARNING) << "Wait load until unload completes"; - callback_on_unload_completion_ = - base::BindOnce(&BrowserLoader::LoadNow, weak_factory_.GetWeakPtr(), - std::move(callback)); - return; - } - - LoadNow(std::move(callback)); -} - -void BrowserLoader::LoadNow(LoadCompletionCallback callback) { - // Reset lacros selection loaders since it may be already initialized one if - // this is reloading. - // TODO(elkurin): We should call Unload before reloading if these loaders - // exist, then we can remove `reset` here. - rootfs_lacros_loader_.reset(); - stateful_lacros_loader_.reset(); - - lacros_start_load_time_ = base::TimeTicks::Now(); - // TODO(crbug.com/40689435): Remove non-error logging from this class. - LOG(WARNING) << "Starting lacros component load."; - - // If the user has specified a path for the lacros-chrome binary, use that - // rather than component manager. - base::FilePath lacros_chrome_path = - base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( - ash::switches::kLacrosChromePath); - if (!lacros_chrome_path.empty()) { - OnLoadComplete(std::move(callback), LacrosSelection::kDeployedLocally, - base::Version(), lacros_chrome_path); - return; - } - - // If the LacrosSelection policy or the user have specified to force using - // stateful or rootfs lacros-chrome binary, force the selection. Otherwise, - // load the newest available binary. - if (std::optional<ash::standalone_browser::LacrosSelection> lacros_selection = - ash::standalone_browser::DetermineLacrosSelection()) { - // TODO(crbug.com/40213424): We should check the version compatibility here, - // too. - switch (lacros_selection.value()) { - case ash::standalone_browser::LacrosSelection::kRootfs: - rootfs_lacros_loader_ = factory_->CreateRootfsLacrosLoader(); - SelectRootfsLacros(std::move(callback), LacrosSelectionSource::kForced); - return; - case ash::standalone_browser::LacrosSelection::kStateful: - stateful_lacros_loader_ = factory_->CreateStatefulLacrosLoader(); - SelectStatefulLacros(std::move(callback), - LacrosSelectionSource::kForced); - return; - case ash::standalone_browser::LacrosSelection::kDeployedLocally: - NOTREACHED(); - } - } - - rootfs_lacros_loader_ = factory_->CreateRootfsLacrosLoader(); - stateful_lacros_loader_ = factory_->CreateStatefulLacrosLoader(); - - // Proceed to load/mount the stateful lacros-chrome binary. - // In the case that the stateful lacros-chrome binary wasn't installed, this - // might take some time. - auto barrier_callback = base::BarrierCallback<LacrosSelectionVersion>( - kLacrosSelectionTypes, - base::BindOnce(&BrowserLoader::OnLoadVersions, weak_factory_.GetWeakPtr(), - std::move(callback))); - - rootfs_lacros_loader_->GetVersion( - base::BindOnce(&BrowserLoader::OnGetVersion, weak_factory_.GetWeakPtr(), - LacrosSelection::kRootfs, barrier_callback)); - stateful_lacros_loader_->GetVersion( - base::BindOnce(&BrowserLoader::OnGetVersion, weak_factory_.GetWeakPtr(), - LacrosSelection::kStateful, barrier_callback)); -} - -void BrowserLoader::OnGetVersion( - LacrosSelection selection, - base::OnceCallback<void(LacrosSelectionVersion)> barrier_callback, - const base::Version& version) { - std::move(barrier_callback).Run(LacrosSelectionVersion(selection, version)); -} - -void BrowserLoader::OnLoadVersions( - LoadCompletionCallback callback, - std::vector<LacrosSelectionVersion> versions) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK_EQ(versions.size(), kLacrosSelectionTypes); - - if (is_unload_requested_) { - LOG(WARNING) << "Unload is requested during collecting Lacros version."; - std::move(callback).Run(base::FilePath(), LacrosSelection::kStateful, - base::Version()); - return; - } - - // Compare the rootfs vs stateful lacros-chrome binary versions. - // If the rootfs lacros-chrome is greater than lacros-chrome version, - // prioritize using the rootfs lacros-chrome. If the stateful lacros-chrome is - // not installed, let stateful lacros-chrome load in the background. - auto selected = base::ranges::max_element( - versions, - [](const LacrosSelectionVersion& lhs, const LacrosSelectionVersion& rhs) { - if (!lhs.version.IsValid()) { - return true; - } - - if (!rhs.version.IsValid()) { - return false; - } - - if (lhs.version != rhs.version) { - return lhs.version < rhs.version; - } - - // If the versions are the same, stateful lacros-chrome should be - // prioritized, so considers LacrosSelectionVersion with kRootfs to be - // smaller. Note that this comparison only happens between kRootfs and - // kStateful. - return lhs.selection == LacrosSelection::kRootfs; - }); - - if (!selected->version.IsValid()) { - // Neither rootfs lacros nor stateful lacros are available. - // Returning an empty file path to notify error. - LOG(ERROR) << "No lacros is available"; - std::move(callback).Run(base::FilePath(), LacrosSelection::kStateful, - base::Version()); - return; - } - - // Selected lacros may be older than the one which was running in a previous - // sessions, accidentally. For experiment, now we intentionally ignore - // the case and forcibly load the selected one, which is the best we could do - // at this moment. - // TODO(crbug.com/40213424): Check the condition and report it via UMA stats. - - switch (selected->selection) { - case LacrosSelection::kRootfs: { - SelectRootfsLacros(std::move(callback), - LacrosSelectionSource::kCompatibilityCheck); - break; - } - case LacrosSelection::kStateful: { - SelectStatefulLacros(std::move(callback), - LacrosSelectionSource::kCompatibilityCheck); - break; - } - case LacrosSelection::kDeployedLocally: { - NOTREACHED(); - } - } -} - void BrowserLoader::Unload() { - is_unload_requested_ = true; - // Can be called even if Lacros isn't enabled, to clean up the old install. - // Unmount the rootfs/stateful lacros-chrome if it was mounted. - if (rootfs_lacros_loader_) { - rootfs_lacros_loader_->Unload( - base::BindOnce(&BrowserLoader::OnUnloadCompleted, - weak_factory_.GetWeakPtr(), LacrosSelection::kRootfs)); - } - + // Unmount the stateful lacros-chrome if it was mounted. if (stateful_lacros_loader_) { - stateful_lacros_loader_->Unload( - base::BindOnce(&BrowserLoader::OnUnloadCompleted, - weak_factory_.GetWeakPtr(), LacrosSelection::kStateful)); + stateful_lacros_loader_->Unload(base::BindOnce( + &BrowserLoader::OnUnloadCompleted, weak_factory_.GetWeakPtr())); } } -void BrowserLoader::OnUnloadCompleted(LacrosSelection selection) { +void BrowserLoader::OnUnloadCompleted() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - switch (selection) { - case LacrosSelection::kRootfs: - CHECK(rootfs_lacros_loader_->IsUnloaded()); - rootfs_lacros_loader_.reset(); - break; - case LacrosSelection::kStateful: - CHECK(stateful_lacros_loader_->IsUnloaded()); - stateful_lacros_loader_.reset(); - break; - case LacrosSelection::kDeployedLocally: - NOTREACHED(); - } - - // If either of rootfs or stateful lacros loader is still in the process of - // unload, wait running completion callback. - if (IsUnloading(rootfs_lacros_loader_.get()) || - IsUnloading(stateful_lacros_loader_.get())) { - return; - } - - // If both of the rootfs and stateful lacros load completed unloading, run the - // stored callback if exists. + CHECK(stateful_lacros_loader_->IsUnloaded()); + stateful_lacros_loader_.reset(); if (callback_on_unload_completion_) { std::move(callback_on_unload_completion_).Run(); } } -base::FilePath DetermineLacrosBinaryPath(const base::FilePath& path) { - // Interpret path as directory. If that fails, interpret it as the executable. - base::FilePath expanded = - path.Append(LacrosSelectionLoader::kLacrosChromeBinary); - if (base::PathExists(expanded)) { - return expanded; - } - if (base::PathExists(path)) { - return path; - } - return {}; -} - -void BrowserLoader::OnLoadComplete(LoadCompletionCallback callback, - LacrosSelection selection, - base::Version version, - const base::FilePath& path) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (is_unload_requested_) { - LOG(WARNING) << "Unload is requested during loading."; - std::move(callback).Run(base::FilePath(), LacrosSelection::kStateful, - base::Version()); - return; - } - - // Bail out on empty `path` which implies there was an error on loading - // lacros. - if (path.empty()) { - std::move(callback).Run(base::FilePath(), selection, base::Version()); - return; - } - - // Fail early if the chrome binary still doesn't exist, such that - // (1) we end up with an error message in Ash's log, and - // (2) BrowserManager doesn't endlessly try to spawn Lacros. - // For example, in the past there have been issues with mounting rootfs Lacros - // that resulted in /run/lacros being empty at this point. - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, - base::BindOnce(&DetermineLacrosBinaryPath, path), - base::BindOnce(&BrowserLoader::FinishOnLoadComplete, - weak_factory_.GetWeakPtr(), std::move(callback), path, - selection, std::move(version))); -} - -void BrowserLoader::FinishOnLoadComplete(LoadCompletionCallback callback, - const base::FilePath& path, - LacrosSelection selection, - base::Version version, - const base::FilePath& lacros_binary) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (is_unload_requested_) { - LOG(WARNING) << "Unload is requested during determining lacros path."; - std::move(callback).Run(base::FilePath(), LacrosSelection::kStateful, - base::Version()); - return; - } - - if (lacros_binary.empty()) { - LOG(ERROR) << "Failed to find binary at " << path; - std::move(callback).Run(base::FilePath(), selection, base::Version()); - return; - } - - base::UmaHistogramMediumTimes( - "ChromeOS.Lacros.LoadTime", - base::TimeTicks::Now() - lacros_start_load_time_); - - // Log the path on success. - LOG(WARNING) << "Loaded lacros image with binary " << lacros_binary; - std::move(callback).Run(lacros_binary, selection, std::move(version)); -} - -std::ostream& operator<<(std::ostream& ostream, - BrowserLoader::LacrosSelectionSource source) { - switch (source) { - case BrowserLoader::LacrosSelectionSource::kUnknown: - return ostream << "Unknown"; - case BrowserLoader::LacrosSelectionSource::kCompatibilityCheck: - return ostream << "CompatibilityCheck"; - case BrowserLoader::LacrosSelectionSource::kForced: - return ostream << "Forced"; - case BrowserLoader::LacrosSelectionSource::kDeployedPath: - return ostream << "DeployedPath"; - } -} - } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/browser_loader.h b/chrome/browser/ash/crosapi/browser_loader.h index ee90a2e..ee762dd3 100644 --- a/chrome/browser/ash/crosapi/browser_loader.h +++ b/chrome/browser/ash/crosapi/browser_loader.h
@@ -44,162 +44,24 @@ virtual ~BrowserLoader(); - // Returns true if the browser loader will try to load stateful lacros-chrome - // builds from the component manager. This may return false if the user - // specifies the lacros-chrome binary on the command line or the user has - // forced the lacros selection to rootfs. - // If this returns false subsequent loads of lacros-chrome will never load - // a newer lacros-chrome version and update checking can be skipped. - static bool WillLoadStatefulComponentBuilds(); - - struct LacrosSelectionVersion { - LacrosSelectionVersion(LacrosSelection selection, base::Version version); - - // LacrosSelection::kRootfs or kStateful should be set here, not - // kDeployedLocally. - LacrosSelection selection; - - base::Version version; - }; - - // Indicates how lacros is selected. - enum class LacrosSelectionSource { - kUnknown, - - // Selected by comparing the version to choose newer one or either of the - // lacros selection is not available. - kCompatibilityCheck, - - // Forced by the selection policy or about:flags. See - // browser_util::DetermineLacrosSelection for the detailed condition when - // the lacros selection is forced. - kForced, - - // Forced by registered lacros-chrome path. - kDeployedPath, - }; - - // Starts to load lacros-chrome binary or the rootfs lacros-chrome binary. - // `callback` is called on completion with the path to the lacros-chrome on - // success, or an empty filepath on failure, and the loaded lacros selection - // which is either 'rootfs' or 'stateful'. - // - // If Load is called during Load, the previous load requests are discarded - // and immediately begin loading. LoadCompletionCallback for the previous - // request will NOT be called in this scenario. - // TODO(elkurin): We should run Unload for previous LacroSelectionLoader. - // - // Load should NOT be called once Unlaod is requested. Note that per- - // LacrosSelectionLoader unload that is requested inside BrowserManager class - // may run before or while calling Load. - // If Load is called during per-loader unload, Load request will be processed - // after all ongoing per-loader unload requests complete that are at most 2. - // Currently, this happens only when selecting stateful lacros-chrome and - // unloading rootfs. - using LoadCompletionCallback = base::OnceCallback< - void(const base::FilePath&, LacrosSelection, base::Version)>; - virtual void Load(LoadCompletionCallback callback); - - // Starts to unload lacros-chrome binary. - // Once Unload is called, BrowserLoader should NOT accept Load requests. - // - // If Unload is called during Load, stops loading procedure on main thread and - // requests LacrosSelectionLoaders to unload. Each loader will start unloading - // after the current task completed. - // - // If Unload is called during Unload, no need to unload again so the - // coming unload request will be ignored. virtual void Unload(); private: - FRIEND_TEST_ALL_PREFIXES(BrowserLoaderTest, - OnLoadSelectionQuicklyChooseRootfs); - FRIEND_TEST_ALL_PREFIXES(BrowserLoaderTest, - OnLoadVersionSelectionNeitherIsAvailable); - FRIEND_TEST_ALL_PREFIXES(BrowserLoaderTest, - OnLoadVersionSelectionStatefulIsUnavailable); - FRIEND_TEST_ALL_PREFIXES(BrowserLoaderTest, - OnLoadVersionSelectionRootfsIsUnavailable); - FRIEND_TEST_ALL_PREFIXES(BrowserLoaderTest, - OnLoadVersionSelectionRootfsIsNewer); - FRIEND_TEST_ALL_PREFIXES(BrowserLoaderTest, - OnLoadVersionSelectionRootfsIsOlder); - FRIEND_TEST_ALL_PREFIXES(BrowserLoaderTest, - OnLoadVersionSelectionSameVersions); - FRIEND_TEST_ALL_PREFIXES(BrowserLoaderTest, OnLoadSelectionPolicyIsRootfs); - FRIEND_TEST_ALL_PREFIXES( - BrowserLoaderTest, - OnLoadSelectionPolicyIsUserChoiceAndCommandLineIsRootfs); - FRIEND_TEST_ALL_PREFIXES( - BrowserLoaderTest, - OnLoadSelectionPolicyIsUserChoiceAndCommandLineIsStateful); - FRIEND_TEST_ALL_PREFIXES(BrowserLoaderTest, - OnLoadLacrosBinarySpecifiedBySwitch); - FRIEND_TEST_ALL_PREFIXES(BrowserLoaderTest, - OnLoadLacrosDirectorySpecifiedBySwitch); - FRIEND_TEST_ALL_PREFIXES(BrowserLoaderTest, LoadWhileUnloading); + void OnUnloadCompleted(); - // Starts loading now/ - void LoadNow(LoadCompletionCallback callback); - - // `source` indicates why rootfs/stateful is selected. `source` is only used - // for logging. - void SelectRootfsLacros(LoadCompletionCallback callback, - LacrosSelectionSource source); - void SelectStatefulLacros(LoadCompletionCallback callback, - LacrosSelectionSource source); - - // Called on GetVersion for each rootfs and stateful lacros loader. - void OnGetVersion( - LacrosSelection selection, - base::OnceCallback<void(LacrosSelectionVersion)> barrier_callback, - const base::Version& version); - - // Called to determine which lacros to load based on version (rootfs vs - // stateful). - // `versions` consists of 2 elements, one for rootfs lacros, one for stateful - // lacros. The order is not specified. - void OnLoadVersions(LoadCompletionCallback callback, - std::vector<LacrosSelectionVersion> versions); - - // Called on the completion of loading. - void OnLoadComplete(LoadCompletionCallback callback, - LacrosSelection selection, - base::Version version, - const base::FilePath& path); - void FinishOnLoadComplete(LoadCompletionCallback callback, - const base::FilePath& path, - LacrosSelection selection, - base::Version version, - const base::FilePath& lacros_binary); - - // Called on unload completed. - void OnUnloadCompleted(LacrosSelection selection); - - // Loader for rootfs lacros and stateful lacros. Loader objects are - // constructed on start loading and reset on unload completion or on reload. - std::unique_ptr<LacrosSelectionLoader> rootfs_lacros_loader_; std::unique_ptr<LacrosSelectionLoader> stateful_lacros_loader_; std::unique_ptr<LacrosSelectionLoaderFactory> factory_; - // Time when the lacros component was loaded. - base::TimeTicks lacros_start_load_time_; - - // Called when Unload is completed for both rootfs and stateful lacros. + // Called when Unload is completed for stateful lacros. base::OnceClosure callback_on_unload_completion_; - // Set to true if BrowserLoader::Unload is requested. - bool is_unload_requested_ = false; - // Used for DCHECKs to ensure method calls executed in the correct thread. SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<BrowserLoader> weak_factory_{this}; }; -std::ostream& operator<<(std::ostream&, BrowserLoader::LacrosSelectionSource); - } // namespace crosapi #endif // CHROME_BROWSER_ASH_CROSAPI_BROWSER_LOADER_H_
diff --git a/chrome/browser/ash/crosapi/browser_loader_unittest.cc b/chrome/browser/ash/crosapi/browser_loader_unittest.cc deleted file mode 100644 index e6bf022..0000000 --- a/chrome/browser/ash/crosapi/browser_loader_unittest.cc +++ /dev/null
@@ -1,505 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ash/crosapi/browser_loader.h" - -#include "ash/constants/ash_switches.h" -#include "base/auto_reset.h" -#include "base/check_op.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/functional/callback.h" -#include "base/memory/scoped_refptr.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task/single_thread_task_runner.h" -#include "base/test/bind.h" -#include "base/test/scoped_command_line.h" -#include "base/test/test_future.h" -#include "base/version.h" -#include "chrome/browser/ash/crosapi/lacros_selection_loader.h" -#include "chrome/browser/ash/crosapi/lacros_selection_loader_factory.h" -#include "chromeos/ash/components/standalone_browser/lacros_selection.h" -#include "components/component_updater/ash/component_manager_ash.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/policy_constants.h" -#include "content/public/test/browser_task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace crosapi { -namespace { - -// Call the registered callback when Unload is started. -class UnloadObserver { - public: - UnloadObserver() = default; - UnloadObserver(const UnloadObserver&) = delete; - UnloadObserver& operator=(const UnloadObserver&) = delete; - ~UnloadObserver() = default; - - void OnUnloadStarted() { - if (callback_) { - std::move(callback_).Run(); - } - } - - void SetCallback(base::OnceClosure cb) { callback_ = std::move(cb); } - - private: - base::OnceClosure callback_; -}; - -// This fake class is used to test BrowserLoader who is responsible for deciding -// which lacros selection to use. -// This class does not load nor get actual version. Such features are tested in -// RootfsLacrosLoaderTest for rootfs and StatefulLacrosLoaderTest for stateful. -class FakeLacrosSelectionLoader : public LacrosSelectionLoader { - public: - FakeLacrosSelectionLoader( - const base::Version& version, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : version_(version), task_runner_(task_runner) { - // Create dummy chrome binary path. - CHECK(temp_dir_.CreateUniqueTempDir()); - chrome_path_ = temp_dir_.GetPath().Append(kLacrosChromeBinary); - base::WriteFile(chrome_path_, "I am chrome binary."); - } - - FakeLacrosSelectionLoader(const FakeLacrosSelectionLoader&) = delete; - FakeLacrosSelectionLoader& operator=(const FakeLacrosSelectionLoader&) = - delete; - - ~FakeLacrosSelectionLoader() override = default; - - void Load(LoadCompletionCallback callback, bool forced) override { - // Load should NOT be called when it's unloaded or busy. - CHECK(!is_unloading_ && !is_unloaded_); - - task_runner_->PostTask( - FROM_HERE, base::BindOnce(&FakeLacrosSelectionLoader::OnLoadCompleted, - base::Unretained(this), std::move(callback))); - } - - void Unload(base::OnceClosure callback) override { - is_unloading_ = true; - unload_observer_.OnUnloadStarted(); - - task_runner_->PostTask( - FROM_HERE, base::BindOnce(&FakeLacrosSelectionLoader::OnUnloadCompleted, - base::Unretained(this), std::move(callback))); - } - - bool IsUnloading() const override { return is_unloading_; } - - bool IsUnloaded() const override { return is_unloaded_; } - - void GetVersion( - base::OnceCallback<void(const base::Version&)> callback) override { - task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&FakeLacrosSelectionLoader::OnGetVersionCompleted, - base::Unretained(this), std::move(callback))); - } - - void SetCallbackOnUnload(base::OnceClosure cb) { - unload_observer_.SetCallback(std::move(cb)); - } - - private: - void OnLoadCompleted(LoadCompletionCallback callback) { - if (!callback) { - return; - } - - // If version is invalid, returns empty path. Otherwise fill in with some - // path. Whether path is empty or not is used as a condition to check - // whether error has occurred during loading. - const base::FilePath path = - version_.IsValid() ? temp_dir_.GetPath() : base::FilePath(); - std::move(callback).Run(version_, path); - } - - void OnUnloadCompleted(base::OnceClosure callback) { - is_unloading_ = false; - is_unloaded_ = true; - if (callback) { - std::move(callback).Run(); - } - } - - void OnGetVersionCompleted( - base::OnceCallback<void(const base::Version&)> callback) { - std::move(callback).Run(version_); - } - - const base::Version version_; - base::ScopedTempDir temp_dir_; - base::FilePath chrome_path_; - // `task_runner_` to run Load/Unload/GetVersion task as asynchronous - // operations. - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - UnloadObserver unload_observer_; - - bool is_unloaded_ = false; - bool is_unloading_ = false; -}; - -class FakeLacrosSelectionLoaderFactory : public LacrosSelectionLoaderFactory { - public: - FakeLacrosSelectionLoaderFactory( - const base::Version& rootfs_version, - const base::Version& stateful_version, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : rootfs_version_(rootfs_version), - stateful_version_(stateful_version), - task_runner_(task_runner) {} - - FakeLacrosSelectionLoaderFactory(const FakeLacrosSelectionLoaderFactory&) = - delete; - FakeLacrosSelectionLoaderFactory& operator=( - const FakeLacrosSelectionLoaderFactory&) = delete; - - ~FakeLacrosSelectionLoaderFactory() override = default; - - std::unique_ptr<LacrosSelectionLoader> CreateRootfsLacrosLoader() override { - return std::make_unique<FakeLacrosSelectionLoader>(rootfs_version_, - task_runner_); - } - - std::unique_ptr<LacrosSelectionLoader> CreateStatefulLacrosLoader() override { - return std::make_unique<FakeLacrosSelectionLoader>(stateful_version_, - task_runner_); - } - - private: - // These versions will be set on initializing lacros selection loaders. - const base::Version rootfs_version_ = base::Version(); - const base::Version stateful_version_ = base::Version(); - - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; -}; - -// This implementation of RAII for LacrosSelection is to make it easy reset -// the state between runs. -class ScopedLacrosSelectionCache { - public: - explicit ScopedLacrosSelectionCache( - ash::standalone_browser::LacrosSelectionPolicy lacros_selection) { - SetLacrosSelection(lacros_selection); - } - ScopedLacrosSelectionCache(const ScopedLacrosSelectionCache&) = delete; - ScopedLacrosSelectionCache& operator=(const ScopedLacrosSelectionCache&) = - delete; - ~ScopedLacrosSelectionCache() { - ash::standalone_browser::ClearLacrosSelectionCacheForTest(); - } - - private: - void SetLacrosSelection( - ash::standalone_browser::LacrosSelectionPolicy lacros_selection) { - policy::PolicyMap policy; - policy.Set(policy::key::kLacrosSelection, policy::POLICY_LEVEL_MANDATORY, - policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, - base::Value(GetLacrosSelectionPolicyName(lacros_selection)), - /*external_data_fetcher=*/nullptr); - ash::standalone_browser::CacheLacrosSelection(policy); - } -}; - -} // namespace - -class BrowserLoaderTest : public testing::Test { - public: - BrowserLoaderTest() { - EXPECT_TRUE(BrowserLoader::WillLoadStatefulComponentBuilds()); - } - - protected: - BrowserLoader CreateBrowserLoaderWithFakeSelectionLoaders( - const base::Version& rootfs_lacros_version, - const base::Version& stateful_lacros_version) { - return BrowserLoader(std::make_unique<FakeLacrosSelectionLoaderFactory>( - rootfs_lacros_version, stateful_lacros_version, - task_environment_.GetMainThreadTaskRunner())); - } - - void WaitForTaskComplete() { task_environment_.RunUntilIdle(); } - - private: - content::BrowserTaskEnvironment task_environment_; -}; - -TEST_F(BrowserLoaderTest, OnLoadVersionSelectionNeitherIsAvailable) { - // If both stateful and rootfs lacros-chrome version is invalid, the chrome - // path should be empty. - const base::Version rootfs_lacros_version = base::Version(); - const base::Version stateful_lacros_version = base::Version(); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - base::test::TestFuture<const base::FilePath&, LacrosSelection, base::Version> - future; - browser_loader.Load(future.GetCallback()); - EXPECT_TRUE(future.Get<0>().empty()); -} - -TEST_F(BrowserLoaderTest, OnLoadVersionSelectionStatefulIsUnavailable) { - // Pass invalid `base::Version` to stateful lacros-chrome and set valid - // version to rootfs lacros-chrome. - const base::Version rootfs_lacros_version = base::Version("2.0.0"); - const base::Version stateful_lacros_version = base::Version(); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - base::test::TestFuture<const base::FilePath&, LacrosSelection, base::Version> - future; - browser_loader.Load(future.GetCallback()); - EXPECT_EQ(LacrosSelection::kRootfs, future.Get<1>()); - EXPECT_EQ(rootfs_lacros_version, future.Get<2>()); -} - -TEST_F(BrowserLoaderTest, OnLoadVersionSelectionRootfsIsUnavailable) { - // Pass invalid `base::Version` as a rootfs lacros-chrome version. - const base::Version rootfs_lacros_version = base::Version(); - const base::Version stateful_lacros_version = base::Version("1.0.0"); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - base::test::TestFuture<const base::FilePath&, LacrosSelection, base::Version> - future; - browser_loader.Load(future.GetCallback()); - EXPECT_EQ(LacrosSelection::kStateful, future.Get<1>()); - EXPECT_EQ(stateful_lacros_version, future.Get<2>()); -} - -TEST_F(BrowserLoaderTest, OnLoadVersionSelectionRootfsIsNewer) { - // Use rootfs when a stateful lacros-chrome version is older. - const base::Version rootfs_lacros_version = base::Version("2.0.0"); - const base::Version stateful_lacros_version = base::Version("1.0.0"); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - base::test::TestFuture<const base::FilePath&, LacrosSelection, base::Version> - future; - browser_loader.Load(future.GetCallback()); - EXPECT_EQ(LacrosSelection::kRootfs, future.Get<1>()); - EXPECT_EQ(rootfs_lacros_version, future.Get<2>()); -} - -TEST_F(BrowserLoaderTest, OnLoadVersionSelectionRootfsIsOlder) { - // Use stateful when a rootfs lacros-chrome version is older. - const base::Version rootfs_lacros_version = base::Version("2.0.0"); - const base::Version stateful_lacros_version = base::Version("3.0.0"); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - base::test::TestFuture<const base::FilePath&, LacrosSelection, base::Version> - future; - browser_loader.Load(future.GetCallback()); - EXPECT_EQ(LacrosSelection::kStateful, future.Get<1>()); - EXPECT_EQ(stateful_lacros_version, future.Get<2>()); -} - -TEST_F(BrowserLoaderTest, OnLoadVersionSelectionSameVersions) { - // Use stateful when rootfs and stateful lacros-chrome versions are the same. - const base::Version rootfs_lacros_version = base::Version("2.0.0"); - const base::Version stateful_lacros_version = base::Version("2.0.0"); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - base::test::TestFuture<const base::FilePath&, LacrosSelection, base::Version> - future; - browser_loader.Load(future.GetCallback()); - EXPECT_EQ(LacrosSelection::kStateful, future.Get<1>()); - EXPECT_EQ(stateful_lacros_version, future.Get<2>()); -} - -TEST_F(BrowserLoaderTest, OnLoadSelectionPolicyIsRootfs) { - ScopedLacrosSelectionCache cache( - ash::standalone_browser::LacrosSelectionPolicy::kRootfs); - base::test::ScopedCommandLine command_line; - command_line.GetProcessCommandLine()->AppendSwitchASCII( - ash::standalone_browser::kLacrosSelectionSwitch, - ash::standalone_browser::kLacrosSelectionStateful); - - // Set stateful lacros version newer than rootfs to test that the selection - // policy is prioritized higher. - const base::Version rootfs_lacros_version = base::Version("2.0.0"); - const base::Version stateful_lacros_version = base::Version("3.0.0"); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - base::test::TestFuture<const base::FilePath&, LacrosSelection, base::Version> - future; - browser_loader.Load(future.GetCallback()); - - const LacrosSelection selection = future.Get<1>(); - EXPECT_EQ(selection, LacrosSelection::kRootfs); - EXPECT_FALSE(BrowserLoader::WillLoadStatefulComponentBuilds()); - - // Check stateful lacros loader is not initialized since the selection is - // forced by policy. - EXPECT_FALSE(browser_loader.stateful_lacros_loader_); -} - -TEST_F(BrowserLoaderTest, - OnLoadSelectionPolicyIsUserChoiceAndCommandLineIsRootfs) { - ScopedLacrosSelectionCache cache( - ash::standalone_browser::LacrosSelectionPolicy::kUserChoice); - base::test::ScopedCommandLine command_line; - command_line.GetProcessCommandLine()->AppendSwitchASCII( - ash::standalone_browser::kLacrosSelectionSwitch, - ash::standalone_browser::kLacrosSelectionRootfs); - - // Set stateful lacros version newer than rootfs to test that the user choice - // is prioritized higher. - const base::Version rootfs_lacros_version = base::Version("2.0.0"); - const base::Version stateful_lacros_version = base::Version("3.0.0"); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - base::test::TestFuture<const base::FilePath&, LacrosSelection, base::Version> - future; - browser_loader.Load(future.GetCallback()); - - const LacrosSelection selection = future.Get<1>(); - EXPECT_EQ(selection, LacrosSelection::kRootfs); - EXPECT_FALSE(BrowserLoader::WillLoadStatefulComponentBuilds()); - - // Check stateful lacros loader is not initialized since the selection is - // forced by policy. - EXPECT_FALSE(browser_loader.stateful_lacros_loader_); -} - -TEST_F(BrowserLoaderTest, - OnLoadSelectionPolicyIsUserChoiceAndCommandLineIsStateful) { - ScopedLacrosSelectionCache cache( - ash::standalone_browser::LacrosSelectionPolicy::kUserChoice); - base::test::ScopedCommandLine command_line; - command_line.GetProcessCommandLine()->AppendSwitchASCII( - ash::standalone_browser::kLacrosSelectionSwitch, - ash::standalone_browser::kLacrosSelectionStateful); - - // Set rootfs lacros version newer than rootfs to test that the user choice - // is prioritized higher. - const base::Version rootfs_lacros_version = base::Version("2.0.0"); - const base::Version stateful_lacros_version = base::Version("1.0.0"); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - base::test::TestFuture<const base::FilePath&, LacrosSelection, base::Version> - future; - browser_loader.Load(future.GetCallback()); - - const LacrosSelection selection = future.Get<1>(); - EXPECT_EQ(selection, LacrosSelection::kStateful); - EXPECT_TRUE(BrowserLoader::WillLoadStatefulComponentBuilds()); - - // Check rootfs lacros loader is not initialized since the selection is forced - // by policy. - EXPECT_FALSE(browser_loader.rootfs_lacros_loader_); -} - -TEST_F(BrowserLoaderTest, OnLoadLacrosBinarySpecifiedBySwitch) { - base::ScopedTempDir temp_dir; - CHECK(temp_dir.CreateUniqueTempDir()); - const base::FilePath lacros_chrome_dir = temp_dir.GetPath(); - base::WriteFile(lacros_chrome_dir.Append("chrome"), - "I am lacros-chrome deployed locally."); - const base::FilePath lacros_chrome_path = - temp_dir.GetPath().Append("mychrome"); - base::WriteFile(lacros_chrome_path, - "I am a custom lacros-chrome deployed locally."); - - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - ash::switches::kLacrosChromePath, lacros_chrome_path.MaybeAsASCII()); - - // Set stateful/rootfs lacros-chrome version to check that specified - // lacros-chrome is prioritized higher. - const base::Version rootfs_lacros_version = base::Version("2.0.0"); - const base::Version stateful_lacros_version = base::Version("3.0.0"); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - base::test::TestFuture<base::FilePath, LacrosSelection, base::Version> future; - browser_loader.Load(future.GetCallback<const base::FilePath&, LacrosSelection, - base::Version>()); - - const base::FilePath path = future.Get<0>(); - const LacrosSelection selection = future.Get<1>(); - EXPECT_EQ(path, lacros_chrome_path); - EXPECT_EQ(selection, LacrosSelection::kDeployedLocally); - - // Check both rootfs and stateful lacros loader are not initialized since the - // selection is forced by switch. - EXPECT_FALSE(browser_loader.rootfs_lacros_loader_); - EXPECT_FALSE(browser_loader.stateful_lacros_loader_); -} - -TEST_F(BrowserLoaderTest, OnLoadLacrosDirectorySpecifiedBySwitch) { - base::ScopedTempDir temp_dir; - CHECK(temp_dir.CreateUniqueTempDir()); - const base::FilePath lacros_chrome_dir = temp_dir.GetPath(); - base::WriteFile(lacros_chrome_dir.Append("chrome"), - "I am lacros-chrome deployed locally."); - - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - ash::switches::kLacrosChromePath, lacros_chrome_dir.MaybeAsASCII()); - - // Set stateful/rootfs lacros-chrome version to check that specified - // lacros-chrome is prioritized higher. - const base::Version rootfs_lacros_version = base::Version("2.0.0"); - const base::Version stateful_lacros_version = base::Version("3.0.0"); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - base::test::TestFuture<base::FilePath, LacrosSelection, base::Version> future; - browser_loader.Load(future.GetCallback<const base::FilePath&, LacrosSelection, - base::Version>()); - - const base::FilePath path = future.Get<0>(); - const LacrosSelection selection = future.Get<1>(); - EXPECT_EQ(path, lacros_chrome_dir.Append("chrome")); - EXPECT_EQ(selection, LacrosSelection::kDeployedLocally); - - // Check both rootfs and stateful lacros loader are not initialized since the - // selection is forced by switch. - EXPECT_FALSE(browser_loader.rootfs_lacros_loader_); - EXPECT_FALSE(browser_loader.stateful_lacros_loader_); -} - -TEST_F(BrowserLoaderTest, LoadWhileUnloading) { - // If stateful is newer, rootfs lacros will be unloaded. - const base::Version rootfs_lacros_version = base::Version("2.0.0"); - const base::Version stateful_lacros_version = base::Version("3.0.0"); - auto browser_loader = CreateBrowserLoaderWithFakeSelectionLoaders( - rootfs_lacros_version, stateful_lacros_version); - - // Load once. This will start asynchronous unload for rootfs lacros loader. - base::test::TestFuture<base::FilePath, LacrosSelection, base::Version> future; - browser_loader.Load(future.GetCallback<const base::FilePath&, LacrosSelection, - base::Version>()); - - // Wait until rootfs lacros loader starts Unload. GetVersion runs - // asynchronously before it start unloading. - base::test::TestFuture<void> future1; - FakeLacrosSelectionLoader* rootfs_lacros_loader = - static_cast<FakeLacrosSelectionLoader*>( - browser_loader.rootfs_lacros_loader_.get()); - rootfs_lacros_loader->SetCallbackOnUnload(future1.GetCallback()); - ASSERT_TRUE(future1.Wait()); - - // On requesting Load while Unloading, the load request should be stored to - // `callback_on_unload_completion_` and wait for unload to complete to resume - // load request. - base::test::TestFuture<base::FilePath, LacrosSelection, base::Version> - future2; - browser_loader.Load(future2.GetCallback<const base::FilePath&, - LacrosSelection, base::Version>()); - - EXPECT_EQ(LacrosSelection::kStateful, future2.Get<1>()); -} - -} // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc index 9e4827c8..4d3c1d0 100644 --- a/chrome/browser/ash/crosapi/browser_util.cc +++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -19,15 +19,11 @@ #include "base/version.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_paths.h" -#include "chromeos/ash/components/standalone_browser/lacros_availability.h" #include "chromeos/crosapi/cpp/crosapi_constants.h" #include "components/exo/shell_surface_util.h" #include "components/version_info/channel.h" #include "components/version_info/version_info.h" -using ash::standalone_browser::LacrosAvailability; -using user_manager::User; - namespace crosapi::browser_util { namespace {
diff --git a/chrome/browser/ash/crosapi/browser_util.h b/chrome/browser/ash/crosapi/browser_util.h index 32ad8d5b..25bec24 100644 --- a/chrome/browser/ash/crosapi/browser_util.h +++ b/chrome/browser/ash/crosapi/browser_util.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_ASH_CROSAPI_BROWSER_UTIL_H_ #define CHROME_BROWSER_ASH_CROSAPI_BROWSER_UTIL_H_ -#include "chromeos/ash/components/standalone_browser/lacros_availability.h" #include "chromeos/ash/components/standalone_browser/lacros_selection.h" namespace aura {
diff --git a/chrome/browser/ash/crosapi/browser_util_unittest.cc b/chrome/browser/ash/crosapi/browser_util_unittest.cc index b74ec9b..009dfe6 100644 --- a/chrome/browser/ash/crosapi/browser_util_unittest.cc +++ b/chrome/browser/ash/crosapi/browser_util_unittest.cc
@@ -137,14 +137,4 @@ EXPECT_FALSE(browser_util::GetRootfsLacrosVersionMayBlock(path).IsValid()); } -// Lacros availability has an effect on googlers -TEST_F(BrowserUtilTest, LacrosAvailabilityIgnoreGoogleEnableToUserChoice) { - AddRegularUser("user@google.com"); - - base::test::ScopedCommandLine cmd_line; - cmd_line.GetProcessCommandLine()->AppendSwitch( - ash::switches::kLacrosAvailabilityIgnore); - EXPECT_FALSE(browser_util::IsLacrosEnabled()); -} - } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/lacros_selection_loader_factory.h b/chrome/browser/ash/crosapi/lacros_selection_loader_factory.h index 06010259..547f0cb 100644 --- a/chrome/browser/ash/crosapi/lacros_selection_loader_factory.h +++ b/chrome/browser/ash/crosapi/lacros_selection_loader_factory.h
@@ -15,8 +15,7 @@ public: virtual ~LacrosSelectionLoaderFactory() = default; - // Interface to create LacrosSelectionLoader for rootfs/stateful. - virtual std::unique_ptr<LacrosSelectionLoader> CreateRootfsLacrosLoader() = 0; + // Interface to create LacrosSelectionLoader for stateful. virtual std::unique_ptr<LacrosSelectionLoader> CreateStatefulLacrosLoader() = 0; };
diff --git a/chrome/browser/ash/crosapi/rootfs_lacros_loader.cc b/chrome/browser/ash/crosapi/rootfs_lacros_loader.cc deleted file mode 100644 index f5d733c..0000000 --- a/chrome/browser/ash/crosapi/rootfs_lacros_loader.cc +++ /dev/null
@@ -1,261 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ash/crosapi/rootfs_lacros_loader.h" - -#include <string> -#include <utility> -#include <vector> - -#include "base/files/file_util.h" -#include "base/functional/bind.h" -#include "base/logging.h" -#include "base/path_service.h" -#include "base/task/task_traits.h" -#include "base/task/thread_pool.h" -#include "chrome/browser/ash/crosapi/browser_util.h" -#include "chromeos/ash/components/dbus/upstart/upstart_client.h" -#include "components/user_manager/user_manager.h" - -namespace crosapi { - -namespace { - -// The rootfs lacros-chrome binary related files. -constexpr char kLacrosMetadata[] = "metadata.json"; - -// The rootfs lacros-chrome binary related paths. -// Must be kept in sync with lacros upstart conf files. -constexpr char kRootfsLacrosMountPoint[] = "/run/lacros"; -constexpr char kRootfsLacrosPath[] = "/opt/google/lacros"; - -// Lacros upstart jobs for mounting/unmounting the lacros-chrome image. -// The conversion of upstart job names to dbus object paths is undocumented. See -// function nih_dbus_path in libnih for the implementation. -constexpr char kLacrosMounterUpstartJob[] = "lacros_2dmounter"; -constexpr char kLacrosUnmounterUpstartJob[] = "lacros_2dunmounter"; - -} // namespace - -RootfsLacrosLoader::RootfsLacrosLoader() - : RootfsLacrosLoader( - ash::UpstartClient::Get(), - base::FilePath(kRootfsLacrosPath).Append(kLacrosMetadata)) {} - -RootfsLacrosLoader::RootfsLacrosLoader(ash::UpstartClient* upstart_client, - base::FilePath metadata_path) - : upstart_client_(upstart_client), - metadata_path_(std::move(metadata_path)) {} - -RootfsLacrosLoader::~RootfsLacrosLoader() = default; - -void RootfsLacrosLoader::Load(LoadCompletionCallback callback, bool forced) { - CHECK(state_ == State::kNotLoaded || - state_ == State::kVersionReadyButNotLoaded) - << state_; - LOG(WARNING) << "Loading rootfs lacros."; - - if (state_ == State::kVersionReadyButNotLoaded) { - OnVersionReadyToLoad(std::move(callback), version_.value()); - return; - } - - // Calculate `version_` before start loading. - // It's not calculated yet in case when lacros selection is defined by - // selection policy or stateful lacros is not installed. - state_ = State::kReadingVersion; - GetVersionInternal(base::BindOnce(&RootfsLacrosLoader::OnVersionReadyToLoad, - weak_factory_.GetWeakPtr(), - std::move(callback))); -} - -void RootfsLacrosLoader::Unload(base::OnceClosure callback) { - switch (state_) { - case State::kNotLoaded: - case State::kVersionReadyButNotLoaded: - case State::kUnloaded: - // Nothing to unload if it's not loaded or already unloaded. - state_ = State::kUnloaded; - std::move(callback).Run(); - break; - case State::kReadingVersion: - case State::kLoading: - case State::kUnloading: - // If loader is busy, wait Unload until the current task has finished. - pending_unload_ = - base::BindOnce(&RootfsLacrosLoader::Unload, - weak_factory_.GetWeakPtr(), std::move(callback)); - break; - case State::kLoaded: - state_ = State::kUnloading; - - upstart_client_->StartJob( - kLacrosUnmounterUpstartJob, {}, - base::BindOnce(&RootfsLacrosLoader::OnUnloadCompleted, - weak_factory_.GetWeakPtr(), std::move(callback))); - } -} - -void RootfsLacrosLoader::GetVersion( - base::OnceCallback<void(const base::Version&)> callback) { - CHECK_EQ(state_, State::kNotLoaded) << state_; - state_ = State::kReadingVersion; - GetVersionInternal(std::move(callback)); -} - -bool RootfsLacrosLoader::IsUnloading() const { - return state_ == State::kUnloading; -} - -bool RootfsLacrosLoader::IsUnloaded() const { - return state_ == State::kUnloaded; -} - -void RootfsLacrosLoader::GetVersionInternal( - base::OnceCallback<void(const base::Version&)> callback) { - CHECK_EQ(state_, State::kReadingVersion) << state_; - CHECK(!version_); - - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, - base::BindOnce(&browser_util::GetRootfsLacrosVersionMayBlock, - metadata_path_), - base::BindOnce(&RootfsLacrosLoader::OnGetVersion, - weak_factory_.GetWeakPtr(), std::move(callback))); -} - -void RootfsLacrosLoader::OnGetVersion( - base::OnceCallback<void(const base::Version&)> callback, - base::Version version) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK_EQ(state_, State::kReadingVersion) << state_; - - version_ = version; - state_ = State::kVersionReadyButNotLoaded; - - if (pending_unload_) { - LOG(WARNING) << "Unload is requested during getting version of rootfs."; - std::move(callback).Run(base::Version()); - std::move(pending_unload_).Run(); - return; - } - - std::move(callback).Run(version_.value()); -} - -void RootfsLacrosLoader::OnVersionReadyToLoad(LoadCompletionCallback callback, - const base::Version& version) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK_EQ(state_, State::kVersionReadyButNotLoaded) << state_; - - if (pending_unload_) { - LOG(WARNING) << "Unload is requested during loading rootfs."; - std::move(callback).Run(base::Version(), base::FilePath()); - std::move(pending_unload_).Run(); - return; - } - - // `version_` must be already filled by `version`. - CHECK(version_.has_value() && - ((!version_.value().IsValid() && !version.IsValid()) || - (version_.value() == version))); - - state_ = State::kLoading; - - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, - base::BindOnce( - &base::PathExists, - base::FilePath(kRootfsLacrosMountPoint).Append(kLacrosChromeBinary)), - base::BindOnce(&RootfsLacrosLoader::OnMountCheckToLoad, - weak_factory_.GetWeakPtr(), std::move(callback))); -} - -void RootfsLacrosLoader::OnMountCheckToLoad(LoadCompletionCallback callback, - bool already_mounted) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK_EQ(state_, State::kLoading) << state_; - - if (pending_unload_) { - LOG(WARNING) << "Unload is requested during loading rootfs."; - state_ = State::kVersionReadyButNotLoaded; - std::move(callback).Run(base::Version(), base::FilePath()); - std::move(pending_unload_).Run(); - return; - } - - if (already_mounted) { - OnUpstartLacrosMounter(std::move(callback), true); - return; - } - - std::vector<std::string> job_env; - if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) { - job_env.emplace_back("USE_SESSION_NAMESPACE=true"); - } - - upstart_client_->StartJob( - kLacrosMounterUpstartJob, job_env, - base::BindOnce(&RootfsLacrosLoader::OnUpstartLacrosMounter, - weak_factory_.GetWeakPtr(), std::move(callback))); -} - -void RootfsLacrosLoader::OnUpstartLacrosMounter(LoadCompletionCallback callback, - bool success) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK_EQ(state_, State::kLoading) << state_; - state_ = State::kLoaded; - - LOG_IF(WARNING, !success) << "Upstart failed to mount rootfs lacros."; - - if (pending_unload_) { - LOG(WARNING) << "Unload is requested during loading rootfs."; - std::move(callback).Run(base::Version(), base::FilePath()); - std::move(pending_unload_).Run(); - return; - } - - // `version_` must be calculated before coming here. - CHECK(version_.has_value()); - std::move(callback).Run( - version_.value(), - // If mounting wasn't successful, return a empty mount point to indicate - // failure. `OnLoadComplete` handles empty mount points and forwards the - // errors on the return callbacks. - success ? base::FilePath(kRootfsLacrosMountPoint) : base::FilePath()); -} - -void RootfsLacrosLoader::OnUnloadCompleted(base::OnceClosure callback, - bool success) { - // Proceed anyway regardless of unload success. - if (!success) { - LOG(ERROR) << "Failed to unload rootfs lacros"; - } - - CHECK_EQ(state_, State::kUnloading) << state_; - state_ = State::kUnloaded; - std::move(callback).Run(); -} - -std::ostream& operator<<(std::ostream& ostream, - RootfsLacrosLoader::State state) { - switch (state) { - case RootfsLacrosLoader::State::kNotLoaded: - return ostream << "NotLoaded"; - case RootfsLacrosLoader::State::kReadingVersion: - return ostream << "ReadingVersion"; - case RootfsLacrosLoader::State::kVersionReadyButNotLoaded: - return ostream << "VersionReadyButNotLoaded"; - case RootfsLacrosLoader::State::kLoading: - return ostream << "Loading"; - case RootfsLacrosLoader::State::kLoaded: - return ostream << "Loaded"; - case RootfsLacrosLoader::State::kUnloading: - return ostream << "Unloading"; - case RootfsLacrosLoader::State::kUnloaded: - return ostream << "Unloaded"; - } -} - -} // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/rootfs_lacros_loader.h b/chrome/browser/ash/crosapi/rootfs_lacros_loader.h deleted file mode 100644 index b492af5..0000000 --- a/chrome/browser/ash/crosapi/rootfs_lacros_loader.h +++ /dev/null
@@ -1,124 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ASH_CROSAPI_ROOTFS_LACROS_LOADER_H_ -#define CHROME_BROWSER_ASH_CROSAPI_ROOTFS_LACROS_LOADER_H_ - -#include <optional> -#include <ostream> - -#include "base/files/file_path.h" -#include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/sequence_checker.h" -#include "base/version.h" -#include "chrome/browser/ash/crosapi/lacros_selection_loader.h" - -namespace ash { -class UpstartClient; -} // namespace ash - -namespace crosapi { - -class RootfsLacrosLoader : public LacrosSelectionLoader { - public: - // Constructor for production. - RootfsLacrosLoader(); - // Constructor for testing. - explicit RootfsLacrosLoader(ash::UpstartClient* upstart_client, - base::FilePath metadata_path); - RootfsLacrosLoader(const RootfsLacrosLoader&) = delete; - RootfsLacrosLoader& operator=(const RootfsLacrosLoader&) = delete; - ~RootfsLacrosLoader() override; - - // The state representing the loading state. - enum class State { - // Loader is not running any task. - kNotLoaded, - - // Loader is in the process of reading the version from manifest file. - kReadingVersion, - - // Loader gets version of lacros-chrome but not loaded it yet. - kVersionReadyButNotLoaded, - - // Loader is in the process of loading lacros-chrome. - kLoading, - - // Loader has loaded lacros-chrome and `version_` and `path_` is ready. - kLoaded, - - // Loader is in the process of unloading lacros-chrome. - kUnloading, - - // Loader has unloaded the lacros-chrome. State must NOT change once it - // becomes kUnloaded. - kUnloaded, - }; - - State GetState() const { return state_; } - - // LacrosSelectionLoader: - void Load(LoadCompletionCallback callback, bool forced) override; - void Unload(base::OnceClosure callback) override; - void GetVersion( - base::OnceCallback<void(const base::Version&)> callback) override; - bool IsUnloading() const override; - bool IsUnloaded() const override; - - private: - void GetVersionInternal( - base::OnceCallback<void(const base::Version&)> callback); - - // Called after GetVersion. - void OnGetVersion(base::OnceCallback<void(const base::Version&)> callback, - base::Version version); - - // Called when `version_` is calculated and set during Load() sequence. - void OnVersionReadyToLoad(LoadCompletionCallback callback, - const base::Version& version); - - // Called on checking rootfs lacros-chrome is already maounted or not during - // Load() sequence. - void OnMountCheckToLoad(LoadCompletionCallback callback, - bool already_mounted); - - // Callback from upstart mounting lacros-chrome. - void OnUpstartLacrosMounter(LoadCompletionCallback callback, bool success); - - // Called on unload completed. - void OnUnloadCompleted(base::OnceClosure callback, bool success); - - // The bundled rootfs lacros-chrome binary version. This is set after the - // first async call that checks the installed rootfs lacros version number. - // If `version_` is null, it implies the version is not yet calculated. - // For cases where it failed to read the version, invalid `base::Version()` is - // set. - std::optional<base::Version> version_; - - // Pointer held to `UpstartClient` for testing purposes. - // Otherwise, the lifetime is the same as `ash::UpstartClient::Get()`. - const raw_ptr<ash::UpstartClient> upstart_client_; - - // The path which stores the metadata including the version. - // This is always the same for production code, but may be overridden on - // testing. - base::FilePath metadata_path_; - - base::OnceClosure pending_unload_; - - State state_ = State::kNotLoaded; - - // Used for DCHECKs to ensure method calls executed in the correct thread. - SEQUENCE_CHECKER(sequence_checker_); - - base::WeakPtrFactory<RootfsLacrosLoader> weak_factory_{this}; -}; - -std::ostream& operator<<(std::ostream&, RootfsLacrosLoader::State); - -} // namespace crosapi - -#endif // CHROME_BROWSER_ASH_CROSAPI_ROOTFS_LACROS_LOADER_H_
diff --git a/chrome/browser/ash/crosapi/rootfs_lacros_loader_unittest.cc b/chrome/browser/ash/crosapi/rootfs_lacros_loader_unittest.cc deleted file mode 100644 index c00045d3..0000000 --- a/chrome/browser/ash/crosapi/rootfs_lacros_loader_unittest.cc +++ /dev/null
@@ -1,138 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ash/crosapi/rootfs_lacros_loader.h" - -#include <memory> -#include <string> - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/test/bind.h" -#include "base/test/test_future.h" -#include "base/version.h" -#include "chromeos/ash/components/dbus/upstart/fake_upstart_client.h" -#include "components/user_manager/fake_user_manager.h" -#include "components/user_manager/scoped_user_manager.h" -#include "content/public/test/browser_task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace crosapi { -namespace { - -// Copied from rootfs_lacros_loader.cc -constexpr char kLacrosMounterUpstartJob[] = "lacros_2dmounter"; - -class RootfsLacrosLoaderTest : public testing::Test { - public: - RootfsLacrosLoaderTest() { - CHECK(temp_dir_.CreateUniqueTempDir()); - metadata_path_ = temp_dir_.GetPath().Append("metadata"); - base::WriteFile(metadata_path_, - "{\"content\":{\"version\":\"" + version_str + "\"}}"); - rootfs_lacros_loader_ = std::make_unique<RootfsLacrosLoader>( - &fake_upstart_client_, metadata_path_); - } - - protected: - content::BrowserTaskEnvironment task_environment_; - - const std::string version_str = "1.0.0"; - base::ScopedTempDir temp_dir_; - base::FilePath metadata_path_; - - user_manager::TypedScopedUserManager<user_manager::FakeUserManager> - scoped_user_manager_{std::make_unique<user_manager::FakeUserManager>()}; - ash::FakeUpstartClient fake_upstart_client_; - std::unique_ptr<RootfsLacrosLoader> rootfs_lacros_loader_; -}; - -TEST_F(RootfsLacrosLoaderTest, LoadRootfsLacrosSelectedByCompatibilityCheck) { - bool callback_called = false; - fake_upstart_client_.set_start_job_cb(base::BindRepeating( - [](bool* callback_called, const std::string& job, - const std::vector<std::string>& upstart_env) { - EXPECT_EQ(job, kLacrosMounterUpstartJob); - *callback_called = true; - return ash::FakeUpstartClient::StartJobResult(true /* success */); - }, - &callback_called)); - - EXPECT_EQ(RootfsLacrosLoader::State::kNotLoaded, - rootfs_lacros_loader_->GetState()); - - // If rootfs is selected by compatibility check, it first calls GetVersion to - // read the version, and then Load is requested. Inside GetVersion, Load won't - // complete. - base::test::TestFuture<const base::Version&> future1; - rootfs_lacros_loader_->GetVersion( - future1.GetCallback<const base::Version&>()); - EXPECT_EQ(base::Version(version_str), future1.Get<0>()); - EXPECT_EQ(RootfsLacrosLoader::State::kVersionReadyButNotLoaded, - rootfs_lacros_loader_->GetState()); - EXPECT_FALSE(callback_called); - - // Load is called after version is calculated. - base::test::TestFuture<base::Version, const base::FilePath&> future2; - rootfs_lacros_loader_->Load( - future2.GetCallback<base::Version, const base::FilePath&>(), - /*forced=*/false); - EXPECT_EQ(base::Version(version_str), future2.Get<0>()); - EXPECT_TRUE(callback_called); - - EXPECT_EQ(RootfsLacrosLoader::State::kLoaded, - rootfs_lacros_loader_->GetState()); -} - -TEST_F(RootfsLacrosLoaderTest, LoadRootfsLacrosSelectedByPolicy) { - bool callback_called = false; - fake_upstart_client_.set_start_job_cb(base::BindRepeating( - [](bool* callback_called, const std::string& job, - const std::vector<std::string>& upstart_env) { - EXPECT_EQ(job, kLacrosMounterUpstartJob); - *callback_called = true; - return ash::FakeUpstartClient::StartJobResult(true /* success */); - }, - &callback_called)); - - EXPECT_EQ(RootfsLacrosLoader::State::kNotLoaded, - rootfs_lacros_loader_->GetState()); - - // If rootfs is selected by policy, it does not call GetVersion. Instead, it - // calls Load directly and compute read the version inside Load together. - base::test::TestFuture<base::Version, const base::FilePath&> future; - rootfs_lacros_loader_->Load( - future.GetCallback<base::Version, const base::FilePath&>(), - /*forced=*/false); - EXPECT_EQ(base::Version(version_str), future.Get<0>()); - EXPECT_TRUE(callback_called); - - EXPECT_EQ(RootfsLacrosLoader::State::kLoaded, - rootfs_lacros_loader_->GetState()); -} - -TEST_F(RootfsLacrosLoaderTest, UnloadRequestedOnVersionReady) { - EXPECT_EQ(RootfsLacrosLoader::State::kNotLoaded, - rootfs_lacros_loader_->GetState()); - - // First, request loader to get version and stops at - // `kVersionReadyButNotLoaded`. - base::test::TestFuture<const base::Version&> future1; - rootfs_lacros_loader_->GetVersion( - future1.GetCallback<const base::Version&>()); - EXPECT_EQ(base::Version(version_str), future1.Get<0>()); - EXPECT_EQ(RootfsLacrosLoader::State::kVersionReadyButNotLoaded, - rootfs_lacros_loader_->GetState()); - - // Simulate the case that stateful is selected by compatibility check so that - // it requests rootfs lacros loader to unload. - base::test::TestFuture<void> future2; - rootfs_lacros_loader_->Unload(future2.GetCallback()); - EXPECT_EQ(RootfsLacrosLoader::State::kUnloaded, - rootfs_lacros_loader_->GetState()); -} - -} // namespace -} // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/stateful_lacros_loader_unittest.cc b/chrome/browser/ash/crosapi/stateful_lacros_loader_unittest.cc index 1b6800b..f27b143c 100644 --- a/chrome/browser/ash/crosapi/stateful_lacros_loader_unittest.cc +++ b/chrome/browser/ash/crosapi/stateful_lacros_loader_unittest.cc
@@ -65,7 +65,6 @@ stateful_lacros_loader_ = std::make_unique<StatefulLacrosLoader>( component_manager_, &mock_component_update_service_, kLacrosComponentName); - EXPECT_TRUE(BrowserLoader::WillLoadStatefulComponentBuilds()); } ~StatefulLacrosLoaderTest() override {
diff --git a/chrome/browser/ash/extensions/users_private/users_private_delegate_factory.h b/chrome/browser/ash/extensions/users_private/users_private_delegate_factory.h index caa3d6c..34bf74450c 100644 --- a/chrome/browser/ash/extensions/users_private/users_private_delegate_factory.h +++ b/chrome/browser/ash/extensions/users_private/users_private_delegate_factory.h
@@ -8,7 +8,7 @@ #include "base/no_destructor.h" #include "chrome/browser/profiles/profile_keyed_service_factory.h" -namespace context { +namespace content { class BrowserContext; }
diff --git a/chrome/browser/ash/input_method/BUILD.gn b/chrome/browser/ash/input_method/BUILD.gn index dd2fb34..5fe38e8d 100644 --- a/chrome/browser/ash/input_method/BUILD.gn +++ b/chrome/browser/ash/input_method/BUILD.gn
@@ -89,8 +89,6 @@ "editor_transition_enums.h", "emoji_suggester.cc", "emoji_suggester.h", - "field_trial.cc", - "field_trial.h", "get_current_window_properties.cc", "get_current_window_properties.h", "grammar_manager.cc",
diff --git a/chrome/browser/ash/input_method/assistive_input_denylist.cc b/chrome/browser/ash/input_method/assistive_input_denylist.cc index 144193f..cdc78f2 100644 --- a/chrome/browser/ash/input_method/assistive_input_denylist.cc +++ b/chrome/browser/ash/input_method/assistive_input_denylist.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ash/input_method/assistive_input_denylist.h" -#include "base/json/json_reader.h" #include "chrome/browser/ash/input_method/url_utils.h" namespace ash { @@ -38,19 +37,6 @@ // Exceptions where the features are enabled. const char* kAllowedDomainsWithPaths[][2] = {{"mail.google", "/chat"}}; -std::vector<std::string> ToDenylist(const base::Value& value) { - if (!value.is_list()) { - return {}; - } - std::vector<std::string> domains; - for (const auto& item : value.GetList()) { - if (item.is_string()) { - domains.push_back(item.GetString()); - } - } - return domains; -} - bool MatchesSubDomainFromDefaultList(const GURL& url) { for (const char* domain : kDefaultDomainDenylist) { if (IsSubDomain(url, domain)) { @@ -60,16 +46,6 @@ return false; } -bool MatchesSubDomainFrom(const std::vector<std::string>& denylist, - const GURL& url) { - for (const auto& domain : denylist) { - if (IsSubDomain(url, domain)) { - return true; - } - } - return false; -} - bool AllowedSubDomainWithPathPrefix(const GURL& url) { for (const auto& [domain, path_prefix] : kAllowedDomainsWithPaths) { if (IsSubDomainWithPathPrefix(url, domain, path_prefix)) { @@ -81,25 +57,12 @@ } // namespace -AssistiveInputDenylist::AssistiveInputDenylist( - const DenylistAdditions& additions) { - if (auto parsed = base::JSONReader::Read(additions.autocorrect_denylist_json); - parsed.has_value() && parsed->is_list()) { - autocorrect_denylist_ = ToDenylist(*parsed); - } - - if (auto parsed = base::JSONReader::Read(additions.multi_word_denylist_json); - parsed.has_value() && parsed->is_list()) { - multi_word_denylist_ = ToDenylist(*parsed); - } -} +AssistiveInputDenylist::AssistiveInputDenylist() = default; AssistiveInputDenylist::~AssistiveInputDenylist() = default; bool AssistiveInputDenylist::Contains(const GURL& url) { - return ((MatchesSubDomainFromDefaultList(url) || - MatchesSubDomainFrom(autocorrect_denylist_, url) || - MatchesSubDomainFrom(multi_word_denylist_, url)) && + return (MatchesSubDomainFromDefaultList(url) && // Used to allow specific paths on a top level domain that has been // denied (for example, "mail.google.com/chat"). !AllowedSubDomainWithPathPrefix(url));
diff --git a/chrome/browser/ash/input_method/assistive_input_denylist.h b/chrome/browser/ash/input_method/assistive_input_denylist.h index b774541..1651fa48 100644 --- a/chrome/browser/ash/input_method/assistive_input_denylist.h +++ b/chrome/browser/ash/input_method/assistive_input_denylist.h
@@ -5,36 +5,22 @@ #ifndef CHROME_BROWSER_ASH_INPUT_METHOD_ASSISTIVE_INPUT_DENYLIST_H_ #define CHROME_BROWSER_ASH_INPUT_METHOD_ASSISTIVE_INPUT_DENYLIST_H_ -#include <optional> -#include <string> -#include <vector> - #include "base/values.h" #include "url/gurl.h" namespace ash { namespace input_method { -struct DenylistAdditions { - const std::string autocorrect_denylist_json; - const std::string multi_word_denylist_json; -}; - // Determines if assistive inputs should be enabled or disabled for a particular // input field. A denylist is made up of a list of urls where assistive // features should NOT show. class AssistiveInputDenylist { public: - AssistiveInputDenylist(const DenylistAdditions& additions); + AssistiveInputDenylist(); ~AssistiveInputDenylist(); // Is the url given found in the denylist? bool Contains(const GURL& url); - - private: - // Holds the specific denylists for each experiment. - std::vector<std::string> autocorrect_denylist_; - std::vector<std::string> multi_word_denylist_; }; } // namespace input_method
diff --git a/chrome/browser/ash/input_method/assistive_input_denylist_unittest.cc b/chrome/browser/ash/input_method/assistive_input_denylist_unittest.cc index d6d9805..7f75fc6 100644 --- a/chrome/browser/ash/input_method/assistive_input_denylist_unittest.cc +++ b/chrome/browser/ash/input_method/assistive_input_denylist_unittest.cc
@@ -4,24 +4,11 @@ #include "chrome/browser/ash/input_method/assistive_input_denylist.h" -#include "chrome/browser/ash/input_method/field_trial.h" #include "testing/gmock/include/gmock/gmock.h" namespace ash { namespace input_method { -std::string Empty() { - return ""; -} - -std::string InvalidJson() { - return "[:]"; -} - -std::string ExampleDenylist() { - return "[\"xyz\", \"uk\", \"subdomain.blah\"]"; -} - using Contains = testing::TestWithParam<std::string>; INSTANTIATE_TEST_SUITE_P( @@ -53,40 +40,7 @@ "http://www.abc.smile.amazon.com.au/abc+com+au/some/other/text")); TEST_P(Contains, Url) { - EXPECT_TRUE(AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = Empty(), - .multi_word_denylist_json = Empty()}) - .Contains(GURL(GetParam()))); -} - -TEST_P(Contains, UrlWhenInvalidJsonPassedAsAutocorrectDenylist) { - EXPECT_TRUE(AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = InvalidJson(), - .multi_word_denylist_json = Empty()}) - .Contains(GURL(GetParam()))); -} - -TEST_P(Contains, UrlWhenInvalidJsonPassedAsMultiWordDenylist) { - EXPECT_TRUE(AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = Empty(), - .multi_word_denylist_json = InvalidJson()}) - .Contains(GURL(GetParam()))); -} - -TEST_P(Contains, UrlWhenAutocorrectDynamicDenylistGiven) { - EXPECT_TRUE( - AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = ExampleDenylist(), - .multi_word_denylist_json = Empty()}) - .Contains(GURL(GetParam()))); -} - -TEST_P(Contains, UrlWhenMultiWordDynamicDenylistGiven) { - EXPECT_TRUE( - AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = Empty(), - .multi_word_denylist_json = ExampleDenylist()}) - .Contains(GURL(GetParam()))); + EXPECT_TRUE(AssistiveInputDenylist().Contains(GURL(GetParam()))); } using DoesNotContain = testing::TestWithParam<std::string>; @@ -109,93 +63,7 @@ "http://.com/test")); TEST_P(DoesNotContain, Url) { - EXPECT_FALSE(AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = Empty(), - .multi_word_denylist_json = Empty()}) - .Contains(GURL(GetParam()))); -} - -TEST_P(DoesNotContain, UrlWhenInvalidJsonPassedAsAutocorrectDenylist) { - EXPECT_FALSE(AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = InvalidJson(), - .multi_word_denylist_json = Empty()}) - .Contains(GURL(GetParam()))); -} - -TEST_P(DoesNotContain, UrlWhenInvalidJsonPassedAsMultiWordDenylist) { - EXPECT_FALSE(AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = Empty(), - .multi_word_denylist_json = InvalidJson()}) - .Contains(GURL(GetParam()))); -} - -TEST_P(DoesNotContain, UrlWhenAutocorrectDynamicDenylistGiven) { - EXPECT_FALSE( - AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = ExampleDenylist(), - .multi_word_denylist_json = Empty()}) - .Contains(GURL(GetParam()))); -} - -TEST_P(DoesNotContain, UrlWhenMultiWordDynamicDenylistGiven) { - EXPECT_FALSE( - AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = Empty(), - .multi_word_denylist_json = ExampleDenylist()}) - .Contains(GURL(GetParam()))); -} - -struct UrlExample { - std::string url; - bool found_in_list; -}; - -using UsesDynamicDenylist = testing::TestWithParam<UrlExample>; - -INSTANTIATE_TEST_SUITE_P( - AssistiveInputDenylistTest, - UsesDynamicDenylist, - testing::Values( - // Disabled examples - UrlExample{"http://xyz.com", /*found_in_list=*/true}, - UrlExample{"https://xyz.com", /*found_in_list=*/true}, - UrlExample{"https://www.xyz.com", /*found_in_list=*/true}, - UrlExample{"https://xyz.com/with-path", /*found_in_list=*/true}, - UrlExample{"https://xyz.com/with-path?and=params", - /*found_in_list=*/true}, - UrlExample{"https://uk.com", /*found_in_list=*/true}, - UrlExample{"https://subdomain.blah.com", /*found_in_list=*/true}, - UrlExample{"https://subdomain.blah.com/with-path", - /*found_in_list=*/true}, - // Enabled examples - UrlExample{"https://www.something.co.uk", /*found_in_list=*/false}, - UrlExample{"https://something.co.uk/with-path", - /*found_in_list=*/false}, - UrlExample{"https://blah.com", /*found_in_list=*/false}, - UrlExample{"https://something.blah.com", /*found_in_list=*/false}, - UrlExample{"https://something.blah.com/with-path", - /*found_in_list=*/false})); - -TEST_P(UsesDynamicDenylist, ForAutocorrect) { - const UrlExample& example = GetParam(); - - EXPECT_EQ( - AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = ExampleDenylist(), - .multi_word_denylist_json = Empty()}) - .Contains(GURL(example.url)), - example.found_in_list); -} - -TEST_P(UsesDynamicDenylist, ForMultiWord) { - const UrlExample& example = GetParam(); - - EXPECT_EQ( - AssistiveInputDenylist( - DenylistAdditions{.autocorrect_denylist_json = Empty(), - .multi_word_denylist_json = ExampleDenylist()}) - .Contains(GURL(example.url)), - example.found_in_list); + EXPECT_FALSE(AssistiveInputDenylist().Contains(GURL(GetParam()))); } } // namespace input_method
diff --git a/chrome/browser/ash/input_method/assistive_suggester_client_filter.cc b/chrome/browser/ash/input_method/assistive_suggester_client_filter.cc index 45b150b8..2ba3f94 100644 --- a/chrome/browser/ash/input_method/assistive_suggester_client_filter.cc +++ b/chrome/browser/ash/input_method/assistive_suggester_client_filter.cc
@@ -17,7 +17,6 @@ #include "ash/public/cpp/window_properties.h" #include "base/functional/callback.h" #include "base/hash/hash.h" -#include "chrome/browser/ash/input_method/field_trial.h" #include "chrome/browser/ash/input_method/url_utils.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" @@ -262,14 +261,7 @@ GetUrlCallback get_url, GetFocusedWindowPropertiesCallback get_window_properties) : get_url_(std::move(get_url)), - get_window_properties_(std::move(get_window_properties)), - denylist_(DenylistAdditions{ - .autocorrect_denylist_json = - GetFieldTrialParam(features::kAutocorrectByDefault, - ParamName::kDenylist), - .multi_word_denylist_json = - GetFieldTrialParam(features::kAssistMultiWord, - ParamName::kDenylist)}) {} + get_window_properties_(std::move(get_window_properties)) {} AssistiveSuggesterClientFilter::~AssistiveSuggesterClientFilter() = default;
diff --git a/chrome/browser/ash/input_method/autocorrect_manager.cc b/chrome/browser/ash/input_method/autocorrect_manager.cc index 7fd00ee..405e3a8 100644 --- a/chrome/browser/ash/input_method/autocorrect_manager.cc +++ b/chrome/browser/ash/input_method/autocorrect_manager.cc
@@ -16,12 +16,10 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "chrome/browser/ash/crosapi/browser_util.h" -#include "chrome/browser/ash/input_method/assistive_input_denylist.h" #include "chrome/browser/ash/input_method/assistive_prefs.h" #include "chrome/browser/ash/input_method/assistive_window_properties.h" #include "chrome/browser/ash/input_method/autocorrect_enums.h" #include "chrome/browser/ash/input_method/autocorrect_prefs.h" -#include "chrome/browser/ash/input_method/field_trial.h" #include "chrome/browser/ash/input_method/suggestion_enums.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" @@ -344,15 +342,7 @@ AutocorrectManager::AutocorrectManager( SuggestionHandlerInterface* suggestion_handler, Profile* profile) - : denylist_(DenylistAdditions{ - .autocorrect_denylist_json = - GetFieldTrialParam(features::kAutocorrectByDefault, - ParamName::kDenylist), - .multi_word_denylist_json = - GetFieldTrialParam(features::kAssistMultiWord, - ParamName::kDenylist)}), - suggestion_handler_(suggestion_handler), - profile_(profile) { + : suggestion_handler_(suggestion_handler), profile_(profile) { undo_button_.id = ui::ime::ButtonId::kUndo; undo_button_.window_type = ash::ime::AssistiveWindowType::kUndoWindow; learn_more_button_.id = ui::ime::ButtonId::kLearnMore;
diff --git a/chrome/browser/ash/input_method/field_trial.cc b/chrome/browser/ash/input_method/field_trial.cc deleted file mode 100644 index 1c79031..0000000 --- a/chrome/browser/ash/input_method/field_trial.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ash/input_method/field_trial.h" - -#include "base/metrics/field_trial_params.h" - -namespace ash { -namespace input_method { - -std::string ToString(const ParamName& param_name) { - switch (param_name) { - case ParamName::kDenylist: - return "block"; - } -} - -std::string GetFieldTrialParam(const base::Feature& feature, - const ParamName& param_name) { - return base::GetFieldTrialParamValueByFeature(feature, ToString(param_name)); -} - -} // namespace input_method -} // namespace ash
diff --git a/chrome/browser/ash/input_method/field_trial.h b/chrome/browser/ash/input_method/field_trial.h deleted file mode 100644 index 79315a19..0000000 --- a/chrome/browser/ash/input_method/field_trial.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ASH_INPUT_METHOD_FIELD_TRIAL_H_ -#define CHROME_BROWSER_ASH_INPUT_METHOD_FIELD_TRIAL_H_ - -#include <string> - -#include "base/feature_list.h" - -namespace ash { -namespace input_method { - -enum class ParamName { kDenylist }; - -std::string GetFieldTrialParam(const base::Feature& feature, - const ParamName& param_name); - -} // namespace input_method -} // namespace ash - -#endif // CHROME_BROWSER_ASH_INPUT_METHOD_FIELD_TRIAL_H_
diff --git a/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service.cc b/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service.cc index a6c1772..d0aca73 100644 --- a/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service.cc +++ b/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service.cc
@@ -28,9 +28,6 @@ PrefService* pref_service = user_prefs::UserPrefs::Get(browser_context_.get()); - // TODO(b/188864779, acostinas): After the ARC legacy migration is completed, - // monitor the Always-on VPN state from the network profile property instead - // of the user pref. profile_pref_change_registrar_.Init(pref_service); profile_pref_change_registrar_.Add( arc::prefs::kAlwaysOnVpnLockdown,
diff --git a/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service_browsertest.cc b/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service_browsertest.cc index 4a5ea3c..1ad5de6 100644 --- a/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service_browsertest.cc +++ b/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service_browsertest.cc
@@ -10,22 +10,19 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/values.h" -#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service_factory.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" -#include "chromeos/ash/components/browser_context_helper/browser_context_helper.h" #include "chromeos/ash/components/dbus/shill/shill_service_client.h" #include "chromeos/ash/components/network/network_handler_test_helper.h" #include "components/account_id/account_id.h" #include "components/policy/core/common/policy_pref_names.h" #include "components/prefs/pref_service.h" -#include "components/user_manager/fake_user_manager.h" -#include "components/user_manager/scoped_user_manager.h" #include "content/public/test/browser_test.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gtest/include/gtest/gtest.h" @@ -37,8 +34,6 @@ constexpr char kDefaultEthernetPath[] = "/service/eth1"; constexpr char kDefaultVpnPath[] = "/service/vpn1"; -constexpr char kFakePrimaryUsername[] = "test-primary@example.com"; - constexpr char kTestUrl[] = "test.url.com"; } // namespace @@ -59,6 +54,28 @@ ash::AlwaysOnVpnPreConnectUrlAllowlistServiceFactory::GetInstance() ->SetServiceIsNULLWhileTestingForTesting( /*service_is_null_while_testing=*/false); + + network_handler_test_helper_ = + std::make_unique<::ash::NetworkHandlerTestHelper>(); + ShillServiceClient::Get()->GetTestInterface()->SetServiceProperty( + "/service/wifi1", shill::kStateProperty, + base::Value(shill::kStateIdle)); + + browser() + ->profile() + ->GetProfilePolicyConnector() + ->OverrideIsManagedForTesting(true); + + // The AlwaysOnVpnPreConnectUrlAllowlistService keyed service for this + // profile needs to be disassociated with the null object so that a new + // instance of the service is created. + ash::AlwaysOnVpnPreConnectUrlAllowlistServiceFactory::GetInstance() + ->RecreateServiceInstanceForTesting(browser()->profile()); + + // The service should be created for a managed profile. + ASSERT_TRUE( + ash::AlwaysOnVpnPreConnectUrlAllowlistServiceFactory::GetForProfile( + browser()->profile())); } void TearDownOnMainThread() override { @@ -67,90 +84,6 @@ ->SetServiceIsNULLWhileTestingForTesting( /*service_is_null_while_testing=*/true); } -}; - -IN_PROC_BROWSER_TEST_F(AlwaysOnVpnPreConnectUrlAllowlistServiceTest, - NoServiceForUnmanagedProfiles) { - // The service should be null because the profile is not managed. - EXPECT_FALSE( - ash::AlwaysOnVpnPreConnectUrlAllowlistServiceFactory::GetForProfile( - browser()->profile())); -} - -IN_PROC_BROWSER_TEST_F(AlwaysOnVpnPreConnectUrlAllowlistServiceTest, - NoServiceForSecondaryProfiles) { - // Create a secondary managed profile. - TestingProfile::Builder profile_builder; - profile_builder.OverridePolicyConnectorIsManagedForTesting( - /*is_managed*/ true); - std::unique_ptr<TestingProfile> managed_profile = profile_builder.Build(); - - EXPECT_FALSE( - ash::AlwaysOnVpnPreConnectUrlAllowlistServiceFactory::GetForProfile( - browser()->profile())); -} - -class AlwaysOnVpnPreConnectUrlAllowlistServiceManagedProfileTest - : public AlwaysOnVpnPreConnectUrlAllowlistServiceTest { - public: - AlwaysOnVpnPreConnectUrlAllowlistServiceManagedProfileTest() = default; - AlwaysOnVpnPreConnectUrlAllowlistServiceManagedProfileTest( - const AlwaysOnVpnPreConnectUrlAllowlistServiceManagedProfileTest&) = - delete; - AlwaysOnVpnPreConnectUrlAllowlistServiceManagedProfileTest& operator=( - const AlwaysOnVpnPreConnectUrlAllowlistServiceManagedProfileTest&) = - delete; - ~AlwaysOnVpnPreConnectUrlAllowlistServiceManagedProfileTest() override = - default; - - void SetUpOnMainThread() override { - AlwaysOnVpnPreConnectUrlAllowlistServiceTest::SetUpOnMainThread(); - network_handler_test_helper_ = - std::make_unique<::ash::NetworkHandlerTestHelper>(); - ShillServiceClient::Get()->GetTestInterface()->SetServiceProperty( - "/service/wifi1", shill::kStateProperty, - base::Value(shill::kStateIdle)); - - // Create a primary managed profile. - fake_user_manager_.Reset(std::make_unique<ash::FakeChromeUserManager>()); - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - TestingProfile::Builder profile_builder; - profile_builder.SetPath(temp_dir_.GetPath().AppendASCII( - BrowserContextHelper::GetUserBrowserContextDirName( - user_manager::FakeUserManager::GetFakeUsernameHash( - AccountId::FromUserEmail(kFakePrimaryUsername))))); - profile_builder.SetProfileName(kFakePrimaryUsername); - profile_builder.OverridePolicyConnectorIsManagedForTesting( - /*is_managed*/ true); - - managed_profile_ = profile_builder.Build(); - primary_account_id_ = - AccountId::FromUserEmail(managed_profile_->GetProfileUserName()); - const user_manager::User* user = - fake_user_manager_->AddPublicAccountUser(primary_account_id_); - fake_user_manager_->UserLoggedIn(primary_account_id_, user->username_hash(), - false /* browser_restart */, - false /* is_child */); - fake_user_manager_->SetIsCurrentUserNew(/*is_new=*/true); - - // The AlwaysOnVpnPreConnectUrlAllowlistService keyed service for this - // profile needs to be disassociated with the null object so that a new - // instance of the service is created. - ash::AlwaysOnVpnPreConnectUrlAllowlistServiceFactory::GetInstance() - ->RecreateServiceInstanceForTesting(managed_profile_.get()); - - // The service should be created for a managed profile. - ASSERT_TRUE( - ash::AlwaysOnVpnPreConnectUrlAllowlistServiceFactory::GetForProfile( - managed_profile())); - } - - void TearDownOnMainThread() override { - fake_user_manager_->RemoveUserFromList(primary_account_id_); - managed_profile_.reset(); - fake_user_manager_.Reset(); - AlwaysOnVpnPreConnectUrlAllowlistServiceTest::TearDownOnMainThread(); - } protected: void SetVpnConnectionState(bool vpn_enabled) { @@ -179,49 +112,59 @@ ash::NetworkState::NetworkTechnologyType::kVPN); base::Value::List list; list.Append(kTestUrl); - managed_profile()->GetPrefs()->SetList( + browser()->profile()->GetPrefs()->SetList( policy::policy_prefs::kAlwaysOnVpnPreConnectUrlAllowlist, std::move(list)); - managed_profile()->GetPrefs()->SetBoolean(arc::prefs::kAlwaysOnVpnLockdown, - true); + browser()->profile()->GetPrefs()->SetBoolean( + arc::prefs::kAlwaysOnVpnLockdown, true); } bool IsPreConnectListEnforced() { return ash::AlwaysOnVpnPreConnectUrlAllowlistServiceFactory::GetForProfile( - managed_profile()) + browser()->profile()) ->enforce_alwayson_pre_connect_url_allowlist(); } - Profile* managed_profile() { return managed_profile_.get(); } - private: std::unique_ptr<::ash::NetworkHandlerTestHelper> network_handler_test_helper_; std::unique_ptr<AlwaysOnVpnPreConnectUrlAllowlistService> alwayson_vpn_pre_connect_url_allowlist_service_; - std::unique_ptr<TestingProfile> managed_profile_; - base::ScopedTempDir temp_dir_; - user_manager::TypedScopedUserManager<ash::FakeChromeUserManager> - fake_user_manager_; - AccountId primary_account_id_; }; // Ensure that the local state pref kEnforceAlwaysOnVpnPreConnectUrlAllowlist is // true when the kAlwaysOnVpnPreConnectUrlAllowlist is set but the AlwaysOn VPN // is not yet connected. -IN_PROC_BROWSER_TEST_F( - AlwaysOnVpnPreConnectUrlAllowlistServiceManagedProfileTest, - PreConnectListEnabled) { +IN_PROC_BROWSER_TEST_F(AlwaysOnVpnPreConnectUrlAllowlistServiceTest, + PreConnectListEnabled) { EXPECT_FALSE(IsPreConnectListEnforced()); CreatePreConnectListEnv(); EXPECT_TRUE(IsPreConnectListEnforced()); } // Ensure that the local state pref kEnforceAlwaysOnVpnPreConnectUrlAllowlist is +// also enforced for incognito profiles. +IN_PROC_BROWSER_TEST_F(AlwaysOnVpnPreConnectUrlAllowlistServiceTest, + IncognitoModePreConnectListEnabled) { + EXPECT_FALSE(IsPreConnectListEnforced()); + CreatePreConnectListEnv(); + + // Create an incognito profile. + Profile* incognito_profile = + browser()->profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true); + + AlwaysOnVpnPreConnectUrlAllowlistService* service = + ash::AlwaysOnVpnPreConnectUrlAllowlistServiceFactory::GetForProfile( + incognito_profile); + ASSERT_THAT(service, testing::NotNull()); + + EXPECT_TRUE(service->enforce_alwayson_pre_connect_url_allowlist()); +} + +// Ensure that the local state pref kEnforceAlwaysOnVpnPreConnectUrlAllowlist is // false when the VPN is connected. -IN_PROC_BROWSER_TEST_F( - AlwaysOnVpnPreConnectUrlAllowlistServiceManagedProfileTest, - VpnConnected) { +IN_PROC_BROWSER_TEST_F(AlwaysOnVpnPreConnectUrlAllowlistServiceTest, + VpnConnected) { CreatePreConnectListEnv(); EXPECT_TRUE(IsPreConnectListEnforced()); @@ -237,22 +180,21 @@ // Ensure that the local state pref kEnforceAlwaysOnVpnPreConnectUrlAllowlist is // false when the kAlwaysOnVpnPreConnectUrlAllowlist pref is not set. -IN_PROC_BROWSER_TEST_F( - AlwaysOnVpnPreConnectUrlAllowlistServiceManagedProfileTest, - AlwaysOnVpnPreConnectUrlAllowlistEmpty) { +IN_PROC_BROWSER_TEST_F(AlwaysOnVpnPreConnectUrlAllowlistServiceTest, + AlwaysOnVpnPreConnectUrlAllowlistEmpty) { CreatePreConnectListEnv(); EXPECT_TRUE(IsPreConnectListEnforced()); // Create and set an empty list. base::Value::List list; - managed_profile()->GetPrefs()->SetList( + browser()->profile()->GetPrefs()->SetList( policy::policy_prefs::kAlwaysOnVpnPreConnectUrlAllowlist, list.Clone()); EXPECT_FALSE(IsPreConnectListEnforced()); // Set a value for the kAlwaysOnVpnPreConnectUrlAllowlist pref again and // verify that the pre-connect list is again enforced. list.Append(kTestUrl); - managed_profile()->GetPrefs()->SetList( + browser()->profile()->GetPrefs()->SetList( policy::policy_prefs::kAlwaysOnVpnPreConnectUrlAllowlist, std::move(list)); EXPECT_TRUE(IsPreConnectListEnforced()); @@ -260,22 +202,35 @@ // Ensure that the local state pref kEnforceAlwaysOnVpnPreConnectUrlAllowlist is // false when the VPN is not in lockdown mode. -IN_PROC_BROWSER_TEST_F( - AlwaysOnVpnPreConnectUrlAllowlistServiceManagedProfileTest, - AlwaysOnVpnFalse) { +IN_PROC_BROWSER_TEST_F(AlwaysOnVpnPreConnectUrlAllowlistServiceTest, + AlwaysOnVpnFalse) { CreatePreConnectListEnv(); EXPECT_TRUE(IsPreConnectListEnforced()); // Remove lockdown mode. - managed_profile()->GetPrefs()->SetBoolean(arc::prefs::kAlwaysOnVpnLockdown, - false); + browser()->profile()->GetPrefs()->SetBoolean(arc::prefs::kAlwaysOnVpnLockdown, + false); EXPECT_FALSE(IsPreConnectListEnforced()); // Set lockdown mode and verify that the pre-connect list is again // enforced. - managed_profile()->GetPrefs()->SetBoolean(arc::prefs::kAlwaysOnVpnLockdown, - true); + browser()->profile()->GetPrefs()->SetBoolean(arc::prefs::kAlwaysOnVpnLockdown, + true); EXPECT_TRUE(IsPreConnectListEnforced()); } +IN_PROC_BROWSER_TEST_F(AlwaysOnVpnPreConnectUrlAllowlistServiceTest, + NoEnforcementForSecondaryProfiles) { + // Create a secondary managed profile. + TestingProfile::Builder profile_builder; + profile_builder.OverridePolicyConnectorIsManagedForTesting( + /*is_managed*/ true); + std::unique_ptr<TestingProfile> managed_profile = profile_builder.Build(); + + EXPECT_FALSE( + ash::AlwaysOnVpnPreConnectUrlAllowlistServiceFactory::GetForProfile( + managed_profile.get()) + ->enforce_alwayson_pre_connect_url_allowlist()); +} + } // namespace ash
diff --git a/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service_factory.cc b/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service_factory.cc index 9dbb4d0..db9bc0b 100644 --- a/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service_factory.cc +++ b/chrome/browser/ash/net/alwayson_vpn_pre_connect_url_allowlist_service_factory.cc
@@ -43,11 +43,7 @@ : ProfileKeyedServiceFactory( "AlwaysOnVpnPreConnectUrlAllowlistService", ProfileSelections::Builder() - .WithRegular(ProfileSelection::kOriginalOnly) - .WithGuest(ProfileSelection::kOriginalOnly) - // TODO(crbug.com/41488885): Check if this service is needed for - // Ash Internals. - .WithAshInternals(ProfileSelection::kOriginalOnly) + .WithRegular(ProfileSelection::kOwnInstance) .Build()) {} AlwaysOnVpnPreConnectUrlAllowlistServiceFactory:: @@ -56,13 +52,8 @@ std::unique_ptr<KeyedService> AlwaysOnVpnPreConnectUrlAllowlistServiceFactory:: BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - Profile* profile = Profile::FromBrowserContext(context); - if (!user_manager::UserManager::Get()->IsPrimaryUser( - ash::BrowserContextHelper::Get()->GetUserByBrowserContext(context)) || - !profile->GetProfilePolicyConnector()->IsManaged()) { - return nullptr; - } - return std::make_unique<AlwaysOnVpnPreConnectUrlAllowlistService>(profile); + return std::make_unique<AlwaysOnVpnPreConnectUrlAllowlistService>( + Profile::FromBrowserContext(context)); } bool AlwaysOnVpnPreConnectUrlAllowlistServiceFactory::
diff --git a/chrome/browser/ash/policy/handlers/BUILD.gn b/chrome/browser/ash/policy/handlers/BUILD.gn index c14fdc5..e07256f 100644 --- a/chrome/browser/ash/policy/handlers/BUILD.gn +++ b/chrome/browser/ash/policy/handlers/BUILD.gn
@@ -32,8 +32,6 @@ "device_wifi_allowed_handler.h", "help_me_read_policy_handler.cc", "help_me_read_policy_handler.h", - "lacros_availability_policy_handler.cc", - "lacros_availability_policy_handler.h", "lacros_selection_policy_handler.cc", "lacros_selection_policy_handler.h", "lock_to_single_user_manager.cc",
diff --git a/chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.cc b/chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.cc deleted file mode 100644 index 8194d96a..0000000 --- a/chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.cc +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.h" - -#if !BUILDFLAG(IS_CHROMEOS_ASH) -#error This file shall only be used in ash. -#endif - -#include "chrome/common/pref_names.h" -#include "components/policy/core/browser/policy_error_map.h" -#include "components/policy/policy_constants.h" -#include "components/prefs/pref_value_map.h" -#include "components/strings/grit/components_strings.h" - -namespace policy { - -LacrosAvailabilityPolicyHandler::LacrosAvailabilityPolicyHandler() - : TypeCheckingPolicyHandler(key::kLacrosAvailability, - base::Value::Type::STRING) {} - -LacrosAvailabilityPolicyHandler::~LacrosAvailabilityPolicyHandler() = default; - -bool LacrosAvailabilityPolicyHandler::CheckPolicySettings( - const PolicyMap& policies, - PolicyErrorMap* errors) { - return GetValue(policies, errors).has_value(); -} - -void LacrosAvailabilityPolicyHandler::ApplyPolicySettings( - const PolicyMap& policies, - PrefValueMap* prefs) { - auto enum_value = GetValue(policies, nullptr); - if (enum_value.has_value()) { - prefs->SetInteger(prefs::kLacrosLaunchSwitch, - static_cast<int>(*enum_value)); - } -} - -std::optional<ash::standalone_browser::LacrosAvailability> -LacrosAvailabilityPolicyHandler::GetValue(const PolicyMap& policies, - PolicyErrorMap* errors) { - const base::Value* value; - const bool value_found = CheckAndGetValue(policies, errors, &value) && value; - if (!value_found) - return std::nullopt; - - auto parsed = - ash::standalone_browser::ParseLacrosAvailability(value->GetString()); - if (!parsed.has_value() && errors) - errors->AddError(policy_name(), IDS_POLICY_INVALID_SELECTION_ERROR, - "LacrosAvailabilty value"); - return parsed; -} - -} // namespace policy
diff --git a/chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.h b/chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.h deleted file mode 100644 index e876e89..0000000 --- a/chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_LACROS_AVAILABILITY_POLICY_HANDLER_H_ -#define CHROME_BROWSER_ASH_POLICY_HANDLERS_LACROS_AVAILABILITY_POLICY_HANDLER_H_ - -#include <optional> - -#include "build/buildflag.h" -#include "build/chromeos_buildflags.h" -#include "chromeos/ash/components/standalone_browser/lacros_availability.h" -#include "components/policy/core/browser/configuration_policy_handler.h" - -#if !BUILDFLAG(IS_CHROMEOS_ASH) -#error This file shall only be used in ash. -#endif // BUILDFLAG(IS_CHROMEOS_ASH) - -class PrefValueMap; - -namespace policy { - -class PolicyMap; - -class LacrosAvailabilityPolicyHandler : public TypeCheckingPolicyHandler { - public: - LacrosAvailabilityPolicyHandler(); - - ~LacrosAvailabilityPolicyHandler() override; - - // ConfigurationPolicyHandler: - bool CheckPolicySettings(const PolicyMap& policies, - PolicyErrorMap* errors) override; - - void ApplyPolicySettings(const PolicyMap& policies, - PrefValueMap* prefs) override; - - private: - std::optional<ash::standalone_browser::LacrosAvailability> GetValue( - const PolicyMap& policies, - PolicyErrorMap* errors); -}; - -} // namespace policy - -#endif // CHROME_BROWSER_ASH_POLICY_HANDLERS_LACROS_AVAILABILITY_POLICY_HANDLER_H_
diff --git a/chrome/browser/ash/preferences/preferences.cc b/chrome/browser/ash/preferences/preferences.cc index cd1bdce..4bbeff12 100644 --- a/chrome/browser/ash/preferences/preferences.cc +++ b/chrome/browser/ash/preferences/preferences.cc
@@ -59,7 +59,6 @@ #include "chromeos/ash/components/peripheral_notification/peripheral_notification_manager.h" #include "chromeos/ash/components/settings/cros_settings.h" #include "chromeos/ash/components/settings/cros_settings_names.h" -#include "chromeos/ash/components/standalone_browser/lacros_availability.h" #include "chromeos/ash/components/standalone_browser/lacros_selection.h" #include "chromeos/ash/components/system/statistics_provider.h" #include "chromeos/ash/components/timezone/timezone_resolver.h" @@ -155,10 +154,6 @@ enterprise_management::SystemTimezoneProto::USERS_DECIDE); registry->RegisterStringPref(::prefs::kMinimumAllowedChromeVersion, ""); registry->RegisterIntegerPref( - ::prefs::kLacrosLaunchSwitch, - static_cast<int>( - ash::standalone_browser::LacrosAvailability::kUserChoice)); - registry->RegisterIntegerPref( ::prefs::kLacrosSelection, static_cast<int>( ash::standalone_browser::LacrosSelectionPolicy::kUserChoice));
diff --git a/chrome/browser/ash/scanner/chrome_scanner_delegate.cc b/chrome/browser/ash/scanner/chrome_scanner_delegate.cc index 0a22481..8613ad8 100644 --- a/chrome/browser/ash/scanner/chrome_scanner_delegate.cc +++ b/chrome/browser/ash/scanner/chrome_scanner_delegate.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "ash/public/cpp/scanner/scanner_feedback_info.h" #include "ash/public/cpp/scanner/scanner_profile_scoped_delegate.h" #include "ash/scanner/scanner_controller.h" #include "chrome/browser/ash/scanner/scanner_keyed_service_factory.h" @@ -21,7 +22,8 @@ ProfileManager::GetActiveUserProfile()); } -void ChromeScannerDelegate::OpenFeedbackDialog() { - auto* dialog = new ash::ScannerFeedbackDialog(); +void ChromeScannerDelegate::OpenFeedbackDialog( + ash::ScannerFeedbackInfo feedback_info) { + auto* dialog = new ash::ScannerFeedbackDialog(std::move(feedback_info)); dialog->ShowSystemDialog(); }
diff --git a/chrome/browser/ash/scanner/chrome_scanner_delegate.h b/chrome/browser/ash/scanner/chrome_scanner_delegate.h index 5ac6280..3b0faefe 100644 --- a/chrome/browser/ash/scanner/chrome_scanner_delegate.h +++ b/chrome/browser/ash/scanner/chrome_scanner_delegate.h
@@ -22,7 +22,7 @@ // ash::ScannerDelegate: ash::ScannerProfileScopedDelegate* GetProfileScopedDelegate() override; - void OpenFeedbackDialog() override; + void OpenFeedbackDialog(ash::ScannerFeedbackInfo feedback_info) override; }; #endif // CHROME_BROWSER_ASH_SCANNER_CHROME_SCANNER_DELEGATE_H_
diff --git a/chrome/browser/ash/settings/about_flags.cc b/chrome/browser/ash/settings/about_flags.cc index af874bd..25ced7d 100644 --- a/chrome/browser/ash/settings/about_flags.cc +++ b/chrome/browser/ash/settings/about_flags.cc
@@ -20,7 +20,6 @@ #include "chromeos/ash/components/cryptohome/cryptohome_parameters.h" #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h" #include "chromeos/ash/components/settings/cros_settings_names.h" -#include "chromeos/ash/components/standalone_browser/lacros_availability.h" #include "components/account_id/account_id.h" #include "components/flags_ui/flags_storage.h" #include "components/flags_ui/flags_ui_pref_names.h" @@ -205,43 +204,10 @@ if (!primary_user || primary_user != user_manager->GetActiveUser()) return; - std::set<std::string> flags = flags_; - - // If LacrosAvailability policy is set, inject it into the feature flag, - // so that the value is preserved on restarting the Chrome. - // This is a kind of pseudo feature flag, so do not apply it in - // ApplyUserPolicyToFlags to store in |flags_|, otherwise the value will - // be used to decide whether or not to reboot to apply feature flags. - const PrefService::Preference* lacros_launch_switch_pref = - g_browser_process->local_state()->FindPreference( - ::prefs::kLacrosLaunchSwitch); - if (lacros_launch_switch_pref->IsManaged()) { - // If there's the value, convert it into the feature name. - std::string_view value = - ash::standalone_browser::GetLacrosAvailabilityPolicyName( - static_cast<ash::standalone_browser::LacrosAvailability>( - lacros_launch_switch_pref->GetValue()->GetInt())); - DCHECK(!value.empty()) - << "The unexpect value is set to LacrosAvailability: " - << lacros_launch_switch_pref->GetValue()->GetInt(); - auto* entry = ::about_flags::GetCurrentFlagsState()->FindFeatureEntryByName( - ash::standalone_browser::kLacrosAvailabilityPolicyInternalName); - DCHECK(entry); - int index; - for (index = 0; index < entry->NumOptions(); ++index) { - if (value == entry->ChoiceForOption(index).command_line_value) - break; - } - if (static_cast<size_t>(index) != entry->choices.size()) { - LOG(ERROR) << "Updating the lacros_availability: " << index; - flags.insert(entry->NameForOption(index)); - } - } - auto account_id = cryptohome::CreateAccountIdentifierFromAccountId( primary_user->GetAccountId()); SessionManagerClient::Get()->SetFeatureFlagsForUser( - account_id, {flags.begin(), flags.end()}, origin_list_flags_); + account_id, {flags_.begin(), flags_.end()}, origin_list_flags_); } // static
diff --git a/chrome/browser/ash/system_web_apps/apps/projector_app/untrusted_projector_ui_config.cc b/chrome/browser/ash/system_web_apps/apps/projector_app/untrusted_projector_ui_config.cc index 220fe05..5f18f89 100644 --- a/chrome/browser/ash/system_web_apps/apps/projector_app/untrusted_projector_ui_config.cc +++ b/chrome/browser/ash/system_web_apps/apps/projector_app/untrusted_projector_ui_config.cc
@@ -37,6 +37,8 @@ source->AddBoolean("isDynamicColorsEnabled", ash::features::IsProjectorDynamicColorsEnabled()); source->AddBoolean("isGm3Enabled", ash::features::IsProjectorGm3Enabled()); + source->AddBoolean("useDvsPlaybackEndpoint", + ash::features::IsProjectorUseDVSPlaybackEndpointEnabled()); source->AddBoolean( "isInternalServerSideSpeechRecognitionEnabled",
diff --git a/chrome/browser/autofill/autofill_offer_manager_factory.cc b/chrome/browser/autofill/autofill_offer_manager_factory.cc index 0e0ad39..00f4190 100644 --- a/chrome/browser/autofill/autofill_offer_manager_factory.cc +++ b/chrome/browser/autofill/autofill_offer_manager_factory.cc
@@ -7,6 +7,7 @@ #include "base/no_destructor.h" #include "build/build_config.h" #include "chrome/browser/autofill/personal_data_manager_factory.h" +#include "components/autofill/core/browser/data_manager/personal_data_manager.h" #include "components/autofill/core/browser/payments/autofill_offer_manager.h" namespace autofill { @@ -45,7 +46,8 @@ AutofillOfferManagerFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { return std::make_unique<AutofillOfferManager>( - PersonalDataManagerFactory::GetForBrowserContext(context)); + &PersonalDataManagerFactory::GetForBrowserContext(context) + ->payments_data_manager()); } } // namespace autofill
diff --git a/chrome/browser/browsing_data/browsing_data_model_browsertest.cc b/chrome/browser/browsing_data/browsing_data_model_browsertest.cc index 647f85c..5eb104de 100644 --- a/chrome/browser/browsing_data/browsing_data_model_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_model_browsertest.cc
@@ -480,14 +480,7 @@ public ::testing::WithParamInterface<bool> { public: BrowsingDataModelBrowserTest() { - auto& field_trial_param = - network::features::kTrustTokenOperationsRequiringOriginTrial; std::vector<FeatureRefAndParams> enabled_features = { - {network::features::kPrivateStateTokens, - {{field_trial_param.name, - field_trial_param.GetName( - network::features::TrustTokenOriginTrialSpec:: - kOriginTrialNotRequired)}}}, {features::kPrivacySandboxAdsAPIsOverride, {}}, {features::kIsolatedWebApps, {}}, {features::kIsolatedWebAppDevMode, {}},
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc index 5fa8ce6..548ba93 100644 --- a/chrome/browser/chrome_browser_interface_binders.cc +++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -306,6 +306,7 @@ #include "ash/webui/recorder_app_ui/recorder_app_ui.h" #include "ash/webui/sanitize_ui/mojom/sanitize_ui.mojom.h" #include "ash/webui/sanitize_ui/sanitize_ui.h" +#include "ash/webui/scanner_feedback_ui/mojom/scanner_feedback_ui.mojom.h" #include "ash/webui/scanner_feedback_ui/scanner_feedback_untrusted_ui.h" #include "ash/webui/scanning/mojom/scanning.mojom.h" #include "ash/webui/scanning/scanning_ui.h" @@ -1795,7 +1796,8 @@ .Add<color_change_listener::mojom::PageHandler>(); registry.ForWebUI<ash::ScannerFeedbackUntrustedUI>() - .Add<color_change_listener::mojom::PageHandler>(); + .Add<color_change_listener::mojom::PageHandler>() + .Add<ash::mojom::scanner_feedback_ui::PageHandler>(); #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OFFICIAL_BUILD)
diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc index d7d1bfd..058f17d 100644 --- a/chrome/browser/client_hints/client_hints_browsertest.cc +++ b/chrome/browser/client_hints/client_hints_browsertest.cc
@@ -4801,11 +4801,7 @@ ui_test_utils::NavigateToURL(otr_browser, without_accept_ch_url())); } -// Validate that the updated GREASE algorithm is used by default. The continued -// support of the old algorithm (which used only semicolon and space) is tested -// separately below. That functionality will be maintained for a period of time -// until we are confident in more permutations generated by the updated -// algorithm. +// Validate that the updated GREASE algorithm is used by default. IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, UpdatedGREASEByDefault) { const GURL gurl = accept_ch_url(); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), gurl)); @@ -4814,29 +4810,6 @@ ASSERT_TRUE(SawUpdatedGrease(ua_ch_result) && !SawOldGrease(ua_ch_result)); } -class GreaseFeatureParamOptOutTest : public ClientHintsBrowserTest { - // Test that feature param opt outs are able to trigger the old algorithm, - // which we will maintain until additional confidence in the permutations of - // the new algorithm is attained. - void SetUpScopedFeatureList( - base::test::ScopedFeatureList& scoped_feature_list) override { - std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); - feature_list->InitFromCommandLine("GreaseUACH:updated_algorithm/false", ""); - scoped_feature_list.InitWithFeatureList(std::move(feature_list)); - } -}; - -// Checks that the updated GREASE algorithm is not used when explicitly -// disabled. -IN_PROC_BROWSER_TEST_F(GreaseFeatureParamOptOutTest, - UpdatedGreaseFeatureParamOptOutTest) { - const GURL gurl = accept_ch_url(); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), gurl)); - std::string ua_ch_result = main_frame_ua_observed(); - - ASSERT_TRUE(SawOldGrease(ua_ch_result)); -} - class XRClientHintsTest : public ClientHintsBrowserTest { // Enables ClientHintsXRFormFactor feature in addition to the default ones. void SetUpScopedFeatureList(
diff --git a/chrome/browser/collaboration/messaging/messaging_backend_service_factory.cc b/chrome/browser/collaboration/messaging/messaging_backend_service_factory.cc index 7580412a6..918131c 100644 --- a/chrome/browser/collaboration/messaging/messaging_backend_service_factory.cc +++ b/chrome/browser/collaboration/messaging/messaging_backend_service_factory.cc
@@ -19,6 +19,7 @@ #include "components/collaboration/internal/messaging/messaging_backend_service_impl.h" #include "components/collaboration/internal/messaging/storage/messaging_backend_store_impl.h" #include "components/collaboration/internal/messaging/tab_group_change_notifier_impl.h" +#include "components/collaboration/public/features.h" #include "components/data_sharing/public/features.h" #include "components/saved_tab_groups/public/features.h" #include "components/saved_tab_groups/public/tab_group_sync_service.h" @@ -62,7 +63,8 @@ // to be enabled. if (!base::FeatureList::IsEnabled( data_sharing::features::kDataSharingFeature) || - !tab_groups::IsTabGroupSyncEnabled(profile->GetPrefs())) { + !tab_groups::IsTabGroupSyncEnabled(profile->GetPrefs()) || + !base::FeatureList::IsEnabled(kCollaborationMessaging)) { return std::make_unique<EmptyMessagingBackendService>(); }
diff --git a/chrome/browser/component_updater/trust_token_key_commitments_component_installer.cc b/chrome/browser/component_updater/trust_token_key_commitments_component_installer.cc index 8d55739..55a39e2 100644 --- a/chrome/browser/component_updater/trust_token_key_commitments_component_installer.cc +++ b/chrome/browser/component_updater/trust_token_key_commitments_component_installer.cc
@@ -7,13 +7,11 @@ #include <memory> #include <string> -#include "base/feature_list.h" #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/logging.h" #include "components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy.h" #include "content/public/browser/network_service_instance.h" -#include "services/network/public/cpp/features.h" #include "services/network/public/mojom/network_service.mojom.h" using component_updater::ComponentUpdateService; @@ -22,11 +20,6 @@ void RegisterTrustTokenKeyCommitmentsComponentIfTrustTokensEnabled( ComponentUpdateService* cus) { - if (!base::FeatureList::IsEnabled(network::features::kPrivateStateTokens) && - !base::FeatureList::IsEnabled(network::features::kFledgePst)) { - return; - } - VLOG(1) << "Registering Trust Token Key Commitments component."; auto installer = base::MakeRefCounted<ComponentInstaller>( std::make_unique<TrustTokenKeyCommitmentsComponentInstallerPolicy>(
diff --git a/chrome/browser/component_updater/trust_token_key_commitments_component_installer_unittest.cc b/chrome/browser/component_updater/trust_token_key_commitments_component_installer_unittest.cc deleted file mode 100644 index 8a77e94..0000000 --- a/chrome/browser/component_updater/trust_token_key_commitments_component_installer_unittest.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/component_updater/trust_token_key_commitments_component_installer.h" - -#include "base/files/scoped_temp_dir.h" -#include "base/test/scoped_feature_list.h" -#include "base/test/task_environment.h" -#include "components/component_updater/mock_component_updater_service.h" -#include "services/network/public/cpp/features.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace component_updater { - -namespace { -using ::testing::_; -} // namespace - -class TrustTokenKeyCommitmentsComponentInstallerTest : public ::testing::Test { - public: - TrustTokenKeyCommitmentsComponentInstallerTest() = default; - - protected: - base::test::TaskEnvironment env_; -}; - -TEST_F(TrustTokenKeyCommitmentsComponentInstallerTest, FeatureDisabled) { - base::test::ScopedFeatureList scoped_list; - scoped_list.InitWithFeatures({}, {network::features::kPrivateStateTokens, - network::features::kFledgePst}); - auto service = - std::make_unique<component_updater::MockComponentUpdateService>(); - EXPECT_CALL(*service, RegisterComponent(_)).Times(0); - RegisterTrustTokenKeyCommitmentsComponentIfTrustTokensEnabled(service.get()); - - env_.RunUntilIdle(); -} - -} // namespace component_updater
diff --git a/chrome/browser/extensions/account_extension_tracker.cc b/chrome/browser/extensions/account_extension_tracker.cc index 7650b1ec..dc838b0 100644 --- a/chrome/browser/extensions/account_extension_tracker.cc +++ b/chrome/browser/extensions/account_extension_tracker.cc
@@ -110,13 +110,8 @@ void AccountExtensionTracker::SetAccountExtensionTypeOnExtensionInstalled( const Extension& extension) { - syncer::SyncService* sync_service = - SyncServiceFactory::GetForProfile(profile_); - bool extension_sync_enabled = - sync_service && sync_service->GetUserSettings()->GetSelectedTypes().Has( - syncer::UserSelectableType::kExtensions); - bool is_syncable_extension = - ExtensionSyncService::IsSyncableExtension(profile_, extension); + bool extension_sync_enabled = sync_util::IsSyncingExtensionsEnabled(profile_); + bool is_syncable_extension = sync_util::ShouldSync(profile_, &extension); // Set to `kAccountInstalledSignedIn` if this is a syncable extension (by // ExtensionSyncService) that was installed when a user is signed in and has
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 46531b0..8dd02bd2 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -392,8 +392,6 @@ (*s_allowlist) [::unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled] = settings_api::PrefType::kBoolean; - (*s_allowlist)[unified_consent::prefs::kPageContentCollectionEnabled] = - settings_api::PrefType::kBoolean; (*s_allowlist)[::commerce::kPriceEmailNotificationsEnabled] = settings_api::PrefType::kBoolean;
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc index a7b1526..d959142 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.cc +++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc
@@ -852,9 +852,7 @@ safe_browsing::RemoteHostInfo::ProtocolType protocol = safe_browsing::RemoteHostInfo::UNSPECIFIED; - if (base::FeatureList::IsEnabled( - safe_browsing::kExtensionTelemetryReportContactedHosts) && - url.SchemeIsHTTPOrHTTPS()) { + if (url.SchemeIsHTTPOrHTTPS()) { protocol = safe_browsing::RemoteHostInfo::HTTP_HTTPS; } else if (url.SchemeIsWSOrWSS()) { protocol = safe_browsing::RemoteHostInfo::WEBSOCKET;
diff --git a/chrome/browser/extensions/extension_sync_service.cc b/chrome/browser/extensions/extension_sync_service.cc index 6798b77..da7bacc 100644 --- a/chrome/browser/extensions/extension_sync_service.cc +++ b/chrome/browser/extensions/extension_sync_service.cc
@@ -137,17 +137,6 @@ return ExtensionSyncServiceFactory::GetForBrowserContext(context); } -// static -bool ExtensionSyncService::IsSyncableExtension( - content::BrowserContext* browser_context, - const Extension& extension) { - // Themes are handled by the ThemeSyncableService. - return extensions::sync_util::ShouldSync(browser_context, &extension) && - !extension.is_theme() && - !extensions::blocklist_prefs::IsExtensionBlocklisted( - extension.id(), ExtensionPrefs::Get(browser_context)); -} - void ExtensionSyncService::SyncExtensionChangeIfNeeded( const Extension& extension) { if (ignore_updates_ || !ShouldSync(extension)) { @@ -694,5 +683,11 @@ return false; } - return IsSyncableExtension(profile_, extension); + if (extension.is_theme()) { + // Themes are handled by the ThemeSyncableService. + return false; + } + + // Otherwise, defer to the general extension sync calculation. + return extensions::sync_util::ShouldSync(profile_, &extension); }
diff --git a/chrome/browser/extensions/extension_sync_service.h b/chrome/browser/extensions/extension_sync_service.h index d7dbd12..4cb14de 100644 --- a/chrome/browser/extensions/extension_sync_service.h +++ b/chrome/browser/extensions/extension_sync_service.h
@@ -51,12 +51,6 @@ // Convenience function to get the ExtensionSyncService for a BrowserContext. static ExtensionSyncService* Get(content::BrowserContext* context); - // Returns whether the given extension is eligible to be synced by this class. - // Filters out unsyncable extensions as well as themes (which are handled by - // ThemeSyncableService instead). - static bool IsSyncableExtension(content::BrowserContext* context, - const extensions::Extension& extension); - // Notifies Sync (if needed) of a newly-installed extension or a change to // an existing extension. Call this when you change an extension setting that // is synced as part of ExtensionSyncData (e.g. incognito_enabled). @@ -130,9 +124,7 @@ syncer::DataType type, std::vector<extensions::ExtensionSyncData>* sync_data_list) const; - // Returns if the given `extension` should be synced. This differs from - // `IsSyncableExtension` which checks if an extension is eligible to be synced - // by this class. + // Returns if the given `extension` should be synced by this class. bool ShouldSync(const extensions::Extension& extension) const; // The normal profile associated with this ExtensionSyncService.
diff --git a/chrome/browser/extensions/extension_sync_service_unittest.cc b/chrome/browser/extensions/extension_sync_service_unittest.cc index dadcd20a..9697bfb 100644 --- a/chrome/browser/extensions/extension_sync_service_unittest.cc +++ b/chrome/browser/extensions/extension_sync_service_unittest.cc
@@ -1913,9 +1913,11 @@ // Test that sync cannot enable blocklisted extensions. TEST_F(BlocklistedExtensionSyncServiceTest, SyncBlocklistedExtension) { - std::string& extension_id = this->extension_id(); + // The extension should be syncable before being blocklisted. + EXPECT_TRUE(extensions::sync_util::ShouldSync(profile(), extension())); // Blocklist the extension. + std::string& extension_id = this->extension_id(); test_blocklist().SetBlocklistState(extension_id, extensions::BLOCKLISTED_MALWARE, true); ForceBlocklistUpdate(); @@ -1926,6 +1928,9 @@ // The extension should not be enabled. EXPECT_FALSE(registry()->enabled_extensions().GetByID(extension_id)); EXPECT_TRUE(processor()->changes().empty()); + + // Double check that the extension is not syncable. + EXPECT_FALSE(extensions::sync_util::ShouldSync(profile(), extension())); } // Test that some greylisted extensions can be enabled through sync.
diff --git a/chrome/browser/extensions/extension_sync_util.cc b/chrome/browser/extensions/extension_sync_util.cc index 995ed0d2..7544667 100644 --- a/chrome/browser/extensions/extension_sync_util.cc +++ b/chrome/browser/extensions/extension_sync_util.cc
@@ -14,6 +14,7 @@ #include "components/sync/base/features.h" #include "components/sync/service/sync_service.h" #include "components/sync/service/sync_user_settings.h" +#include "extensions/browser/blocklist_extension_prefs.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/pref_names.h" #include "extensions/common/extension.h" @@ -35,7 +36,9 @@ return false; } return sync_helper::IsSyncable(extension) && - !ExtensionPrefs::Get(context)->DoNotSync(extension->id()); + !ExtensionPrefs::Get(context)->DoNotSync(extension->id()) && + !extensions::blocklist_prefs::IsExtensionBlocklisted( + extension->id(), ExtensionPrefs::Get(context)); } bool IsSyncingExtensionsEnabled(Profile* profile) {
diff --git a/chrome/browser/extensions/orb_and_cors_extension_browsertest.cc b/chrome/browser/extensions/orb_and_cors_extension_browsertest.cc index 9edbcfe..4efbee77 100644 --- a/chrome/browser/extensions/orb_and_cors_extension_browsertest.cc +++ b/chrome/browser/extensions/orb_and_cors_extension_browsertest.cc
@@ -1268,21 +1268,10 @@ // // (Specifically, this makes sure RFHI is passing the correct factory // parameter to URLLoaderFactoryParamsHelper::CreateForIsolatedWorld.) -class TrustTokenExtensionBrowserTest : public OrbAndCorsExtensionBrowserTest { - public: - TrustTokenExtensionBrowserTest() { - scoped_feature_list_.InitAndEnableFeature( - network::features::kPrivateStateTokens); - } - - protected: - base::test::ScopedFeatureList scoped_feature_list_; -}; - // TODO(crbug.com/40221677): Have trust tokens handle the existence, or not, of // PrivacySandboxSettings3. IN_PROC_BROWSER_TEST_F( - TrustTokenExtensionBrowserTest, + OrbAndCorsExtensionBrowserTest, DISABLED_FromProgrammaticContentScript_TrustTokenRedemptionAllowed) { // Trust Tokens operations only work on secure origins - set up a https test // server to help with this. One alternative would be using a localhost URL
diff --git a/chrome/browser/extensions/user_script_world_configuration_manager_unittest.cc b/chrome/browser/extensions/user_script_world_configuration_manager_unittest.cc index 5bb189f..7b03fe5 100644 --- a/chrome/browser/extensions/user_script_world_configuration_manager_unittest.cc +++ b/chrome/browser/extensions/user_script_world_configuration_manager_unittest.cc
@@ -88,9 +88,13 @@ // Register two different configurations for user script worlds, one for the // default world and another for "world 1". configuration_manager()->SetUserScriptWorldInfo( - *extension, std::nullopt, "script-src: self", /*enable_messaging=*/false); + *extension, mojom::UserScriptWorldInfo::New(extension->id(), std::nullopt, + "script-src: self", + /*enable_messaging=*/false)); configuration_manager()->SetUserScriptWorldInfo( - *extension, "world 1", "script-src: none", /*enable_messaging=*/false); + *extension, mojom::UserScriptWorldInfo::New(extension->id(), "world 1", + "script-src: none", + /*enable_messaging=*/false)); EXPECT_EQ( 2u, configuration_manager()->GetAllUserScriptWorlds(extension->id()).size()); @@ -119,15 +123,21 @@ // Set configurations for a specified world and the default world for each // extension. - configuration_manager()->SetUserScriptWorldInfo(*extension1, default_world, - csp1, kEnableMessaging); - configuration_manager()->SetUserScriptWorldInfo(*extension1, other_world, - csp2, kEnableMessaging); + configuration_manager()->SetUserScriptWorldInfo( + *extension1, + mojom::UserScriptWorldInfo::New(extension1->id(), default_world, csp1, + kEnableMessaging)); + configuration_manager()->SetUserScriptWorldInfo( + *extension1, mojom::UserScriptWorldInfo::New( + extension1->id(), other_world, csp2, kEnableMessaging)); - configuration_manager()->SetUserScriptWorldInfo(*extension2, default_world, - csp1, kEnableMessaging); - configuration_manager()->SetUserScriptWorldInfo(*extension2, other_world, - csp2, kEnableMessaging); + configuration_manager()->SetUserScriptWorldInfo( + *extension2, + mojom::UserScriptWorldInfo::New(extension2->id(), default_world, csp1, + kEnableMessaging)); + configuration_manager()->SetUserScriptWorldInfo( + *extension2, mojom::UserScriptWorldInfo::New( + extension2->id(), other_world, csp2, kEnableMessaging)); // Verify initial state. Each extension should have those two worlds // configured.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index dc204a3..b4bd4d6 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -4478,6 +4478,11 @@ "expiry_milestone": 135 }, { + "name": "fedcm-delegation", + "owners": [ "goto@chromium.org", "web-identity-eng@google.com"], + "expiry_milestone": 135 + }, + { "name": "fedcm-idp-registration", "owners": [ "goto@chromium.org", "web-identity-eng@google.com"], "expiry_milestone": 135 @@ -7041,14 +7046,6 @@ "expiry_milestone": 130 }, { - "name": "price-tracking-icon-colors", - "owners": [ - "mdjones@chromium.org", - "chrome-shopping-eng@google.com" - ], - "expiry_milestone": 128 - }, - { "name": "price-tracking-subscription-service-locale-key", "owners": [ "qib@google.com", "chrommerce-eng@google.com" ], "expiry_milestone": 135 @@ -7241,6 +7238,11 @@ "expiry_milestone": 136 }, { + "name": "projector-use-dvs-playback-endpoint", + "owners": ["bzielinski@google.com", "cros-projector@google.com"], + "expiry_milestone": 140 + }, + { "name": "promise-icons", "owners": ["vpao@chromium.org", "chromeos-apps-foundation-team@google.com"], "expiry_milestone": 130 @@ -8015,11 +8017,6 @@ "expiry_milestone": 140 }, { - "name": "shopping-icon-color-variant", - "owners": [ "chrome-desktop-ui-sea@google.com" ], - "expiry_milestone": 126 - }, - { "name": "shopping-list", "owners": [ "mdjones@chromium.org", "chrome-shopping-eng@google.com" ], "expiry_milestone": 122
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 81ee7e7b..af3d197 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1941,6 +1941,10 @@ "Enables RPs specify whether they want to trigger the FedCM widget flow or " "the button flow."; +const char kFedCmDelegationName[] = "FedCM with delegation support"; +const char kFedCmDelegationDescription[] = + "Enables IdPs to delegate presentation to the browser."; + const char kFedCmIdPRegistrationName[] = "FedCM with IdP Registration support"; const char kFedCmIdPRegistrationDescription[] = "Enables RPs to get identity credentials from registered IdPs."; @@ -6936,13 +6940,6 @@ const char kCrosComponentsDescription[] = "Enable cros-component UI elements, replacing other elements."; -const char kLacrosAvailabilityIgnoreName[] = - "Ignore lacros-availability policy"; -const char kLacrosAvailabilityIgnoreDescription[] = - "Makes the lacros-availability policy have no effect on Google-internal " - "accounts. Instead, Lacros availability will be controlled by experiment " - "and/or user flags for such accounts."; - const char kLacrosStabilityName[] = "Lacros stability"; const char kLacrosStabilityDescription[] = "Lacros update channel."; @@ -7178,6 +7175,12 @@ "Allows Screencast to use the latest model for server side speech " "recognition."; +const char kProjectorUseDVSPlaybackEndpointName[] = + "Use DVS endpoint in the Screencast app"; +const char kProjectorUseDVSPlaybackEndpointDescription[] = + "Use the latest endpoint for retrieving playback urls in the Screencast " + "app."; + const char kReleaseNotesNotificationAllChannelsName[] = "Release Notes Notification All Channels"; const char kReleaseNotesNotificationAllChannelsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 6a9aa31..7d5d9b3 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1097,6 +1097,9 @@ extern const char kFedCmButtonModeName[]; extern const char kFedCmButtonModeDescription[]; +extern const char kFedCmDelegationName[]; +extern const char kFedCmDelegationDescription[]; + extern const char kFedCmIdPRegistrationName[]; extern const char kFedCmIdPRegistrationDescription[]; @@ -4037,9 +4040,6 @@ extern const char kCrosComponentsName[]; extern const char kCrosComponentsDescription[]; -extern const char kLacrosAvailabilityIgnoreName[]; -extern const char kLacrosAvailabilityIgnoreDescription[]; - extern const char kLacrosStabilityName[]; extern const char kLacrosStabilityDescription[]; @@ -4172,6 +4172,9 @@ extern const char kProjectorServerSideUsmName[]; extern const char kProjectorServerSideUsmDescription[]; +extern const char kProjectorUseDVSPlaybackEndpointName[]; +extern const char kProjectorUseDVSPlaybackEndpointDescription[]; + extern const char kReleaseNotesNotificationAllChannelsName[]; extern const char kReleaseNotesNotificationAllChannelsDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 02bd697..ed0ee3f 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -410,7 +410,6 @@ &tab_groups::kUseAlternateHistorySyncIllustration, &visited_url_ranking::features::kVisitedURLRankingService, &webapps::features::kWebApkInstallFailureNotification, - &network::features::kPrivateStateTokens, &base::features::kPostGetMyMemoryStateToBackground, }; @@ -838,7 +837,7 @@ BASE_FEATURE(kNewTabPageAndroidTriggerForPrerender2, "NewTabPageAndroidTriggerForPrerender2", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kNotificationPermissionVariant, "NotificationPermissionVariant",
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 e818aa6..9db11f2 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
@@ -441,7 +441,6 @@ public static final String PRIVACY_SANDBOX_PRIVACY_GUIDE_AD_TOPICS = "PrivacySandboxPrivacyGuideAdTopics"; public static final String PRIVACY_SANDBOX_PRIVACY_POLICY = "PrivacySandboxPrivacyPolicy"; - public static final String PRIVATE_STATE_TOKENS = "PrivateStateTokens"; public static final String PUSH_MESSAGING_DISALLOW_SENDER_IDS = "PushMessagingDisallowSenderIDs"; public static final String PWA_UPDATE_DIALOG_FOR_ICON = "PwaUpdateDialogForIcon"; @@ -696,7 +695,7 @@ public static final CachedFlag sNavBarColorMatchesTabBackground = newCachedFlag(NAV_BAR_COLOR_MATCHES_TAB_BACKGROUND, true); public static final CachedFlag sNewTabPageAndroidTriggerForPrerender2 = - newCachedFlag(NEW_TAB_PAGE_ANDROID_TRIGGER_FOR_PRERENDER2, false); + newCachedFlag(NEW_TAB_PAGE_ANDROID_TRIGGER_FOR_PRERENDER2, true); public static final CachedFlag sNotificationTrampoline = newCachedFlag(NOTIFICATION_TRAMPOLINE, false); public static final CachedFlag sPowerSavingModeBroadcastReceiverInBackground =
diff --git a/chrome/browser/glic/glic_keyed_service.cc b/chrome/browser/glic/glic_keyed_service.cc index ea81166..b6e22ecc 100644 --- a/chrome/browser/glic/glic_keyed_service.cc +++ b/chrome/browser/glic/glic_keyed_service.cc
@@ -76,6 +76,14 @@ return window_controller_->GetSize(); } +void GlicKeyedService::SetPanelDraggableAreas( + const std::vector<gfx::Rect>& draggable_areas) { + if (!window_controller_) { + return; + } + window_controller_->SetDraggableAreas(draggable_areas); +} + void GlicKeyedService::GetContextFromFocusedTab( bool include_inner_text, bool include_viewport_screenshot,
diff --git a/chrome/browser/glic/glic_keyed_service.h b/chrome/browser/glic/glic_keyed_service.h index 2ee3ac5..fdb8603 100644 --- a/chrome/browser/glic/glic_keyed_service.h +++ b/chrome/browser/glic/glic_keyed_service.h
@@ -43,6 +43,7 @@ glic::mojom::WebClientHandler::CreateTabCallback callback); virtual void ClosePanel(); std::optional<gfx::Size> ResizePanel(const gfx::Size& size); + void SetPanelDraggableAreas(const std::vector<gfx::Rect>& draggable_areas); void GetContextFromFocusedTab( bool include_inner_text,
diff --git a/chrome/browser/glic/glic_window_controller.cc b/chrome/browser/glic/glic_window_controller.cc index 91c1aaf..9aed5961 100644 --- a/chrome/browser/glic/glic_window_controller.cc +++ b/chrome/browser/glic/glic_window_controller.cc
@@ -23,6 +23,7 @@ constexpr static int kSnapDistanceThreshold = 50; constexpr static int kWidgetWidth = 400; constexpr static int kWidgetHeight = 800; +constexpr static int kWidgetTopBarHeight = 80; // Helper class for observing mouse and key events from native window. class WindowEventObserver : public ui::EventObserver { @@ -33,7 +34,8 @@ : glic_window_controller_(glic_window_controller), glic_view_(glic_view) { event_monitor_ = views::EventMonitor::CreateWindowMonitor( this, glic_view->GetWidget()->GetNativeWindow(), - {ui::EventType::kMouseDragged}); + {ui::EventType::kMousePressed, ui::EventType::kMouseReleased, + ui::EventType::kMouseDragged}); } WindowEventObserver(const WindowEventObserver&) = delete; @@ -41,19 +43,37 @@ ~WindowEventObserver() override = default; void OnEvent(const ui::Event& event) override { - if (event.IsMouseEvent()) { - if (event.type() == ui::EventType::kMouseDragged) { - gfx::Point mouse_location = event_monitor_->GetLastMouseLocation(); - views::View::ConvertPointFromScreen(glic_view_, &mouse_location); - glic_window_controller_->DragFromPoint( - mouse_location.OffsetFromOrigin()); - } + if (!event.IsMouseEvent()) { + return; + } + + gfx::Point mouse_location = event_monitor_->GetLastMouseLocation(); + views::View::ConvertPointFromScreen(glic_view_, &mouse_location); + if (event.type() == ui::EventType::kMousePressed && + glic_view_->IsPointWithinDraggableArea(mouse_location)) { + mouse_down_in_draggable_area_ = true; + } + + if (event.type() == ui::EventType::kMouseReleased || + event.type() == ui::EventType::kMouseExited) { + mouse_down_in_draggable_area_ = false; + } + + // Window should only be dragged if a corresponding mouse drag event was + // initiated in the draggable area. + if (mouse_down_in_draggable_area_ && + event.type() == ui::EventType::kMouseDragged) { + glic_window_controller_->DragFromPoint(mouse_location.OffsetFromOrigin()); } } raw_ptr<glic::GlicWindowController> glic_window_controller_; raw_ptr<glic::GlicView> glic_view_; std::unique_ptr<views::EventMonitor> event_monitor_; + + // Tracks whether the mouse is pressed and was initially within a draggable + // area of the window. + bool mouse_down_in_draggable_area_; }; } // namespace @@ -64,7 +84,8 @@ : profile_(profile) {} void GlicWindowController::Show(views::View* glic_button_view) { - // TODO(crbug.com/379943498): possibly bring to front or activate in this case + // TODO(crbug.com/379943498): If a glic window already exists, handle showing + // by bringing to front or activating. if (widget_) { return; } @@ -93,6 +114,8 @@ widget_->Show(); window_event_observer_ = std::make_unique<WindowEventObserver>(this, glic_view_); + // Set the draggable area to the top bar of the window, by default. + glic_view_->SetDraggableAreas({{0, 0, kWidgetWidth, kWidgetTopBarHeight}}); } gfx::Point GlicWindowController::GetTopRightPositionForAttachedWindow( @@ -145,6 +168,15 @@ return widget_->GetSize(); } +void GlicWindowController::SetDraggableAreas( + const std::vector<gfx::Rect>& draggable_areas) { + if (!glic_view_) { + return; + } + + glic_view_->SetDraggableAreas(draggable_areas); +} + void GlicWindowController::Close() { if (!widget_) { return; @@ -177,11 +209,11 @@ for (Browser* browser : BrowserList::GetInstance()->OrderedByActivation()) { views::Widget* window_widget = browser->window()->AsBrowserView()->GetWidget(); - // Skips if: - // - incognito - // - not visible - // - is the same widget as glic - // - is a different profile (uses browser context to check) + // Skips if the browser: + // - is incognito + // - is not visible + // - uses the same widget as glic + // - uses a different profile from glic if (browser->profile()->IsOffTheRecord() || !browser->window()->IsVisible() || window_widget == widget_.get() || browser->GetWebView()->GetBrowserContext() != @@ -222,7 +254,7 @@ return; } gfx::Rect glic_rect = widget_->GetWindowBoundsInScreen(); - // TODO fix exact snap location + // TODO(andreaxg): Fix exact snap location. gfx::Rect glic_button_rect = browser->window() ->AsBrowserView() ->tab_strip_region_view() @@ -244,7 +276,7 @@ views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); params.activatable = views::Widget::InitParams::Activatable::kNo; params.accept_events = false; - // Name specified for debug purposes + // Widget name is specified for debug purposes. params.name = "HolderWindow"; params.bounds = gfx::Rect(0, 0, 0, 0); params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
diff --git a/chrome/browser/glic/glic_window_controller.h b/chrome/browser/glic/glic_window_controller.h index 64885a4..2c4fa1e 100644 --- a/chrome/browser/glic/glic_window_controller.h +++ b/chrome/browser/glic/glic_window_controller.h
@@ -43,10 +43,13 @@ // Returns the current size of the glic window. gfx::Size GetSize(); + // Sets the areas of the view from which it should be draggable. + void SetDraggableAreas(const std::vector<gfx::Rect>& draggable_areas); + // Called to notify the controller that the window was requested to be closed. void Close(); - // User drags glic window + // Drags the glic window following the current mouse location. void DragFromPoint(gfx::Vector2d mouse_location); // Returns a WeakPtr to this instance. It can be destroyed at any time if the @@ -77,7 +80,6 @@ delete; ~PinnedTargetWidgetObserver() override; void SetPinnedTargetWidget(views::Widget* widget); - void OnWidgetBoundsChanged(views::Widget* widget, const gfx::Rect& new_bounds) override; void OnWidgetDestroying(views::Widget* widget) override; @@ -94,8 +96,8 @@ // glic to the top right of the browser's glic button. void HandleBrowserPinning(gfx::Vector2d mouse_location); - // When glic is unpinned, reparent to empty holder widget. Initializes the - // empty holder widget if it hasn't been created yet.g + // When glic is unpinned, reparent it to an empty holder Widget. Initializes + // the empty holder widget if it hasn't been created yet. void MaybeCreateHolderWindowAndReparent(); // Moves glic view to the pin target of the specified browser.
diff --git a/chrome/browser/glic/launcher/glic_status_icon.cc b/chrome/browser/glic/launcher/glic_status_icon.cc index cde9cbe..bb0f792 100644 --- a/chrome/browser/glic/launcher/glic_status_icon.cc +++ b/chrome/browser/glic/launcher/glic_status_icon.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/status_icons/status_icon_menu_model.h" #include "chrome/browser/status_icons/status_tray.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/common/chrome_features.h" #include "chrome/grit/generated_resources.h" #include "components/user_education/common/help_bubble/help_bubble_params.h" #include "glic_status_icon.h" @@ -30,6 +31,11 @@ status_icon_ = status_tray_->CreateStatusIcon( StatusTray::GLIC_ICON, status_tray_icon, l10n_util::GetStringUTF16(IDS_GLIC_STATUS_ICON_TOOLTIP)); +#if BUILDFLAG(IS_MAC) + if (features::kGlicStatusIconOpenMenuWithSecondaryClick.Get()) { + status_icon_->SetOpenMenuWithSecondaryClick(true); + } +#endif status_icon_->AddObserver(this); std::unique_ptr<StatusIconMenuModel> menu = CreateStatusIconMenu();
diff --git a/chrome/browser/k_anonymity_service/k_anonymity_service_client_browsertest.cc b/chrome/browser/k_anonymity_service/k_anonymity_service_client_browsertest.cc index d24de94..31ce81c 100644 --- a/chrome/browser/k_anonymity_service/k_anonymity_service_client_browsertest.cc +++ b/chrome/browser/k_anonymity_service/k_anonymity_service_client_browsertest.cc
@@ -81,8 +81,7 @@ GURL ohttp_relay = https_server_->GetURL("/ohttpRelay"); feature_list_.InitWithFeaturesAndParameters( - /*enabled_features=*/{{network::features::kPrivateStateTokens, {}}, - {features::kKAnonymityService, + /*enabled_features=*/{{features::kKAnonymityService, {{"KAnonymityServiceAuthServer", https_server_->base_url().spec()}, {"KAnonymityServiceJoinServer",
diff --git a/chrome/browser/k_anonymity_service/k_anonymity_service_client_unittest.cc b/chrome/browser/k_anonymity_service/k_anonymity_service_client_unittest.cc index 28c43d3a..ee95229 100644 --- a/chrome/browser/k_anonymity_service/k_anonymity_service_client_unittest.cc +++ b/chrome/browser/k_anonymity_service/k_anonymity_service_client_unittest.cc
@@ -49,7 +49,7 @@ protected: void SetUp() override { feature_list_.InitWithFeatures( - /*enabled_features=*/{network::features::kPrivateStateTokens}, + {}, /*disabled_features=*/{features::kKAnonymityServiceOHTTPRequests}); TestingProfile::Builder builder; builder.SetSharedURLLoaderFactory( @@ -521,8 +521,7 @@ protected: void SetUp() override { feature_list_.InitWithFeaturesAndParameters( - {{network::features::kPrivateStateTokens, {}}, - {features::kKAnonymityService, + {{features::kKAnonymityService, { {"KAnonymityServiceJoinRelayServer", kJoinRelayURL}, {"KAnonymityServiceQueryRelayServer", kQueryRelayURL},
diff --git a/chrome/browser/k_anonymity_service/k_anonymity_trust_token_getter.cc b/chrome/browser/k_anonymity_service/k_anonymity_trust_token_getter.cc index 17d808e..6938b75 100644 --- a/chrome/browser/k_anonymity_service/k_anonymity_trust_token_getter.cc +++ b/chrome/browser/k_anonymity_service/k_anonymity_trust_token_getter.cc
@@ -20,7 +20,6 @@ #include "mojo/public/cpp/bindings/callback_helpers.h" #include "net/base/load_flags.h" #include "net/traffic_annotation/network_traffic_annotation.h" -#include "services/network/public/cpp/features.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/simple_url_loader.h" @@ -120,14 +119,11 @@ void KAnonymityTrustTokenGetter::TryGetTrustTokenAndKey( TryGetTrustTokenAndKeyCallback callback) { - if ((!base::FeatureList::IsEnabled(network::features::kPrivateStateTokens) && - !base::FeatureList::IsEnabled(network::features::kFledgePst)) || - !identity_manager_ || + if (!identity_manager_ || !identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSignin)) { std::move(callback).Run(std::nullopt); return; } - RecordTrustTokenGetterAction( KAnonymityTrustTokenGetterAction::kTryGetTrustTokenAndKey); bool currently_fetching = pending_callbacks_.size() > 0;
diff --git a/chrome/browser/k_anonymity_service/k_anonymity_trust_token_getter_unittest.cc b/chrome/browser/k_anonymity_service/k_anonymity_trust_token_getter_unittest.cc index efec5fd..1e904958 100644 --- a/chrome/browser/k_anonymity_service/k_anonymity_trust_token_getter_unittest.cc +++ b/chrome/browser/k_anonymity_service/k_anonymity_trust_token_getter_unittest.cc
@@ -66,8 +66,7 @@ protected: void SetUp() override { feature_list_.InitWithFeaturesAndParameters( - /*enabled_features=*/{{network::features::kPrivateStateTokens, {}}, - {features::kKAnonymityService, + /*enabled_features=*/{{features::kKAnonymityService, {{"KAnonymityServiceAuthServer", kAuthServer}}}}, /*disabled_features=*/{}); TestingProfile::Builder builder;
diff --git a/chrome/browser/media/audio_ducker.cc b/chrome/browser/media/audio_ducker.cc new file mode 100644 index 0000000..0f2570b --- /dev/null +++ b/chrome/browser/media/audio_ducker.cc
@@ -0,0 +1,80 @@ +// 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/media/audio_ducker.h" + +#include "content/public/browser/media_session.h" +#include "content/public/browser/media_session_service.h" + +AudioDucker::AudioDucker(content::Page& page) + : content::PageUserData<AudioDucker>(page), + content::WebContentsObserver(GetWebContents()) {} + +AudioDucker::~AudioDucker() { + StopDuckingOtherAudio(); +} + +bool AudioDucker::StartDuckingOtherAudio() { + if (ducking_state_ == AudioDuckingState::kDucking) { + return true; + } + if (!BindToAudioFocusManagerIfNecessary()) { + return false; + } + StartDuckingImpl(); + ducking_state_ = AudioDuckingState::kDucking; + return true; +} + +bool AudioDucker::StopDuckingOtherAudio() { + if (ducking_state_ == AudioDuckingState::kNoDucking) { + return true; + } + if (!BindToAudioFocusManagerIfNecessary()) { + return false; + } + audio_focus_remote_->StopDuckingAllAudio(); + ducking_state_ = AudioDuckingState::kNoDucking; + return true; +} + +void AudioDucker::MediaSessionCreated(content::MediaSession*) { + // When a MediaSession is created and we're already ducking, we need to tell + // the AudioFocusManager to start ducking again while exempting the new + // request ID. This will supercede the previous request and replace it with a + // request that has an exempted MediaSession. + if (ducking_state_ == AudioDuckingState::kDucking && + BindToAudioFocusManagerIfNecessary()) { + StartDuckingImpl(); + } +} + +void AudioDucker::StartDuckingImpl() { + // Null base::UnguessableTokens cannot be passed via mojo, so convert to an + // empty optional if the request ID is null. + const base::UnguessableToken& request_id = + content::MediaSession::GetRequestIdFromWebContents(GetWebContents()); + std::optional<base::UnguessableToken> optional_request_id; + if (!request_id.is_empty()) { + optional_request_id = request_id; + } + + audio_focus_remote_->StartDuckingAllAudio(optional_request_id); +} + +content::WebContents* AudioDucker::GetWebContents() const { + return content::WebContents::FromRenderFrameHost(&page().GetMainDocument()); +} + +bool AudioDucker::BindToAudioFocusManagerIfNecessary() { + if (audio_focus_remote_.is_bound()) { + return true; + } + content::GetMediaSessionService().BindAudioFocusManager( + audio_focus_remote_.BindNewPipeAndPassReceiver()); + audio_focus_remote_.reset_on_disconnect(); + return audio_focus_remote_.is_bound(); +} + +PAGE_USER_DATA_KEY_IMPL(AudioDucker);
diff --git a/chrome/browser/media/audio_ducker.h b/chrome/browser/media/audio_ducker.h new file mode 100644 index 0000000..c1dad0a --- /dev/null +++ b/chrome/browser/media/audio_ducker.h
@@ -0,0 +1,66 @@ +// 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_MEDIA_AUDIO_DUCKER_H_ +#define CHROME_BROWSER_MEDIA_AUDIO_DUCKER_H_ + +#include "content/public/browser/page_user_data.h" +#include "content/public/browser/web_contents_observer.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "services/media_session/public/mojom/audio_focus.mojom.h" + +// The AudioDucker ducks other audio in Chrome besides what is playing through +// its associated Page's WebContents. +// +// TODO(https://crbug.com/382316461): This should also duck audio from +// applications other than Chrome. +class AudioDucker : public content::PageUserData<AudioDucker>, + public content::WebContentsObserver { + public: + enum class AudioDuckingState { + // The AudioDucker is not currently ducking other audio. + kNoDucking, + + // The AudioDucker is currently ducking other audio. + kDucking, + }; + + AudioDucker(const AudioDucker&) = delete; + AudioDucker& operator=(const AudioDucker&) = delete; + ~AudioDucker() override; + + // Ducks all audio in Chrome except audio playback in our associated Page's + // WebContents. Returns true if ducking was started successfully or if we're + // already ducking. + bool StartDuckingOtherAudio(); + + // Stops ducking started by `StartDuckingOtherAudio()`. Does nothing if we're + // not currently ducking. Returns true if ducking was stopped successfully or + // if we're not currently ducking. + bool StopDuckingOtherAudio(); + + AudioDuckingState GetAudioDuckingState() const { return ducking_state_; } + + private: + explicit AudioDucker(content::Page& page); + + friend PageUserData; + PAGE_USER_DATA_KEY_DECL(); + + // content::WebContentsObserver: + void MediaSessionCreated(content::MediaSession*) override; + + void StartDuckingImpl(); + + content::WebContents* GetWebContents() const; + + // Binds |audio_focus_remote_| if it's not already bound. Returns true if + // |audio_focus_remote_| is already bound or has become bound. + bool BindToAudioFocusManagerIfNecessary(); + + AudioDuckingState ducking_state_ = AudioDuckingState::kNoDucking; + mojo::Remote<media_session::mojom::AudioFocusManager> audio_focus_remote_; +}; + +#endif // CHROME_BROWSER_MEDIA_AUDIO_DUCKER_H_
diff --git a/chrome/browser/media/audio_ducker_browsertest.cc b/chrome/browser/media/audio_ducker_browsertest.cc new file mode 100644 index 0000000..d71d7bcb --- /dev/null +++ b/chrome/browser/media/audio_ducker_browsertest.cc
@@ -0,0 +1,244 @@ +// 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/media/audio_ducker.h" + +#include "base/functional/bind.h" +#include "base/run_loop.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/media_session.h" +#include "content/public/browser/media_session_service.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "services/media_session/public/cpp/test/audio_focus_test_util.h" + +namespace { + +constexpr base::FilePath::CharType kTestPage[] = + FILE_PATH_LITERAL("media/bigbuck-player.html"); + +constexpr base::FilePath::CharType kTestPageStartWithNoPlayer[] = + FILE_PATH_LITERAL("media/start-with-no-player.html"); + +} // namespace + +using media_session::mojom::MediaSessionInfo; + +class AudioDuckerBrowserTest : public InProcessBrowserTest { + public: + AudioDuckerBrowserTest() = default; + AudioDuckerBrowserTest(const AudioDuckerBrowserTest&) = delete; + AudioDuckerBrowserTest& operator=(const AudioDuckerBrowserTest&) = delete; + ~AudioDuckerBrowserTest() override = default; + + void SetUpOnMainThread() override { + ResetAudioFocusObserver(); + + host_resolver()->AddRule("*", "127.0.0.1"); + embedded_test_server()->ServeFilesFromSourceDirectory("chrome/test/data"); + ASSERT_TRUE(embedded_test_server()->Start()); + } + + void AddVideo(content::WebContents& web_contents) { + web_contents.GetPrimaryMainFrame() + ->ExecuteJavaScriptWithUserGestureForTests( + u"addVideo();", base::NullCallback(), + content::ISOLATED_WORLD_ID_GLOBAL); + } + + void PlayVideoAndWaitForAudioFocus(content::WebContents& web_contents) { + ResetAudioFocusObserver(); + web_contents.GetPrimaryMainFrame() + ->ExecuteJavaScriptWithUserGestureForTests( + u"document.getElementsByTagName('video')[0].play()", + base::NullCallback(), content::ISOLATED_WORLD_ID_GLOBAL); + WaitForAudioFocusGained(); + } + + void ResetAudioFocusObserver() { + mojo::Remote<media_session::mojom::AudioFocusManager> audio_focus_remote; + content::GetMediaSessionService().BindAudioFocusManager( + audio_focus_remote.BindNewPipeAndPassReceiver()); + audio_focus_observer_ = + std::make_unique<media_session::test::TestAudioFocusObserver>(); + audio_focus_remote->AddObserver( + audio_focus_observer_->BindNewPipeAndPassRemote()); + } + + void WaitForAudioFocusGained() { + audio_focus_observer_->WaitForGainedEvent(); + } + + void FlushAudioFocusManager() { + mojo::Remote<media_session::mojom::AudioFocusManager> audio_focus_remote; + content::GetMediaSessionService().BindAudioFocusManager( + audio_focus_remote.BindNewPipeAndPassReceiver()); + + base::RunLoop flush_waiter; + audio_focus_remote->FlushForTesting(flush_waiter.QuitClosure()); + flush_waiter.Run(); + } + + void ExpectMediaSessionState(content::MediaSession& media_session, + MediaSessionInfo::SessionState expected_state) { + base::RunLoop waiter; + media_session.GetMediaSessionInfo(base::BindOnce( + [](MediaSessionInfo::SessionState expected_state, + base::OnceClosure wait_closure, + media_session::mojom::MediaSessionInfoPtr info) { + EXPECT_EQ(info->state, expected_state); + std::move(wait_closure).Run(); + }, + expected_state, waiter.QuitClosure())); + waiter.Run(); + } + + private: + std::unique_ptr<media_session::test::TestAudioFocusObserver> + audio_focus_observer_; +}; + +IN_PROC_BROWSER_TEST_F(AudioDuckerBrowserTest, + DucksAudioInOtherTabs_MediaPlaying) { + GURL test_page_url = ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath(kTestPage)); + + // Open a test page and start playing a video. + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url)); + content::WebContents* web_contents1 = + browser()->tab_strip_model()->GetActiveWebContents(); + PlayVideoAndWaitForAudioFocus(*web_contents1); + + // Open a second test page and also play a video. + ASSERT_TRUE(ui_test_utils::NavigateToURLWithDisposition( + browser(), test_page_url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP)); + content::WebContents* web_contents2 = + browser()->tab_strip_model()->GetActiveWebContents(); + PlayVideoAndWaitForAudioFocus(*web_contents2); + + content::MediaSession* media_session1 = + content::MediaSession::GetIfExists(web_contents1); + content::MediaSession* media_session2 = + content::MediaSession::GetIfExists(web_contents2); + ASSERT_TRUE(media_session1); + ASSERT_TRUE(media_session2); + + AudioDucker* audio_ducker = + AudioDucker::GetOrCreateForPage(web_contents2->GetPrimaryPage()); + + // Neither page should be ducked. + ExpectMediaSessionState(*media_session1, + MediaSessionInfo::SessionState::kActive); + ExpectMediaSessionState(*media_session2, + MediaSessionInfo::SessionState::kActive); + EXPECT_EQ(AudioDucker::AudioDuckingState::kNoDucking, + audio_ducker->GetAudioDuckingState()); + + // Tell the AudioDucker associated with the second page to duck other audio. + EXPECT_TRUE(audio_ducker->StartDuckingOtherAudio()); + FlushAudioFocusManager(); + + // The first page should be ducked while the second remains unducked. + ExpectMediaSessionState(*media_session1, + MediaSessionInfo::SessionState::kDucking); + ExpectMediaSessionState(*media_session2, + MediaSessionInfo::SessionState::kActive); + EXPECT_EQ(AudioDucker::AudioDuckingState::kDucking, + audio_ducker->GetAudioDuckingState()); + + // Tell the AudioDucker to stop ducking. + EXPECT_TRUE(audio_ducker->StopDuckingOtherAudio()); + FlushAudioFocusManager(); + + // Neither page should be ducked. + ExpectMediaSessionState(*media_session1, + MediaSessionInfo::SessionState::kActive); + ExpectMediaSessionState(*media_session2, + MediaSessionInfo::SessionState::kActive); + EXPECT_EQ(AudioDucker::AudioDuckingState::kNoDucking, + audio_ducker->GetAudioDuckingState()); +} + +IN_PROC_BROWSER_TEST_F(AudioDuckerBrowserTest, + DucksAudioInOtherTabs_NoMediaPlaying) { + GURL test_page_url = ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath(kTestPage)); + + // Open a test page and start playing a video. + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url)); + content::WebContents* web_contents1 = + browser()->tab_strip_model()->GetActiveWebContents(); + PlayVideoAndWaitForAudioFocus(*web_contents1); + + // Open a second test page that has no video. + GURL test_page_no_player_url = ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath(kTestPageStartWithNoPlayer)); + + ASSERT_TRUE(ui_test_utils::NavigateToURLWithDisposition( + browser(), test_page_no_player_url, + WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP)); + content::WebContents* web_contents2 = + browser()->tab_strip_model()->GetActiveWebContents(); + + content::MediaSession* media_session1 = + content::MediaSession::GetIfExists(web_contents1); + ASSERT_TRUE(media_session1); + ASSERT_EQ(nullptr, content::MediaSession::GetIfExists(web_contents2)); + + AudioDucker* audio_ducker = + AudioDucker::GetOrCreateForPage(web_contents2->GetPrimaryPage()); + + // The first page should not be ducked. + ExpectMediaSessionState(*media_session1, + MediaSessionInfo::SessionState::kActive); + EXPECT_EQ(AudioDucker::AudioDuckingState::kNoDucking, + audio_ducker->GetAudioDuckingState()); + + // Tell the AudioDucker associated with the second page to duck other audio. + EXPECT_TRUE(audio_ducker->StartDuckingOtherAudio()); + FlushAudioFocusManager(); + + // The first page should be ducked. + ExpectMediaSessionState(*media_session1, + MediaSessionInfo::SessionState::kDucking); + EXPECT_EQ(AudioDucker::AudioDuckingState::kDucking, + audio_ducker->GetAudioDuckingState()); + + // Add a video into the second page and play it. + AddVideo(*web_contents2); + PlayVideoAndWaitForAudioFocus(*web_contents2); + content::MediaSession* media_session2 = + content::MediaSession::GetIfExists(web_contents2); + ASSERT_TRUE(media_session2); + + // The first page should still be ducked but the second page should not be + // ducked. + ExpectMediaSessionState(*media_session1, + MediaSessionInfo::SessionState::kDucking); + ExpectMediaSessionState(*media_session2, + MediaSessionInfo::SessionState::kActive); + EXPECT_EQ(AudioDucker::AudioDuckingState::kDucking, + audio_ducker->GetAudioDuckingState()); + + // Tell the AudioDucker to stop ducking. + EXPECT_TRUE(audio_ducker->StopDuckingOtherAudio()); + FlushAudioFocusManager(); + + // The first page should no longer be ducked. + ExpectMediaSessionState(*media_session1, + MediaSessionInfo::SessionState::kActive); + ExpectMediaSessionState(*media_session2, + MediaSessionInfo::SessionState::kActive); + EXPECT_EQ(AudioDucker::AudioDuckingState::kNoDucking, + audio_ducker->GetAudioDuckingState()); +}
diff --git a/chrome/browser/net/profile_network_context_service_browsertest.cc b/chrome/browser/net/profile_network_context_service_browsertest.cc index 1d3c941..f3ce54e 100644 --- a/chrome/browser/net/profile_network_context_service_browsertest.cc +++ b/chrome/browser/net/profile_network_context_service_browsertest.cc
@@ -845,19 +845,7 @@ class ProfileNetworkContextTrustTokensBrowsertest : public ProfileNetworkContextServiceBrowsertest { public: - ProfileNetworkContextTrustTokensBrowsertest() { - auto& field_trial_param = - network::features::kTrustTokenOperationsRequiringOriginTrial; - feature_list_.InitWithFeaturesAndParameters( - // Enabled Features: - {{network::features::kPrivateStateTokens, - {{field_trial_param.name, - field_trial_param.GetName( - network::features::TrustTokenOriginTrialSpec:: - kOriginTrialNotRequired)}}}}, - // Disabled Features: - {}); - } + ProfileNetworkContextTrustTokensBrowsertest() = default; ~ProfileNetworkContextTrustTokensBrowsertest() override = default; void SetUpOnMainThread() override { @@ -909,12 +897,10 @@ private: std::unique_ptr<net::EmbeddedTestServer> https_server_; network::test::TrustTokenRequestHandler request_handler_; - base::test::ScopedFeatureList feature_list_; }; IN_PROC_BROWSER_TEST_F(ProfileNetworkContextTrustTokensBrowsertest, TrustTokenBlocked) { - base::test::ScopedFeatureList feature_list_; ProvideRequestHandlerKeyCommitmentsToNetworkService("a.test"); auto* privacy_sandbox_settings = PrivacySandboxSettingsFactory::GetForProfile(browser()->profile());
diff --git a/chrome/browser/net/trust_token_usecounter_browsertest.cc b/chrome/browser/net/trust_token_usecounter_browsertest.cc index f4faeac..0f1bf8b 100644 --- a/chrome/browser/net/trust_token_usecounter_browsertest.cc +++ b/chrome/browser/net/trust_token_usecounter_browsertest.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" @@ -11,7 +10,6 @@ #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" #include "net/test/embedded_test_server/embedded_test_server.h" -#include "services/network/public/cpp/features.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h" @@ -28,9 +26,7 @@ class TrustTokenUseCountersBrowsertest : public InProcessBrowserTest { public: - TrustTokenUseCountersBrowsertest() { - features_.InitAndEnableFeature(network::features::kPrivateStateTokens); - } + TrustTokenUseCountersBrowsertest() = default; void SetUpOnMainThread() override { server_.AddDefaultHandlers( @@ -39,8 +35,6 @@ } protected: - base::test::ScopedFeatureList features_; - net::EmbeddedTestServer server_{net::EmbeddedTestServer::TYPE_HTTPS}; };
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index daa5ef7f..22cfee7 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -202,7 +202,6 @@ #include "chrome/browser/ash/policy/handlers/configuration_policy_handler_ash.h" #include "chrome/browser/ash/policy/handlers/contextual_google_integrations_policies_handler.h" #include "chrome/browser/ash/policy/handlers/help_me_read_policy_handler.h" -#include "chrome/browser/ash/policy/handlers/lacros_availability_policy_handler.h" #include "chrome/browser/ash/policy/handlers/lacros_selection_policy_handler.h" #include "chrome/browser/ash/policy/handlers/multi_screen_capture_policy_handler.h" #include "chrome/browser/ash/policy/handlers/screen_capture_location_policy_handler.h" @@ -3052,7 +3051,6 @@ SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED)); handlers->AddHandler(std::make_unique<BooleanDisablingPolicyHandler>( key::kNearbyShareAllowed, prefs::kNearbySharingEnabledPrefName)); - handlers->AddHandler(std::make_unique<LacrosAvailabilityPolicyHandler>()); handlers->AddHandler(std::make_unique<LacrosSelectionPolicyHandler>()); handlers->AddHandler(std::make_unique<BooleanDisablingPolicyHandler>( key::kFastPairEnabled, ash::prefs::kFastPairEnabled));
diff --git a/chrome/browser/policy/test/default_search_provider_policy_browsertest.cc b/chrome/browser/policy/test/default_search_provider_policy_browsertest.cc index 3f8d9b6..47c09b01 100644 --- a/chrome/browser/policy/test/default_search_provider_policy_browsertest.cc +++ b/chrome/browser/policy/test/default_search_provider_policy_browsertest.cc
@@ -56,8 +56,7 @@ search_test_utils::WaitForTemplateURLServiceToLoad(service); const TemplateURL* default_search = service->GetDefaultSearchProvider(); ASSERT_TRUE(default_search); - EXPECT_EQ(default_search->created_by_policy(), - TemplateURLData::CreatedByPolicy::kNoPolicy); + EXPECT_FALSE(default_search->CreatedByPolicy()); EXPECT_NE(kKeyword, default_search->keyword()); EXPECT_NE(kSearchURL, default_search->url()); EXPECT_FALSE(default_search->alternate_urls().size() == 2 && @@ -96,8 +95,7 @@ UpdateProviderPolicy(policies); default_search = service->GetDefaultSearchProvider(); ASSERT_TRUE(default_search); - EXPECT_EQ(default_search->created_by_policy(), - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider); + EXPECT_TRUE(default_search->CreatedByDefaultSearchProviderPolicy()); EXPECT_EQ(kKeyword, default_search->keyword()); EXPECT_EQ(kSearchURL, default_search->url()); EXPECT_EQ(2U, default_search->alternate_urls().size());
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 8424b56..f45d3c59 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -1169,8 +1169,13 @@ const char kCryptAuthEnrollmentUserPrivateKey[] = "cryptauth.enrollment.user_private_key"; const char kLacrosLaunchOnLogin[] = "lacros.launch_on_login"; +const char kLacrosLaunchSwitch[] = "lacros_launch_switch"; #endif +// Deprecated 12/2024. +inline constexpr char kPageContentCollectionEnabled[] = + "page_content_collection.enabled"; + // Register local state used only for migration (clearing or moving to a new // key). void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) { @@ -1280,6 +1285,11 @@ // Deprecated 11/2024. registry->RegisterIntegerPref(kOnDeviceModelTimeoutCount, 0); + +#if BUILDFLAG(IS_CHROMEOS) + // Deprecated 12/2024. + registry->RegisterIntegerPref(kLacrosLaunchSwitch, 0); +#endif } // Register prefs used only for migration (clearing or moving to a new key). @@ -1663,6 +1673,9 @@ std::string()); registry->RegisterBooleanPref(kLacrosLaunchOnLogin, false); #endif + + // Deprecated 12/2024. + registry->RegisterBooleanPref(kPageContentCollectionEnabled, false); } } // namespace @@ -2161,6 +2174,7 @@ bookmarks_webui::RegisterProfilePrefs(registry); browser_sync::ForeignSessionHandler::RegisterProfilePrefs(registry); BrowserUserEducationStorageService::RegisterProfilePrefs(registry); + captions::LiveCaptionController::RegisterProfilePrefs(registry); captions::LiveTranslateController::RegisterProfilePrefs(registry); ChromeAuthenticatorRequestDelegate::RegisterProfilePrefs(registry); commerce::CommerceUiTabHelper::RegisterProfilePrefs(registry); @@ -2199,10 +2213,6 @@ toolbar::RegisterProfilePrefs(registry); UnifiedAutoplayConfig::RegisterProfilePrefs(registry); user_notes::RegisterProfilePrefs(registry); - -#if !BUILDFLAG(IS_CHROMEOS_LACROS) - captions::LiveCaptionController::RegisterProfilePrefs(registry); -#endif // !BUILDFLAG(IS_CHROMEOS_LACROS) #endif // BUILDFLAG(IS_ANDROID) #if BUILDFLAG(IS_CHROMEOS) @@ -2582,6 +2592,11 @@ optimization_guide::model_execution::prefs::MigrateLegacyUsagePrefs( local_state); + // Added 12/2024 +#if BUILDFLAG(IS_CHROMEOS) + local_state->ClearPref(kLacrosLaunchSwitch); +#endif + // Please don't delete the following line. It is used by PRESUBMIT.py. // END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS @@ -3000,6 +3015,9 @@ profile_prefs->ClearPref(kLacrosLaunchOnLogin); #endif + // Added 12/2024. + profile_prefs->ClearPref(kPageContentCollectionEnabled); + // Please don't delete the following line. It is used by PRESUBMIT.py. // END_MIGRATE_OBSOLETE_PROFILE_PREFS
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java index 86b4d333f..5082c75f 100644 --- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java
@@ -572,11 +572,9 @@ ReadAloudReadabilityHooksFactory factory = ServiceLoaderUtil.maybeCreate(ReadAloudReadabilityHooksFactory.class); if (factory != null) { - mReadabilityHooks = factory.create(mActivity.getApplicationContext(), profile); + mReadabilityHooks = factory.create(mActivity, profile); } else { - mReadabilityHooks = - new ReadAloudReadabilityHooksUpstreamImpl( - mActivity.getApplicationContext(), profile); + mReadabilityHooks = new ReadAloudReadabilityHooksUpstreamImpl(mActivity, profile); } if (mReadabilityHooks.isEnabled()) { boolean isAllowed = ReadAloudFeatures.isAllowed(profile);
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index c54052fd..2ac8293 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -4649,10 +4649,7 @@ // added benefit of also doing the right thing when Lacros is enabled). #if BUILDFLAG(IS_CHROMEOS_ASH) chrome::SettingsWindowManager::GetInstance()->ShowOSSettings( - GetProfile(), - ash::features::IsOsSettingsRevampWayfindingEnabled() - ? chromeos::settings::mojom::kLanguagesSubpagePath - : chromeos::settings::mojom::kLanguagesAndInputSectionPath); + GetProfile(), chromeos::settings::mojom::kLanguagesSubpagePath); #else WindowOpenDisposition disposition = ui::DispositionFromEventFlags( event_flags, WindowOpenDisposition::NEW_FOREGROUND_TAB);
diff --git a/chrome/browser/resources/ash/settings/BUILD.gn b/chrome/browser/resources/ash/settings/BUILD.gn index c9016fb..748fc22 100644 --- a/chrome/browser/resources/ash/settings/BUILD.gn +++ b/chrome/browser/resources/ash/settings/BUILD.gn
@@ -284,7 +284,6 @@ "os_languages_page/os_japanese_dictionary_expand.ts", "os_languages_page/os_japanese_dictionary_entry_row.ts", "os_languages_page/os_languages_page_v2.ts", - "os_languages_page/os_languages_section.ts", "os_people_page/account_manager_settings_card.ts", "os_people_page/add_user_dialog.ts", "os_people_page/additional_accounts_settings_card.ts",
diff --git a/chrome/browser/resources/ash/settings/common/route_origin_mixin.ts b/chrome/browser/resources/ash/settings/common/route_origin_mixin.ts index de33fb9..7431d5fa 100644 --- a/chrome/browser/resources/ash/settings/common/route_origin_mixin.ts +++ b/chrome/browser/resources/ash/settings/common/route_origin_mixin.ts
@@ -75,9 +75,6 @@ } // Route change does not apply to the route for this page. - // When infinite scroll exists (OsSettingsRevampWayfinding disabled) - // subpage triggers should be refocused if the previous route was the - // root page. if (newRoute !== this.route && newRoute !== routes.BASIC) { return; }
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html deleted file mode 100644 index b6058b3..0000000 --- a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html +++ /dev/null
@@ -1,66 +0,0 @@ -<style include="settings-shared"></style> - -<!-- Top-level settings section. --> -<os-settings-animated-pages id="pages" section="[[section_]]"> - <div route-path="default"> - <language-settings-card - prefs="{{prefs}}" - languages="[[languages]]" - language-helper="[[languageHelper]]"> - </language-settings-card> - </div> - - <!-- "Languages" page. --> - <template is="dom-if" route-path="/osLanguages/languages"> - <os-settings-subpage page-title="$i18n{languagesPageTitle}"> - <os-settings-languages-page-v2 - language-helper="[[languageHelper]]" - languages="[[languages]]" - prefs="{{prefs}}"> - </os-settings-languages-page-v2> - </os-settings-subpage> - </template> - - <!-- "App Languages" sub-page. --> - <template is="dom-if" route-path="/osLanguages/languages/appLanguages"> - <os-settings-subpage page-title="$i18n{appLanguagesTitle}"> - <os-settings-app-languages-page prefs="{{prefs}}"> - </os-settings-app-languages-page> - </os-settings-subpage> - </template> - - <!-- "Input" page. --> - <template is="dom-if" route-path="/osLanguages/input"> - <os-settings-subpage page-title="$i18n{inputPageTitle}"> - <os-settings-input-page language-helper="[[languageHelper]]" - languages="[[languages]]" prefs="{{prefs}}"> - </os-settings-input-page> - </os-settings-subpage> - </template> - - <!-- "Input method settings" sub-sub-page. --> - <template is="dom-if" route-path="/osLanguages/inputMethodOptions"> - <os-settings-subpage> - <settings-input-method-options-page - language-helper="[[languageHelper]]" - prefs="{{prefs}}"> - </settings-input-method-options-page> - </os-settings-subpage> - </template> - - <!-- "Customize spell check" sub-sub-page. --> - <template is="dom-if" route-path="/osLanguages/editDictionary"> - <os-settings-subpage page-title="$i18n{editDictionaryLabel}"> - <os-settings-edit-dictionary-page></os-settings-edit-dictionary-page> - </os-settings-subpage> - </template> - - <!-- "Japanese Manage User dictionary" sub-sub-page. --> - <template is="dom-if" route-path="/osLanguages/japaneseManageUserDictionary"> - <os-settings-subpage page-title="$i18n{japaneseManageUserDictionaryLabel}"> - <os-settings-japanese-manage-user-dictionary-page> - </os-settings-japanese-manage-user-dictionary-page> - </os-settings-subpage> - </template> - -</os-settings-animated-pages>
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.ts b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.ts deleted file mode 100644 index ea5f51e..0000000 --- a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.ts +++ /dev/null
@@ -1,83 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview - * 'os-settings-languages-section' is the top-level settings section for - * languages. - */ - -import 'chrome://resources/ash/common/cr_elements/cr_icon_button/cr_icon_button.js'; -import 'chrome://resources/ash/common/cr_elements/cr_shared_vars.css.js'; -import './language_settings_card.js'; -import '../os_settings_page/os_settings_animated_pages.js'; -import '../os_settings_page/os_settings_subpage.js'; -import '../settings_shared.css.js'; -import '../settings_vars.css.js'; - -import {I18nMixin} from 'chrome://resources/ash/common/cr_elements/i18n_mixin.js'; -import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -import type {PrefsState} from '../common/types.js'; -import {Section} from '../mojom-webui/routes.mojom-webui.js'; - -import type {LanguageHelper, LanguagesModel} from './languages_types.js'; -import {getTemplate} from './os_languages_section.html.js'; - -const OsSettingsLanguagesSectionElementBase = I18nMixin(PolymerElement); - -export class OsSettingsLanguagesSectionElement extends - OsSettingsLanguagesSectionElementBase { - static get is() { - return 'os-settings-languages-section' as const; - } - - static get template() { - return getTemplate(); - } - - static get properties() { - return { - prefs: { - type: Object, - notify: true, - }, - - section_: { - type: Number, - value: Section.kLanguagesAndInput, - readOnly: true, - }, - - /** - * Set of languages from <settings-languages> - */ - languages: Object, - - /** - * Language helper API from <settings-languages> - */ - languageHelper: Object, - }; - } - - // Public API: Bidirectional data flow. - /** Passed down to children. Do not access without using PrefsMixin. */ - prefs: PrefsState; - - languages: LanguagesModel|undefined; - languageHelper: LanguageHelper|undefined; - - // Internal state. - private section_: Section; -} - -customElements.define( - OsSettingsLanguagesSectionElement.is, OsSettingsLanguagesSectionElement); - -declare global { - interface HTMLElementTagNameMap { - [OsSettingsLanguagesSectionElement.is]: OsSettingsLanguagesSectionElement; - } -}
diff --git a/chrome/browser/resources/ash/settings/os_page_availability.ts b/chrome/browser/resources/ash/settings/os_page_availability.ts index 5eaf4150..2b7bd4e 100644 --- a/chrome/browser/resources/ash/settings/os_page_availability.ts +++ b/chrome/browser/resources/ash/settings/os_page_availability.ts
@@ -45,11 +45,6 @@ [Section.kPeople]: !!routes.OS_PEOPLE, [Section.kPersonalization]: !!routes.PERSONALIZATION, [Section.kPrivacyAndSecurity]: !!routes.OS_PRIVACY, - - // Only available when OsSettingsRevampWayfinding feature is enabled. [Section.kSystemPreferences]: !!routes.SYSTEM_PREFERENCES, - - // Only available when OsSettingsRevampWayfinding feature is disabled. - [Section.kLanguagesAndInput]: !!routes.OS_LANGUAGES, }; }
diff --git a/chrome/browser/resources/ash/settings/os_settings_routes.ts b/chrome/browser/resources/ash/settings/os_settings_routes.ts index 316b9dd3..824e3ca 100644 --- a/chrome/browser/resources/ash/settings/os_settings_routes.ts +++ b/chrome/browser/resources/ash/settings/os_settings_routes.ts
@@ -13,7 +13,7 @@ import {assert} from 'chrome://resources/js/assert.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; -import {androidAppsVisible, isAppParentalControlsFeatureAvailable, isArcVmEnabled, isCrostiniSupported, isGuest, isInputDeviceSettingsSplitEnabled, isKerberosEnabled, isPluginVmAvailable, isRevampWayfindingEnabled} from './common/load_time_booleans.js'; +import {androidAppsVisible, isAppParentalControlsFeatureAvailable, isArcVmEnabled, isCrostiniSupported, isGuest, isInputDeviceSettingsSplitEnabled, isKerberosEnabled, isPluginVmAvailable} from './common/load_time_booleans.js'; import * as routesMojom from './mojom-webui/routes.mojom-webui.js'; /** @@ -342,17 +342,6 @@ if (!isGuest()) { r.OS_PEOPLE = createSection( r.BASIC, routesMojom.PEOPLE_SECTION_PATH, Section.kPeople); - - if (!isRevampWayfindingEnabled()) { - r.ACCOUNT_MANAGER = createSubpage( - r.OS_PEOPLE, routesMojom.MY_ACCOUNTS_SUBPAGE_PATH, - Subpage.kMyAccounts); - // TODO(b/305747266) : Disambiguate the names for OS_SYNC and SYNC. - r.OS_SYNC = createSubpage( - r.OS_PEOPLE, routesMojom.SYNC_SUBPAGE_PATH, Subpage.kSync); - r.SYNC = createSubpage( - r.OS_PEOPLE, routesMojom.SYNC_SETUP_SUBPAGE_PATH, Subpage.kSyncSetup); - } } // Kerberos section. @@ -547,141 +536,103 @@ r.ABOUT, routesMojom.INTERNAL_STORYBOOK_SUBPAGE_PATH, Subpage.kInternalStorybook); - if (isRevampWayfindingEnabled()) { - // Device section, Input subpages. - const inputParentRoute = isInputDeviceSettingsSplitEnabled() ? - r.PER_DEVICE_KEYBOARD : - r.KEYBOARD; - assert(inputParentRoute); - r.OS_LANGUAGES_INPUT = createSubpage( - inputParentRoute, routesMojom.INPUT_SUBPAGE_PATH, Subpage.kInput); - r.OS_LANGUAGES_INPUT_METHOD_OPTIONS = createSubpage( - r.OS_LANGUAGES_INPUT, routesMojom.INPUT_METHOD_OPTIONS_SUBPAGE_PATH, - Subpage.kInputMethodOptions); - r.OS_LANGUAGES_EDIT_DICTIONARY = createSubpage( - r.OS_LANGUAGES_INPUT, routesMojom.EDIT_DICTIONARY_SUBPAGE_PATH, - Subpage.kEditDictionary); - r.OS_LANGUAGES_JAPANESE_MANAGE_USER_DICTIONARY = createSubpage( - r.OS_LANGUAGES_INPUT, - routesMojom.JAPANESE_MANAGE_USER_DICTIONARY_SUBPAGE_PATH, - Subpage.kJapaneseManageUserDictionary); + // Device section, Input subpages. + const inputParentRoute = + isInputDeviceSettingsSplitEnabled() ? r.PER_DEVICE_KEYBOARD : r.KEYBOARD; + assert(inputParentRoute); + r.OS_LANGUAGES_INPUT = createSubpage( + inputParentRoute, routesMojom.INPUT_SUBPAGE_PATH, Subpage.kInput); + r.OS_LANGUAGES_INPUT_METHOD_OPTIONS = createSubpage( + r.OS_LANGUAGES_INPUT, routesMojom.INPUT_METHOD_OPTIONS_SUBPAGE_PATH, + Subpage.kInputMethodOptions); + r.OS_LANGUAGES_EDIT_DICTIONARY = createSubpage( + r.OS_LANGUAGES_INPUT, routesMojom.EDIT_DICTIONARY_SUBPAGE_PATH, + Subpage.kEditDictionary); + r.OS_LANGUAGES_JAPANESE_MANAGE_USER_DICTIONARY = createSubpage( + r.OS_LANGUAGES_INPUT, + routesMojom.JAPANESE_MANAGE_USER_DICTIONARY_SUBPAGE_PATH, + Subpage.kJapaneseManageUserDictionary); - // System Preferences section. - r.SYSTEM_PREFERENCES = createSection( - r.BASIC, routesMojom.SYSTEM_PREFERENCES_SECTION_PATH, - Section.kSystemPreferences); + // System Preferences section. + r.SYSTEM_PREFERENCES = createSection( + r.BASIC, routesMojom.SYSTEM_PREFERENCES_SECTION_PATH, + Section.kSystemPreferences); - // Date and Time subpages. - r.DATETIME_TIMEZONE_SUBPAGE = createSubpage( - r.SYSTEM_PREFERENCES, routesMojom.TIME_ZONE_SUBPAGE_PATH, - Subpage.kTimeZone); + // Date and Time subpages. + r.DATETIME_TIMEZONE_SUBPAGE = createSubpage( + r.SYSTEM_PREFERENCES, routesMojom.TIME_ZONE_SUBPAGE_PATH, + Subpage.kTimeZone); - // Files subpages. - if (!isGuest()) { - r.GOOGLE_DRIVE = createSubpage( - r.SYSTEM_PREFERENCES, routesMojom.GOOGLE_DRIVE_SUBPAGE_PATH, - Subpage.kGoogleDrive); - if (loadTimeData.getBoolean('showOfficeSettings')) { - r.OFFICE = createSubpage( - r.SYSTEM_PREFERENCES, routesMojom.OFFICE_FILES_SUBPAGE_PATH, - Subpage.kOfficeFiles); - } - if (loadTimeData.getBoolean('showOneDriveSettings')) { - r.ONE_DRIVE = createSubpage( - r.SYSTEM_PREFERENCES, routesMojom.ONE_DRIVE_SUBPAGE_PATH, - Subpage.kOneDrive); - } - r.SMB_SHARES = createSubpage( - r.SYSTEM_PREFERENCES, routesMojom.NETWORK_FILE_SHARES_SUBPAGE_PATH, - Subpage.kNetworkFileShares); + // Files subpages. + if (!isGuest()) { + r.GOOGLE_DRIVE = createSubpage( + r.SYSTEM_PREFERENCES, routesMojom.GOOGLE_DRIVE_SUBPAGE_PATH, + Subpage.kGoogleDrive); + if (loadTimeData.getBoolean('showOfficeSettings')) { + r.OFFICE = createSubpage( + r.SYSTEM_PREFERENCES, routesMojom.OFFICE_FILES_SUBPAGE_PATH, + Subpage.kOfficeFiles); } - - // Language subpages. - r.OS_LANGUAGES_LANGUAGES = createSubpage( - r.SYSTEM_PREFERENCES, routesMojom.LANGUAGES_SUBPAGE_PATH, - Subpage.kLanguages); - if (loadTimeData.getBoolean('isPerAppLanguageEnabled')) { - r.OS_LANGUAGES_APP_LANGUAGES = createSubpage( - r.OS_LANGUAGES_LANGUAGES, routesMojom.APP_LANGUAGES_SUBPAGE_PATH, - Subpage.kAppLanguages); + if (loadTimeData.getBoolean('showOneDriveSettings')) { + r.ONE_DRIVE = createSubpage( + r.SYSTEM_PREFERENCES, routesMojom.ONE_DRIVE_SUBPAGE_PATH, + Subpage.kOneDrive); } + r.SMB_SHARES = createSubpage( + r.SYSTEM_PREFERENCES, routesMojom.NETWORK_FILE_SHARES_SUBPAGE_PATH, + Subpage.kNetworkFileShares); + } - // Search and Assistant subpages. - r.SEARCH_SUBPAGE = createSubpage( - r.SYSTEM_PREFERENCES, routesMojom.SEARCH_SUBPAGE_PATH, Subpage.kSearch); - r.GOOGLE_ASSISTANT = createSubpage( - r.SYSTEM_PREFERENCES, routesMojom.ASSISTANT_SUBPAGE_PATH, - Subpage.kAssistant); + // Language subpages. + r.OS_LANGUAGES_LANGUAGES = createSubpage( + r.SYSTEM_PREFERENCES, routesMojom.LANGUAGES_SUBPAGE_PATH, + Subpage.kLanguages); + if (loadTimeData.getBoolean('isPerAppLanguageEnabled')) { + r.OS_LANGUAGES_APP_LANGUAGES = createSubpage( + r.OS_LANGUAGES_LANGUAGES, routesMojom.APP_LANGUAGES_SUBPAGE_PATH, + Subpage.kAppLanguages); + } - // Storage and power subpages. - r.STORAGE = createSubpage( - r.SYSTEM_PREFERENCES, routesMojom.STORAGE_SUBPAGE_PATH, - Subpage.kStorage); - r.EXTERNAL_STORAGE_PREFERENCES = createSubpage( - r.STORAGE, routesMojom.EXTERNAL_STORAGE_SUBPAGE_PATH, - Subpage.kExternalStorage); - r.POWER = createSubpage( - r.SYSTEM_PREFERENCES, routesMojom.POWER_SUBPAGE_PATH, Subpage.kPower); + // Search and Assistant subpages. + r.SEARCH_SUBPAGE = createSubpage( + r.SYSTEM_PREFERENCES, routesMojom.SEARCH_SUBPAGE_PATH, Subpage.kSearch); + r.GOOGLE_ASSISTANT = createSubpage( + r.SYSTEM_PREFERENCES, routesMojom.ASSISTANT_SUBPAGE_PATH, + Subpage.kAssistant); - // Printing subpage. - r.CUPS_PRINTERS = createSubpage( - r.DEVICE, routesMojom.PRINTING_DETAILS_SUBPAGE_PATH, - Subpage.kPrintingDetails); + // Storage and power subpages. + r.STORAGE = createSubpage( + r.SYSTEM_PREFERENCES, routesMojom.STORAGE_SUBPAGE_PATH, Subpage.kStorage); + r.EXTERNAL_STORAGE_PREFERENCES = createSubpage( + r.STORAGE, routesMojom.EXTERNAL_STORAGE_SUBPAGE_PATH, + Subpage.kExternalStorage); + r.POWER = createSubpage( + r.SYSTEM_PREFERENCES, routesMojom.POWER_SUBPAGE_PATH, Subpage.kPower); - // Crostini subpages. - if (isCrostiniSupported()) { - r.CROSTINI_DETAILS = createSubpage( - r.ABOUT, routesMojom.CROSTINI_DETAILS_SUBPAGE_PATH, - Subpage.kCrostiniDetails); + // Printing subpage. + r.CUPS_PRINTERS = createSubpage( + r.DEVICE, routesMojom.PRINTING_DETAILS_SUBPAGE_PATH, + Subpage.kPrintingDetails); - r.BRUSCHETTA_DETAILS = createSubpage( - r.ABOUT, routesMojom.BRUSCHETTA_DETAILS_SUBPAGE_PATH, - Subpage.kBruschettaDetails); - } + // Crostini subpages. + if (isCrostiniSupported()) { + r.CROSTINI_DETAILS = createSubpage( + r.ABOUT, routesMojom.CROSTINI_DETAILS_SUBPAGE_PATH, + Subpage.kCrostiniDetails); - // Sync subpages. - if (!isGuest()) { - assert(r.OS_PRIVACY); - // TODO(b/305747266) : Disambiguate the names for OS_SYNC and SYNC. - r.OS_SYNC = createSubpage( - r.OS_PRIVACY, routesMojom.SYNC_SUBPAGE_PATH, Subpage.kSync); - r.SYNC = createSubpage( - r.OS_PRIVACY, routesMojom.SYNC_SETUP_SUBPAGE_PATH, - Subpage.kSyncSetup); - } - } else { - // Device section. - r.STORAGE = createSubpage( - r.DEVICE, routesMojom.STORAGE_SUBPAGE_PATH, Subpage.kStorage); - r.EXTERNAL_STORAGE_PREFERENCES = createSubpage( - r.STORAGE, routesMojom.EXTERNAL_STORAGE_SUBPAGE_PATH, - Subpage.kExternalStorage); - r.POWER = - createSubpage(r.DEVICE, routesMojom.POWER_SUBPAGE_PATH, Subpage.kPower); + r.BRUSCHETTA_DETAILS = createSubpage( + r.ABOUT, routesMojom.BRUSCHETTA_DETAILS_SUBPAGE_PATH, + Subpage.kBruschettaDetails); + } - // Languages and Input section. - r.OS_LANGUAGES = createSection( - r.ADVANCED, routesMojom.LANGUAGES_AND_INPUT_SECTION_PATH, - Section.kLanguagesAndInput); - r.OS_LANGUAGES_LANGUAGES = createSubpage( - r.OS_LANGUAGES, routesMojom.LANGUAGES_SUBPAGE_PATH, Subpage.kLanguages); - r.OS_LANGUAGES_INPUT = createSubpage( - r.OS_LANGUAGES, routesMojom.INPUT_SUBPAGE_PATH, Subpage.kInput); - r.OS_LANGUAGES_INPUT_METHOD_OPTIONS = createSubpage( - r.OS_LANGUAGES_INPUT, routesMojom.INPUT_METHOD_OPTIONS_SUBPAGE_PATH, - Subpage.kInputMethodOptions); - r.OS_LANGUAGES_EDIT_DICTIONARY = createSubpage( - r.OS_LANGUAGES_INPUT, routesMojom.EDIT_DICTIONARY_SUBPAGE_PATH, - Subpage.kEditDictionary); - r.OS_LANGUAGES_JAPANESE_MANAGE_USER_DICTIONARY = createSubpage( - r.OS_LANGUAGES_INPUT, - routesMojom.JAPANESE_MANAGE_USER_DICTIONARY_SUBPAGE_PATH, - Subpage.kJapaneseManageUserDictionary); - if (loadTimeData.getBoolean('isPerAppLanguageEnabled')) { - r.OS_LANGUAGES_APP_LANGUAGES = createSubpage( - r.OS_LANGUAGES_LANGUAGES, routesMojom.APP_LANGUAGES_SUBPAGE_PATH, - Subpage.kAppLanguages); - } + // Sync subpages. + if (!isGuest()) { + assert(r.OS_PRIVACY); + // TODO(b/305747266) : Disambiguate the names for OS_SYNC and SYNC. + r.OS_SYNC = createSubpage( + r.OS_PRIVACY, routesMojom.SYNC_SUBPAGE_PATH, Subpage.kSync); + r.SYNC = createSubpage( + r.OS_PRIVACY, routesMojom.SYNC_SETUP_SUBPAGE_PATH, Subpage.kSyncSetup); } // Crostini details subpages.
diff --git a/chrome/browser/resources/ash/settings/router.ts b/chrome/browser/resources/ash/settings/router.ts index 0d78477..ad1f5e6 100644 --- a/chrome/browser/resources/ash/settings/router.ts +++ b/chrome/browser/resources/ash/settings/router.ts
@@ -6,7 +6,6 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {castExists} from './assert_extras.js'; -import {isRevampWayfindingEnabled} from './common/load_time_booleans.js'; import type {RouteObserverMixinInterface} from './common/route_observer_mixin.js'; import type {OsSettingsRoutes} from './os_settings_routes.js'; import {createRoutes, PATH_REDIRECTS, Route} from './os_settings_routes.js'; @@ -169,10 +168,8 @@ // Remove any trailing slash. let canonicalPath = path.replace(CANONICAL_PATH_REGEX, '$1$2'); - // Handle redirects for obsolete paths. - if (isRevampWayfindingEnabled()) { - canonicalPath = PATH_REDIRECTS[canonicalPath] || canonicalPath; - } + // Handle redirects for paths (e.g. deprecated paths). + canonicalPath = PATH_REDIRECTS[canonicalPath] || canonicalPath; const matchingRoute = Object.values(this.routes_).find(route => { return route.path === canonicalPath && isNavigableRoute(route);
diff --git a/chrome/browser/resources/data_sharing/data_sharing.html b/chrome/browser/resources/data_sharing/data_sharing.html index 4383bbea..b06c0bbc 100644 --- a/chrome/browser/resources/data_sharing/data_sharing.html +++ b/chrome/browser/resources/data_sharing/data_sharing.html
@@ -6,6 +6,11 @@ <!-- Add CSS variables for Chrome's themed material color equivalents --> <link rel="stylesheet" href="//theme/colors.css?sets=ui,chrome"> <!-- Load desired system fonts onto the body --> + <style> + body { + margin: 0; + } + </style> <link rel="stylesheet" href="//resources/css/text_defaults_md.css"> <link rel="stylesheet" href="data_sharing_sdk.css"> <script type="module" src="data_sharing_app.js"></script>
diff --git a/chrome/browser/resources/data_sharing/data_sharing_app.html b/chrome/browser/resources/data_sharing/data_sharing_app.html index df1b198f..4be4efec 100644 --- a/chrome/browser/resources/data_sharing/data_sharing_app.html +++ b/chrome/browser/resources/data_sharing/data_sharing_app.html
@@ -2,6 +2,7 @@ .container { width: 448px; min-height: 200px; + background-color: var(--color-sys-surface); --skw-color-primary: var(--color-sys-primary); --skw-color-surface-tint: var(--color-sys-surface-tint);
diff --git a/chrome/browser/resources/extensions/detail_view.ts b/chrome/browser/resources/extensions/detail_view.ts index 0f9351d..7a142c21 100644 --- a/chrome/browser/resources/extensions/detail_view.ts +++ b/chrome/browser/resources/extensions/detail_view.ts
@@ -673,7 +673,7 @@ /** * Returns the HTML representation of the Manifest V2 deprecation message * subtitle string. We need the HTML representation instead of the string - * since the string holds a link. + * since the string holds substitutions. */ protected getMv2DeprecationMessageSubtitle_(): TrustedHTML { switch (this.mv2ExperimentStage_) { @@ -681,8 +681,11 @@ return window.trustedTypes!.emptyHTML; case Mv2ExperimentStage.WARNING: return this.i18nAdvanced('mv2DeprecationMessageWarningSubtitle', { - substitutions: - ['https://chromewebstore.google.com/category/extensions'], + substitutions: [ + 'https://chromewebstore.google.com/category/extensions', + this.i18n('opensInNewTab'), + ], + attrs: ['aria-description'], }); case Mv2ExperimentStage.DISABLE_WITH_REENABLE: case Mv2ExperimentStage.UNSUPPORTED: @@ -690,7 +693,9 @@ substitutions: [ 'https://support.google.com/chrome_webstore' + '?p=unsupported_extensions', + this.i18n('opensInNewTab'), ], + attrs: ['aria-description'], }); default: assertNotReached();
diff --git a/chrome/browser/resources/extensions/mv2_deprecation_panel.ts b/chrome/browser/resources/extensions/mv2_deprecation_panel.ts index 40efaae..ae4b98f 100644 --- a/chrome/browser/resources/extensions/mv2_deprecation_panel.ts +++ b/chrome/browser/resources/extensions/mv2_deprecation_panel.ts
@@ -130,6 +130,8 @@ const subtitle = await PluralStringProxyImpl.getInstance().getPluralString( subtitleVar, this.extensions.length); this.subtitleString_ = subtitle.replace('$1', subtitleLink); + this.subtitleString_ = + this.subtitleString_.replace('$2', this.i18n('opensInNewTab')); } /** @@ -247,7 +249,8 @@ * representation instead of the string since the string holds a link. */ protected getSubtitleString_(): TrustedHTML { - return sanitizeInnerHtml(this.subtitleString_); + return sanitizeInnerHtml( + this.subtitleString_, {attrs: ['aria-description']}); } /**
diff --git a/chrome/browser/resources/glic/glic_api/glic_api.ts b/chrome/browser/resources/glic/glic_api/glic_api.ts index 30ceb8ba..17f5d75 100644 --- a/chrome/browser/resources/glic/glic_api/glic_api.ts +++ b/chrome/browser/resources/glic/glic_api/glic_api.ts
@@ -73,6 +73,9 @@ resizeWindow(width: number, height: number): Promise<{actualWidth: number, actualHeight: number}>; + // Set the areas of the glic window from which it should be draggable. + setWindowDraggableAreas(areas: DraggableArea[]): Promise<void>; + // Fetches page context for the currently focused tab, optionally including // more expensive-to-generate data. Undefined optional arguments indicate that // the respective data is not being requested. @@ -192,3 +195,13 @@ } export type GetTabContextError = ErrorWithReason<GetTabContextErrorReason>; + +/** + * A rectangular area based in the glic window's coordinate system. + */ +export declare interface DraggableArea { + x: number; + y: number; + width: number; + height: number; +}
diff --git a/chrome/browser/resources/glic/glic_api/glic_api_client.ts b/chrome/browser/resources/glic/glic_api/glic_api_client.ts index 679a91ad..02d5896d 100644 --- a/chrome/browser/resources/glic/glic_api/glic_api_client.ts +++ b/chrome/browser/resources/glic/glic_api/glic_api_client.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import type {ErrorWithReason, GlicBrowserHost, GlicHostRegistry, GlicWebClient, TabContextResult, TabData} from '../glic_api/glic_api.js'; +import type {DraggableArea, ErrorWithReason, GlicBrowserHost, GlicHostRegistry, GlicWebClient, TabContextResult, TabData} from '../glic_api/glic_api.js'; import {GetTabContextErrorReason} from '../glic_api/glic_api.js'; import {PostMessageRequestReceiver, PostMessageRequestSender} from './post_message_transport.js'; @@ -141,6 +141,11 @@ return this.sender.requestWithResponse( 'glicBrowserResizeWindow', {width, height}); } + + async setWindowDraggableAreas(areas: DraggableArea[]) { + return this.sender.requestWithResponse( + 'glicBrowserSetWindowDraggableAreas', {areas}); + } } // Returns a promise which resolves to the `GlicHostRegistry`. This promise
diff --git a/chrome/browser/resources/glic/glic_api/request_types.ts b/chrome/browser/resources/glic/glic_api/request_types.ts index dd675cb..3025b49 100644 --- a/chrome/browser/resources/glic/glic_api/request_types.ts +++ b/chrome/browser/resources/glic/glic_api/request_types.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import type {GetTabContextErrorReason, TabContextResult, TabData} from '../glic_api/glic_api.js'; +import type {DraggableArea, GetTabContextErrorReason, TabContextResult, TabData} from '../glic_api/glic_api.js'; /* This file defines messages sent over postMessage in-between the Glic WebUI @@ -82,6 +82,12 @@ actualHeight: number, }, }; + glicBrowserSetWindowDraggableAreas: { + request: { + areas: DraggableArea[], + }, + response: void, + }; } // Types of requests to the GlicWebClient.
diff --git a/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts b/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts index a0dc2ead..8338fe42 100644 --- a/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts +++ b/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts
@@ -18,7 +18,7 @@ import type {BrowserProxy} from '../browser_proxy.js'; import type {WebClientHandlerInterface, WebClientInterface} from '../glic.mojom-webui.js'; import {GetTabContextErrorReason as MojoGetTabContextErrorReason, WebClientHandlerRemote, WebClientReceiver} from '../glic.mojom-webui.js'; -import type {Screenshot, WebPageData} from '../glic_api/glic_api.js'; +import type {DraggableArea, Screenshot, WebPageData} from '../glic_api/glic_api.js'; import {GetTabContextErrorReason} from '../glic_api/glic_api.js'; import type {PostMessageRequestHandler} from '../glic_api/post_message_transport.js'; import {PostMessageRequestReceiver, PostMessageRequestSender} from '../glic_api/post_message_transport.js'; @@ -194,6 +194,10 @@ actualHeight: response.actualSize.height, }; } + + async glicBrowserSetWindowDraggableAreas(request: {areas: DraggableArea[]}) { + this.handler.setPanelDraggableAreas(request.areas); + } } export class GlicApiHost implements PostMessageRequestHandler {
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index 515417aa..b257737 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -626,12 +626,10 @@ </category-setting-exceptions> </settings-subpage> </template> - <template is="dom-if" if="[[privateStateTokensEnabled_]]"> - <template is="dom-if" route-path="/content/autoVerify" no-search> - <settings-subpage page-title="$i18n{siteSettingsAntiAbuse}"> - <settings-anti-abuse-page></settings-anti-abuse-page> - </settings-subpage> - </template> + <template is="dom-if" route-path="/content/autoVerify" no-search> + <settings-subpage page-title="$i18n{siteSettingsAntiAbuse}"> + <settings-anti-abuse-page></settings-anti-abuse-page> + </settings-subpage> </template> <template is="dom-if" route-path="/content/microphone" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryMicrophone}"
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.ts b/chrome/browser/resources/settings/privacy_page/privacy_page.ts index 0db2fc6f..e09c5bd 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.ts +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.ts
@@ -202,11 +202,6 @@ loadTimeData.getBoolean('isPrivacySandboxRestrictedNoticeEnabled'), }, - privateStateTokensEnabled_: { - type: Boolean, - value: () => loadTimeData.getBoolean('privateStateTokensEnabled'), - }, - autoPictureInPictureEnabled_: { type: Boolean, value: () => loadTimeData.getBoolean('autoPictureInPictureEnabled'),
diff --git a/chrome/browser/resources/settings/route.ts b/chrome/browser/resources/settings/route.ts index 5ea1056..5f800ae 100644 --- a/chrome/browser/resources/settings/route.ts +++ b/chrome/browser/resources/settings/route.ts
@@ -92,9 +92,7 @@ r.SITE_SETTINGS.createChild('smartCardReaders'); } // </if> - if (loadTimeData.getBoolean('privateStateTokensEnabled')) { - r.SITE_SETTINGS_AUTO_VERIFY = r.SITE_SETTINGS.createChild('autoVerify'); - } + r.SITE_SETTINGS_AUTO_VERIFY = r.SITE_SETTINGS.createChild('autoVerify'); if (!loadTimeData.getBoolean('enableAiSettingsPageRefresh') && loadTimeData.getBoolean('enableComposeProactiveNudge')) { r.OFFER_WRITING_HELP = r.SITE_SETTINGS.createChild('offerWritingHelp');
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts b/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts index 03c3df3e..ed942aa9 100644 --- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts +++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts
@@ -65,7 +65,6 @@ icon: 'privacy20:person-check', enabledLabel: 'siteSettingsAntiAbuseEnabledSubLabel', disabledLabel: 'siteSettingsAntiAbuseDisabledSubLabel', - shouldShow: () => loadTimeData.getBoolean('privateStateTokensEnabled'), }, { route: routes.SITE_SETTINGS_AR,
diff --git a/chrome/browser/safe_browsing/chrome_client_side_detection_service_delegate.cc b/chrome/browser/safe_browsing/chrome_client_side_detection_service_delegate.cc index 74e84d9..3aa151a 100644 --- a/chrome/browser/safe_browsing/chrome_client_side_detection_service_delegate.cc +++ b/chrome/browser/safe_browsing/chrome_client_side_detection_service_delegate.cc
@@ -25,6 +25,10 @@ optimization_guide::OnDeviceModelEligibilityReason:: kConfigNotAvailableForFeature, optimization_guide::OnDeviceModelEligibilityReason::kModelToBeInstalled, + optimization_guide::OnDeviceModelEligibilityReason:: + kSafetyModelNotAvailable, + optimization_guide::OnDeviceModelEligibilityReason:: + kLanguageDetectionModelNotAvailable, }); } // namespace
diff --git a/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc index d4d9512..99df2fc 100644 --- a/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_service_unittest.cc
@@ -766,12 +766,28 @@ CHECK(availability_observer); // Now that the delegate is observing, send `kConfigNotAvailableForFeature` - // first to the observer, which will not stop the observing. + // first to the observer, which will not stop the observing. We will then test + // for all the possible waitable reasons, which should also not stop + // observing. availability_observer->OnDeviceModelAvailabilityChanged( optimization_guide::ModelBasedCapabilityKey::kScamDetection, optimization_guide::OnDeviceModelEligibilityReason:: kConfigNotAvailableForFeature); + availability_observer->OnDeviceModelAvailabilityChanged( + optimization_guide::ModelBasedCapabilityKey::kScamDetection, + optimization_guide::OnDeviceModelEligibilityReason::kModelToBeInstalled); + + availability_observer->OnDeviceModelAvailabilityChanged( + optimization_guide::ModelBasedCapabilityKey::kScamDetection, + optimization_guide::OnDeviceModelEligibilityReason:: + kSafetyModelNotAvailable); + + availability_observer->OnDeviceModelAvailabilityChanged( + optimization_guide::ModelBasedCapabilityKey::kScamDetection, + optimization_guide::OnDeviceModelEligibilityReason:: + kLanguageDetectionModelNotAvailable); + histogram_tester.ExpectUniqueSample( "SBClientPhishing.OnDeviceModelDownloadSuccess", true, 0);
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_browsertest.cc b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_browsertest.cc index 749d140..a281f160 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_browsertest.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_browsertest.cc
@@ -74,7 +74,6 @@ scoped_feature_list_.InitWithFeatures( /*enabled_features=*/ {kExtensionTelemetryForEnterprise, - kExtensionTelemetryReportContactedHosts, kExtensionTelemetryDeclarativeNetRequestActionSignal, extensions_features::kIncludeJSCallStackInExtensionApiRequest}, /*disabled_features=*/ @@ -870,8 +869,7 @@ scoped_feature_list_.Reset(); scoped_feature_list_.InitWithFeatures( /*enabled_features=*/ - {kExtensionTelemetryInterceptRemoteHostsContactedInRenderer, - kExtensionTelemetryReportContactedHosts}, + {kExtensionTelemetryInterceptRemoteHostsContactedInRenderer}, /*disabled_features=*/{}); } };
diff --git a/chrome/browser/search_engine_choice/search_engine_choice_dialog_service_unittest.cc b/chrome/browser/search_engine_choice/search_engine_choice_dialog_service_unittest.cc index 2362931..3e3c6f4 100644 --- a/chrome/browser/search_engine_choice/search_engine_choice_dialog_service_unittest.cc +++ b/chrome/browser/search_engine_choice/search_engine_choice_dialog_service_unittest.cc
@@ -49,8 +49,7 @@ "https://%s/alt#quux={searchTerms}", kCustomSearchEngineDomain)); if (created_by_policy) { - data.created_by_policy = - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider; + data.policy_origin = TemplateURLData::PolicyOrigin::kDefaultSearchProvider; } TemplateURL* template_url =
diff --git a/chrome/browser/search_engines/template_url_service_sync_unittest.cc b/chrome/browser/search_engines/template_url_service_sync_unittest.cc index 341c45b..4d30cec 100644 --- a/chrome/browser/search_engines/template_url_service_sync_unittest.cc +++ b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
@@ -499,7 +499,7 @@ model()->Add(CreateTestTemplateURL(u"key2", "http://key2.com")); model()->Add(CreateTestTemplateURL( u"key3", "http://key3.com", std::string(), base::Time::FromTimeT(100), - false, TemplateURLData::CreatedByPolicy::kDefaultSearchProvider)); + false, TemplateURLData::PolicyOrigin::kDefaultSearchProvider)); syncer::SyncDataList all_sync_data = model()->GetAllSyncData(syncer::SEARCH_ENGINES); @@ -510,8 +510,7 @@ std::string guid = GetGUID(*iter); TemplateURL* service_turl = model()->GetTemplateURLForGUID(guid); std::unique_ptr<TemplateURL> deserialized(Deserialize(*iter)); - ASSERT_EQ(service_turl->created_by_policy(), - TemplateURLData::CreatedByPolicy::kNoPolicy); + ASSERT_FALSE(service_turl->CreatedByPolicy()); AssertEquals(*service_turl, *deserialized); } } @@ -697,17 +696,17 @@ // Duplicate keyword, same hostname model()->Add(CreateTestTemplateURL( u"key1", "http://key1.com", "localguid1", base::Time::FromTimeT(10), - false, TemplateURLData::CreatedByPolicy::kNoPolicy, 111)); + false, TemplateURLData::PolicyOrigin::kNoPolicy, 111)); // Duplicate keyword, different hostname model()->Add(CreateTestTemplateURL( u"key2", "http://expected.com", "localguid2", base::Time::FromTimeT(10), - false, TemplateURLData::CreatedByPolicy::kNoPolicy, 112)); + false, TemplateURLData::PolicyOrigin::kNoPolicy, 112)); // Add model()->Add(CreateTestTemplateURL( u"unique", "http://unique.com", "localguid3", base::Time::FromTimeT(10), - false, TemplateURLData::CreatedByPolicy::kNoPolicy, 113)); + false, TemplateURLData::PolicyOrigin::kNoPolicy, 113)); ASSERT_EQ(3U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size()); MergeAndExpectNotify(CreateInitialSyncData(), 1); @@ -749,8 +748,8 @@ model()->Add(CreateTestTemplateURL( u"key1", "http://key1.com", "localguid1", base::Time::FromTimeT(100), /*safe_for_autoreplace=*/false, - /*created_by_policy=*/ - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider)); + /*policy_origin=*/ + TemplateURLData::PolicyOrigin::kDefaultSearchProvider)); { auto play_api_engine = CreateTestTemplateURL( @@ -969,7 +968,7 @@ syncer::SyncChange::ACTION_ADD, CreateTestTemplateURL(u"keyword1", "http://aaa.com", std::string(), base::Time::FromTimeT(100), true, - TemplateURLData::CreatedByPolicy::kNoPolicy, 0))); + TemplateURLData::PolicyOrigin::kNoPolicy, 0))); changes.push_back(CreateTestSyncChange( syncer::SyncChange::ACTION_ADD, CreateTestTemplateURL(u"keyword2", "http://bbb.com"))); @@ -1248,7 +1247,7 @@ data.safe_for_autoreplace = false; data.date_created = Time::FromTimeT(100); data.last_modified = Time::FromTimeT(100); - data.created_by_policy = TemplateURLData::CreatedByPolicy::kNoPolicy; + data.policy_origin = TemplateURLData::PolicyOrigin::kNoPolicy; data.prepopulate_id = 999999; data.sync_guid = "guid2"; std::unique_ptr<TemplateURL> turl2(new TemplateURL(data)); @@ -1326,7 +1325,7 @@ data.safe_for_autoreplace = false; data.date_created = Time::FromTimeT(100); data.last_modified = Time::FromTimeT(100); - data.created_by_policy = TemplateURLData::CreatedByPolicy::kNoPolicy; + data.policy_origin = TemplateURLData::PolicyOrigin::kNoPolicy; data.prepopulate_id = 999999; data.sync_guid = "guid2"; std::unique_ptr<TemplateURL> turl2(new TemplateURL(data)); @@ -2587,7 +2586,7 @@ std::unique_ptr<TemplateURL> turl( CreateTestTemplateURL(u"what", "http://thewhat.com/{searchTerms}", "normal_guid", base::Time::FromTimeT(10), true, - TemplateURLData::CreatedByPolicy::kNoPolicy, 0)); + TemplateURLData::PolicyOrigin::kNoPolicy, 0)); initial_data.push_back( TemplateURLService::CreateSyncDataFromTemplateURL(*turl));
diff --git a/chrome/browser/search_engines/template_url_service_test_util.cc b/chrome/browser/search_engines/template_url_service_test_util.cc index d14bc52e..3a3b3801 100644 --- a/chrome/browser/search_engines/template_url_service_test_util.cc +++ b/chrome/browser/search_engines/template_url_service_test_util.cc
@@ -105,7 +105,7 @@ const std::string& guid, base::Time last_modified, bool safe_for_autoreplace, - TemplateURLData::CreatedByPolicy created_by_policy, + TemplateURLData::PolicyOrigin policy_origin, int prepopulate_id) { DCHECK(!base::StartsWith(guid, "key")) << "Don't use test GUIDs with the form \"key1\". Use \"guid1\" instead " @@ -119,7 +119,7 @@ data.safe_for_autoreplace = safe_for_autoreplace; data.date_created = base::Time::FromTimeT(100); data.last_modified = last_modified; - data.created_by_policy = created_by_policy; + data.policy_origin = policy_origin; data.prepopulate_id = prepopulate_id; if (!guid.empty()) { data.sync_guid = guid;
diff --git a/chrome/browser/search_engines/template_url_service_test_util.h b/chrome/browser/search_engines/template_url_service_test_util.h index 3815c08..2caa5bc9 100644 --- a/chrome/browser/search_engines/template_url_service_test_util.h +++ b/chrome/browser/search_engines/template_url_service_test_util.h
@@ -52,8 +52,8 @@ const std::string& guid = std::string(), base::Time last_modified = base::Time::FromTimeT(100), bool safe_for_autoreplace = false, - TemplateURLData::CreatedByPolicy created_by_policy = - TemplateURLData::CreatedByPolicy::kNoPolicy, + TemplateURLData::PolicyOrigin policy_origin = + TemplateURLData::PolicyOrigin::kNoPolicy, int prepopulate_id = 999999); class TemplateURLServiceTestUtil : public TemplateURLServiceObserver {
diff --git a/chrome/browser/search_engines/template_url_service_unittest.cc b/chrome/browser/search_engines/template_url_service_unittest.cc index 63a019f..87e5b960 100644 --- a/chrome/browser/search_engines/template_url_service_unittest.cc +++ b/chrome/browser/search_engines/template_url_service_unittest.cc
@@ -2626,23 +2626,22 @@ struct EnterpriseSearchTestParam { bool choice_enabled; - TemplateURLData::CreatedByPolicy created_by_policy; + TemplateURLData::PolicyOrigin policy_origin; }; static std::string EnterpriseSearchTestParamToTestSuffix( const ::testing::TestParamInfo<EnterpriseSearchTestParam>& info) { // Note: ensures this only runs for site search and search aggregator // policies. - CHECK(info.param.created_by_policy == - TemplateURLData::CreatedByPolicy::kSiteSearch || - info.param.created_by_policy == - TemplateURLData::CreatedByPolicy::kSearchAggregator); + CHECK(info.param.policy_origin == + TemplateURLData::PolicyOrigin::kSiteSearch || + info.param.policy_origin == + TemplateURLData::PolicyOrigin::kSearchAggregator); return base::StringPrintf( "%s_%s", info.param.choice_enabled ? "SearchEngineChoiceEnabled" : "SearchEngineChoiceDisabled", - info.param.created_by_policy == - TemplateURLData::CreatedByPolicy::kSiteSearch + info.param.policy_origin == TemplateURLData::PolicyOrigin::kSiteSearch ? "SiteSearch" : "SearchAggregator"); } @@ -2653,7 +2652,7 @@ public: TemplateURLServiceEnterpriseSearchTest() : TemplateURLServiceTestBase(GetParam().choice_enabled), - created_by_policy_(GetParam().created_by_policy) { + policy_origin_(GetParam().policy_origin) { EXPECT_EQ( IsSearchEngineChoiceEnabled(), base::FeatureList::IsEnabled(switches::kSearchEngineChoiceTrigger)); @@ -2670,7 +2669,7 @@ data->SetShortName(base::UTF8ToUTF16(keyword + "name")); data->SetKeyword(base::UTF8ToUTF16(keyword)); data->SetURL(std::string("https://") + keyword + ".com/q={searchTerms}"); - data->created_by_policy = created_by_policy_; + data->policy_origin = policy_origin_; data->enforced_by_policy = false; data->featured_by_policy = featured_by_policy; data->is_active = TemplateURLData::ActiveStatus::kTrue; @@ -2690,7 +2689,7 @@ return CreateEnterpriseSearchEntry(keyword, /*featured_by_policy=*/false); } - TemplateURLData::CreatedByPolicy created_by_policy_; + TemplateURLData::PolicyOrigin policy_origin_; }; INSTANTIATE_TEST_SUITE_P( @@ -2699,18 +2698,16 @@ ::testing::Values( EnterpriseSearchTestParam{ .choice_enabled = false, - .created_by_policy = TemplateURLData::CreatedByPolicy::kSiteSearch}, + .policy_origin = TemplateURLData::PolicyOrigin::kSiteSearch}, EnterpriseSearchTestParam{ .choice_enabled = false, - .created_by_policy = - TemplateURLData::CreatedByPolicy::kSearchAggregator}, + .policy_origin = TemplateURLData::PolicyOrigin::kSearchAggregator}, EnterpriseSearchTestParam{ .choice_enabled = true, - .created_by_policy = TemplateURLData::CreatedByPolicy::kSiteSearch}, + .policy_origin = TemplateURLData::PolicyOrigin::kSiteSearch}, EnterpriseSearchTestParam{ .choice_enabled = true, - .created_by_policy = - TemplateURLData::CreatedByPolicy::kSearchAggregator}), + .policy_origin = TemplateURLData::PolicyOrigin::kSearchAggregator}), &EnterpriseSearchTestParamToTestSuffix); TEST_P(TemplateURLServiceEnterpriseSearchTest,
diff --git a/chrome/browser/sessions/session_data_deleter.cc b/chrome/browser/sessions/session_data_deleter.cc index 0293b2c..81a37a4f4 100644 --- a/chrome/browser/sessions/session_data_deleter.cc +++ b/chrome/browser/sessions/session_data_deleter.cc
@@ -8,7 +8,6 @@ #include <stdint.h> #include "base/command_line.h" -#include "base/feature_list.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/memory/ref_counted.h" @@ -30,15 +29,12 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_usage_info.h" -#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "mojo/public/cpp/bindings/remote.h" #include "net/cookies/cookie_util.h" -#include "services/network/public/cpp/features.h" #include "services/network/public/mojom/cookie_manager.mojom.h" #include "services/network/public/mojom/network_context.mojom.h" #include "storage/browser/quota/special_storage_policy.h" -#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/storage_key/storage_key.h" namespace { @@ -153,11 +149,9 @@ cookie_manager_->DeleteSessionOnlyCookies( base::BindOnce(&SessionDataDeleterInternal::OnCookieDeletionDone, this)); - if (base::FeatureList::IsEnabled(network::features::kPrivateStateTokens)) { - storage_partition->GetNetworkContext()->ClearTrustTokenSessionOnlyData( - base::BindOnce(&SessionDataDeleterInternal::OnTrustTokenDeletionDone, - this)); - } + storage_partition->GetNetworkContext()->ClearTrustTokenSessionOnlyData( + base::BindOnce(&SessionDataDeleterInternal::OnTrustTokenDeletionDone, + this)); // Note that from this point on |*this| is kept alive by scoped_refptr<> // references automatically taken by |Bind()|, so when the last callback
diff --git a/chrome/browser/speech/speech_recognition_client_browser_interface.cc b/chrome/browser/speech/speech_recognition_client_browser_interface.cc index 3bd63c1..ced8c2f0 100644 --- a/chrome/browser/speech/speech_recognition_client_browser_interface.cc +++ b/chrome/browser/speech/speech_recognition_client_browser_interface.cc
@@ -8,12 +8,7 @@ #include "base/feature_list.h" #include "base/functional/bind.h" -#include "base/unguessable_token.h" -#include "build/build_config.h" -#include "chrome/browser/accessibility/live_caption/live_caption_controller_factory.h" #include "chrome/browser/profiles/profile.h" -#include "components/live_caption/live_caption_controller.h" -#include "components/live_caption/live_caption_ui_remote_driver.h" #include "components/live_caption/pref_names.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" @@ -29,7 +24,6 @@ SpeechRecognitionClientBrowserInterface(content::BrowserContext* context) { Profile* profile = Profile::FromBrowserContext(context); profile_prefs_ = profile->GetPrefs(); - controller_ = captions::LiveCaptionControllerFactory::GetForProfile(profile); pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>(); pref_change_registrar_->Init(profile_prefs_); @@ -50,7 +44,7 @@ base::BindRepeating(&SpeechRecognitionClientBrowserInterface:: OnSpeechRecognitionMaskOffensiveWordsChanged, base::Unretained(this))); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) pref_change_registrar_->Add( prefs::kUserMicrophoneCaptionLanguageCode, base::BindRepeating( @@ -79,7 +73,11 @@ OnLiveCaptionAvailabilityChanged(); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +void SpeechRecognitionClientBrowserInterface::REMOVED_1() { + NOTREACHED(); +} + +#if BUILDFLAG(IS_CHROMEOS) void SpeechRecognitionClientBrowserInterface:: BindBabelOrcaSpeechRecognitionBrowserObserver( mojo::PendingRemote<media::mojom::SpeechRecognitionBrowserObserver> @@ -95,22 +93,6 @@ } #endif -void SpeechRecognitionClientBrowserInterface::BindRecognizerToRemoteClient( - mojo::PendingReceiver<media::mojom::SpeechRecognitionRecognizerClient> - client_receiver, - mojo::PendingReceiver<media::mojom::SpeechRecognitionSurfaceClient> - surface_client_receiver, - mojo::PendingRemote<media::mojom::SpeechRecognitionSurface> surface_remote, - media::mojom::SpeechRecognitionSurfaceMetadataPtr metadata) { -#if BUILDFLAG(IS_CHROMEOS_ASH) - ui_drivers_.Add( - std::make_unique<captions::LiveCaptionUiRemoteDriver>( - controller_, std::move(surface_client_receiver), - std::move(surface_remote), metadata->session_id.ToString()), - std::move(client_receiver)); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) -} - void SpeechRecognitionClientBrowserInterface::OnSodaInstalled( speech::LanguageCode language_code) { if (waiting_on_live_caption_ && @@ -120,13 +102,13 @@ profile_prefs_->GetBoolean(prefs::kLiveCaptionEnabled)); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) if (waiting_on_babel_orca_ && prefs::IsLanguageCodeForMicrophoneCaption( language_code, profile_prefs_)) { waiting_on_babel_orca_ = false; NotifyBabelOrcaCaptionObservers(babel_orca_enabled_); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } void SpeechRecognitionClientBrowserInterface:: @@ -178,7 +160,7 @@ } } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void SpeechRecognitionClientBrowserInterface::OnBabelOrcaAvailabilityChanged( bool enabled) { if (babel_orca_availability_observers_.empty()) { @@ -217,5 +199,5 @@ observer->SpeechRecognitionAvailabilityChanged(enabled); } } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } // namespace speech
diff --git a/chrome/browser/speech/speech_recognition_client_browser_interface.h b/chrome/browser/speech/speech_recognition_client_browser_interface.h index 89237e8..3d9ba4a9 100644 --- a/chrome/browser/speech/speech_recognition_client_browser_interface.h +++ b/chrome/browser/speech/speech_recognition_client_browser_interface.h
@@ -12,15 +12,10 @@ #include "media/mojo/mojom/speech_recognition.mojom.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote_set.h" -#include "mojo/public/cpp/bindings/unique_receiver_set.h" class PrefChangeRegistrar; class PrefService; -namespace captions { -class LiveCaptionController; -} // namespace captions - namespace content { class BrowserContext; } // namespace content @@ -48,16 +43,10 @@ void BindSpeechRecognitionBrowserObserver( mojo::PendingRemote<media::mojom::SpeechRecognitionBrowserObserver> pending_remote) override; - void BindRecognizerToRemoteClient( - mojo::PendingReceiver<media::mojom::SpeechRecognitionRecognizerClient> - client_receiver, - mojo::PendingReceiver<media::mojom::SpeechRecognitionSurfaceClient> - host_receiver, - mojo::PendingRemote<media::mojom::SpeechRecognitionSurface> origin_remote, - media::mojom::SpeechRecognitionSurfaceMetadataPtr metadata) override; + void REMOVED_1() override; - // BabelOrca feature methods are ash only. -#if BUILDFLAG(IS_CHROMEOS_ASH) + // BabelOrca feature methods are chromeos only. +#if BUILDFLAG(IS_CHROMEOS) void BindBabelOrcaSpeechRecognitionBrowserObserver( mojo::PendingRemote<media::mojom::SpeechRecognitionBrowserObserver> pending_remote) override; @@ -100,12 +89,8 @@ mojo::ReceiverSet<media::mojom::SpeechRecognitionClientBrowserInterface> speech_recognition_client_browser_interface_; - mojo::UniqueReceiverSet<media::mojom::SpeechRecognitionRecognizerClient> - ui_drivers_; - std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; raw_ptr<PrefService> profile_prefs_; - raw_ptr<captions::LiveCaptionController> controller_; }; } // namespace speech
diff --git a/chrome/browser/status_icons/status_icon.cc b/chrome/browser/status_icons/status_icon.cc index 50667438..cee36cb 100644 --- a/chrome/browser/status_icons/status_icon.cc +++ b/chrome/browser/status_icons/status_icon.cc
@@ -42,6 +42,11 @@ void StatusIcon::ForceVisible() {} +#if BUILDFLAG(IS_MAC) +void StatusIcon::SetOpenMenuWithSecondaryClick( + bool open_menu_with_secondary_click) {} +#endif + void StatusIcon::SetContextMenu(std::unique_ptr<StatusIconMenuModel> menu) { // The UI may been showing a menu for the current model, don't destroy it // until we've notified the UI of the change.
diff --git a/chrome/browser/status_icons/status_icon.h b/chrome/browser/status_icons/status_icon.h index 54811bb1..f72e8a4 100644 --- a/chrome/browser/status_icons/status_icon.h +++ b/chrome/browser/status_icons/status_icon.h
@@ -75,6 +75,14 @@ // thread to do it. Use sparingly. virtual void ForceVisible(); +#if BUILDFLAG(IS_MAC) + // On mac, if there is a menu, by default primary click will open it and not + // call DispatchClickEvent(). Use this function to make the menu open on + // secondary click, and dispatch the click event on left click. + virtual void SetOpenMenuWithSecondaryClick( + bool open_menu_with_secondary_click); +#endif + protected: // Invoked after a call to SetContextMenu() to let the platform-specific // subclass update the native context menu based on the new model. If NULL is
diff --git a/chrome/browser/storage_access_api/api_browsertest.cc b/chrome/browser/storage_access_api/api_browsertest.cc index e6e74f04..38b17cd 100644 --- a/chrome/browser/storage_access_api/api_browsertest.cc +++ b/chrome/browser/storage_access_api/api_browsertest.cc
@@ -96,16 +96,16 @@ namespace { -constexpr char kHostA[] = "a.test"; -constexpr char kOriginA[] = "https://a.test"; -constexpr char kOriginB[] = "https://b.test"; -constexpr char kUrlA[] = "https://a.test/random.path"; -constexpr char kHostASubdomain[] = "subdomain.a.test"; -constexpr char kHostB[] = "b.test"; -constexpr char kHostBSubdomain[] = "subdomain.b.test"; -constexpr char kHostBSubdomain2[] = "subdomain2.b.test"; -constexpr char kHostC[] = "c.test"; -constexpr char kHostD[] = "d.test"; +constexpr std::string_view kHostA = "a.test"; +constexpr std::string_view kOriginA = "https://a.test"; +constexpr std::string_view kOriginB = "https://b.test"; +constexpr std::string_view kUrlA = "https://a.test/random.path"; +constexpr std::string_view kHostASubdomain = "subdomain.a.test"; +constexpr std::string_view kHostB = "b.test"; +constexpr std::string_view kHostBSubdomain = "subdomain.b.test"; +constexpr std::string_view kHostBSubdomain2 = "subdomain2.b.test"; +constexpr std::string_view kHostC = "c.test"; +constexpr std::string_view kHostD = "d.test"; constexpr char kUseCounterHistogram[] = "Blink.UseCounter.Features"; constexpr char kRequestOutcomeHistogram[] = "API.StorageAccess.RequestOutcome"; @@ -127,17 +127,17 @@ enum class TestType { kFrame, kWorker }; // Helpers to express expected -std::pair<std::string, std::string> CookieBundle(const std::string& cookies) { +std::pair<std::string, std::string> CookieBundle(std::string_view cookies) { DCHECK_NE(cookies, "None"); DCHECK_NE(cookies, ""); - return {cookies, cookies}; + return {std::string(cookies), std::string(cookies)}; } std::tuple<std::string, std::string, std::string> CookieBundleWithContent( - const std::string& cookies) { + std::string_view cookies) { DCHECK_NE(cookies, "None"); DCHECK_NE(cookies, ""); - return {cookies, cookies, cookies}; + return {std::string(cookies), std::string(cookies), std::string(cookies)}; } constexpr std::pair<const char*, const char*> kNoCookies = @@ -355,7 +355,7 @@ void TearDownOnMainThread() override { prompt_factory_.reset(); } - void SetCrossSiteCookieOnDomain(const std::string& domain) { + void SetCrossSiteCookieOnDomain(std::string_view domain) { GURL domain_url = GetURL(domain); std::string cookie = base::StrCat({"cross-site=", domain}); ASSERT_TRUE( @@ -365,8 +365,8 @@ testing::HasSubstr(cookie)); } - void SetPartitionedCookieInContext(const std::string& top_level_host, - const std::string& embedded_host) { + void SetPartitionedCookieInContext(std::string_view top_level_host, + std::string_view embedded_host) { GURL host_url = GetURL(embedded_host); std::string cookie = base::StrCat({"cross-site=", embedded_host, "(partitioned)"}); @@ -385,7 +385,7 @@ testing::HasSubstr(cookie)); } - void BlockAllCookiesOnHost(const std::string& host) { + void BlockAllCookiesOnHost(std::string_view host) { CookieSettingsFactory::GetForProfile(browser()->profile()) ->SetCookieSetting(GetURL(host), ContentSetting::CONTENT_SETTING_BLOCK); } @@ -404,39 +404,39 @@ : content_settings::CookieControlsMode::kOff)); } - void NavigateToPage(const std::string& host, const std::string& path) { + void NavigateToPage(std::string_view host, std::string_view path) { GURL main_url(https_server_.GetURL(host, path)); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url)); } - void NavigateToPageWithFrame(const std::string& host, + void NavigateToPageWithFrame(std::string_view host, Browser* browser_ptr = nullptr) { GURL main_url(https_server_.GetURL(host, "/iframe.html")); ASSERT_TRUE(ui_test_utils::NavigateToURL( browser_ptr ? browser_ptr : browser(), main_url)); } - void NavigateToNewTabWithFrame(const std::string& host) { + void NavigateToNewTabWithFrame(std::string_view host) { GURL main_url(https_server_.GetURL(host, "/iframe.html")); ui_test_utils::NavigateToURLWithDisposition( browser(), main_url, WindowOpenDisposition::NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); } - void NavigateFrameTo(const std::string& host, const std::string& path) { + void NavigateFrameTo(std::string_view host, std::string_view path) { NavigateFrameTo(https_server_.GetURL(host, path)); } void NavigateFrameTo(const GURL& url, Browser* browser_ptr = nullptr, - const std::string& iframe_id = "test") { + std::string_view iframe_id = "test") { content::WebContents* web_contents = (browser_ptr ? browser_ptr : browser()) ->tab_strip_model() ->GetActiveWebContents(); EXPECT_TRUE(NavigateIframeToURL(web_contents, iframe_id, url)); } - void NavigateNestedFrameTo(const std::string& host, const std::string& path) { + void NavigateNestedFrameTo(std::string_view host, std::string_view path) { NavigateNestedFrameTo(https_server_.GetURL(host, path)); } @@ -454,7 +454,7 @@ load_observer.Wait(); } - void NavigateToPageWithTwoFrames(const std::string& host) { + void NavigateToPageWithTwoFrames(std::string_view host) { GURL main_url(https_server_.GetURL(host, "/two_iframes_blank.html")); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url)); } @@ -471,11 +471,11 @@ EXPECT_TRUE(NavigateIframeToURL(web_contents, "iframe2", url)); } - GURL EchoCookiesURL(const std::string& host) { + GURL EchoCookiesURL(std::string_view host) { return https_server().GetURL(host, "/echoheader?cookie"); } - GURL RedirectViaHosts(const std::vector<std::string>& hosts, + GURL RedirectViaHosts(const std::vector<std::string_view>& hosts, const GURL& destination) { GURL url = destination; @@ -508,7 +508,7 @@ // consistent. std::pair<std::string, std::string> ReadCookies( content::RenderFrameHost* render_frame_host, - const std::string& subresource_host) { + std::string_view subresource_host) { return { content::EvalJs(render_frame_host, "document.cookie", content::EXECUTE_SCRIPT_NO_USER_GESTURE) @@ -525,7 +525,7 @@ // (via `document.cookie`) are consistent with each other. std::tuple<std::string, std::string, std::string> ReadCookiesAndContent( content::RenderFrameHost* render_frame_host, - const std::string& subresource_host) { + std::string_view subresource_host) { auto [js_cookies, subresource_cookies] = ReadCookies(render_frame_host, subresource_host); return { @@ -2379,7 +2379,7 @@ : public StorageAccessAPIBaseBrowserTest, public testing::WithParamInterface< /* (origin, content_setting, is_storage_partitioned) */ - std::tuple<const char*, ContentSetting, bool>> { + std::tuple<std::string_view, ContentSetting, bool>> { public: std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { return GetEnabledFeaturesForStorage(IsStoragePartitioned()); @@ -2415,7 +2415,7 @@ // Derive a test name from parameter information. static std::string TestName(const ::testing::TestParamInfo<ParamType>& info) { - const char* origin = std::get<0>(info.param); + std::string_view origin = std::get<0>(info.param); ContentSetting content_setting = std::get<1>(info.param); bool is_storage_partitioned = std::get<2>(info.param); return base::JoinString( @@ -2436,7 +2436,7 @@ private: ContentSetting GetContentSetting() const { return std::get<1>(GetParam()); } - const char* GetContentOrigin() const { return std::get<0>(GetParam()); } + std::string_view GetContentOrigin() const { return std::get<0>(GetParam()); } bool IsStoragePartitioned() const { return std::get<2>(GetParam()); } };
diff --git a/chrome/browser/sync/test/integration/single_client_offer_sync_test.cc b/chrome/browser/sync/test/integration/single_client_offer_sync_test.cc index f3375a8..e3403429 100644 --- a/chrome/browser/sync/test/integration/single_client_offer_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_offer_sync_test.cc
@@ -143,7 +143,7 @@ // Make sure the data is in the DB. autofill::PersonalDataManager* pdm = GetPersonalDataManager(0); ASSERT_NE(nullptr, pdm); - std::vector<AutofillOfferData*> offers = + std::vector<const AutofillOfferData*> offers = pdm->payments_data_manager().GetAutofillOffers(); ASSERT_EQ(1uL, offers.size()); EXPECT_EQ(999, offers[0]->GetOfferId()); @@ -170,7 +170,7 @@ // Make sure the card is in the DB. autofill::PersonalDataManager* pdm = GetPersonalDataManager(0); ASSERT_NE(nullptr, pdm); - std::vector<AutofillOfferData*> offers = + std::vector<const AutofillOfferData*> offers = pdm->payments_data_manager().GetAutofillOffers(); ASSERT_EQ(1uL, offers.size()); EXPECT_EQ(999, offers[0]->GetOfferId()); @@ -212,7 +212,7 @@ // Make sure the card is in the DB. autofill::PersonalDataManager* pdm = GetPersonalDataManager(0); ASSERT_NE(nullptr, pdm); - std::vector<AutofillOfferData*> offers = + std::vector<const AutofillOfferData*> offers = pdm->payments_data_manager().GetAutofillOffers(); ASSERT_EQ(1uL, offers.size()); EXPECT_EQ(999, offers[0]->GetOfferId());
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 6fb7ea25..56976d7 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -202,10 +202,6 @@ "webui/gcm_internals_ui.h", "webui/history_clusters/history_clusters_internals_ui_config.cc", "webui/history_clusters/history_clusters_internals_ui_config.h", - "webui/internal_debug_pages_disabled/internal_debug_pages_disabled_ui.cc", - "webui/internal_debug_pages_disabled/internal_debug_pages_disabled_ui.h", - "webui/internal_webui_config.cc", - "webui/internal_webui_config.h", "webui/interstitials/interstitial_ui.cc", "webui/interstitials/interstitial_ui.h", "webui/local_state/local_state_ui.cc", @@ -426,6 +422,7 @@ "//chrome/browser/ui/tab_contents", "//chrome/browser/ui/tab_contents:impl", "//chrome/browser/ui/webui", + "//chrome/browser/ui/webui:internal_webui_config", "//chrome/browser/ui/webui:webui_util", "//chrome/browser/ui/webui/bluetooth_internals", "//chrome/browser/ui/zoom",
diff --git a/chrome/browser/ui/android/device_lock/java/res/layout/device_lock_view.xml b/chrome/browser/ui/android/device_lock/java/res/layout/device_lock_view.xml index e1a200e..084de81 100644 --- a/chrome/browser/ui/android/device_lock/java/res/layout/device_lock_view.xml +++ b/chrome/browser/ui/android/device_lock/java/res/layout/device_lock_view.xml
@@ -54,6 +54,7 @@ android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" + android:gravity="center" android:text="@string/device_lock_title" android:textAppearance="@style/TextAppearance.Headline.Primary" /> @@ -65,9 +66,21 @@ android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" + android:gravity="center" android:text="@string/device_lock_description" android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> + <TextView + android:id="@+id/device_lock_notice" + android:layout_below="@id/device_lock_description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="20dp" + android:padding="16dp" + android:gravity="center" + android:text="@string/device_lock_notice" + android:textAppearance="@style/TextAppearance.TextMedium.Primary" /> + <FrameLayout android:id="@+id/device_lock_notice_container" android:layout_below="@id/device_lock_description" @@ -79,7 +92,7 @@ android:background="@drawable/rounded_corner_card"> <org.chromium.components.browser_ui.widget.text.TextViewWithCompoundDrawables - android:id="@+id/device_lock_notice" + android:id="@+id/device_lock_notice_legacy" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="start|center_vertical"
diff --git a/chrome/browser/ui/android/device_lock/java/res/layout/missing_device_lock_view.xml b/chrome/browser/ui/android/device_lock/java/res/layout/missing_device_lock_view.xml index 99a685f..fbd9d0a2 100644 --- a/chrome/browser/ui/android/device_lock/java/res/layout/missing_device_lock_view.xml +++ b/chrome/browser/ui/android/device_lock/java/res/layout/missing_device_lock_view.xml
@@ -47,6 +47,7 @@ android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" + android:gravity="center" android:text="@string/missing_device_lock_title" android:textAppearance="@style/TextAppearance.Headline.Primary" /> @@ -58,6 +59,7 @@ android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" + android:gravity="center" android:text="@string/missing_device_lock_description" android:textAppearance="@style/TextAppearance.TextMedium.Primary" />
diff --git a/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockView.java b/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockView.java index ad31667..84890d1f 100644 --- a/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockView.java +++ b/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockView.java
@@ -7,6 +7,7 @@ import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; +import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.LinearLayout; @@ -16,6 +17,8 @@ import org.chromium.components.browser_ui.widget.DualControlLayout.ButtonType; import org.chromium.components.browser_ui.widget.MaterialProgressBar; import org.chromium.components.browser_ui.widget.text.TextViewWithCompoundDrawables; +import org.chromium.components.signin.SigninFeatureMap; +import org.chromium.components.signin.SigninFeatures; /** * View that displays the device lock page to users and prompts them to create one if none are @@ -25,7 +28,8 @@ private MaterialProgressBar mProgressBar; private TextView mTitle; private TextView mDescription; - private TextViewWithCompoundDrawables mNoticeText; + private TextView mNoticeText; + private TextViewWithCompoundDrawables mNoticeTextLegacy; private DualControlLayout mButtonBar; private Button mContinueButton; private Button mDismissButton; @@ -49,6 +53,15 @@ mProgressBar.setIndeterminate(true); mDescription = findViewById(R.id.device_lock_description); mNoticeText = findViewById(R.id.device_lock_notice); + mNoticeTextLegacy = findViewById(R.id.device_lock_notice_legacy); + + if (SigninFeatureMap.isEnabled(SigninFeatures.UNO_FOR_AUTO)) { + findViewById(R.id.device_lock_notice_container).setVisibility(View.GONE); + mNoticeText.setVisibility(View.VISIBLE); + } else { + findViewById(R.id.device_lock_notice_container).setVisibility(View.VISIBLE); + mNoticeText.setVisibility(View.GONE); + } mDismissButton = DualControlLayout.createButtonForLayout( @@ -82,8 +95,10 @@ return mDescription; } - TextViewWithCompoundDrawables getNoticeText() { - return mNoticeText; + TextView getNoticeText() { + return SigninFeatureMap.isEnabled(SigninFeatures.UNO_FOR_AUTO) + ? mNoticeText + : mNoticeTextLegacy; } TextView getContinueButton() {
diff --git a/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockViewBinder.java b/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockViewBinder.java index fa46e34..11a9c343 100644 --- a/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockViewBinder.java +++ b/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockViewBinder.java
@@ -13,6 +13,9 @@ import org.chromium.components.browser_ui.device_lock.DeviceLockActivityLauncher; import org.chromium.components.browser_ui.device_lock.DeviceLockDialogMetrics; import org.chromium.components.browser_ui.device_lock.DeviceLockDialogMetrics.DeviceLockDialogAction; +import org.chromium.components.browser_ui.widget.text.TextViewWithCompoundDrawables; +import org.chromium.components.signin.SigninFeatureMap; +import org.chromium.components.signin.SigninFeatures; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; @@ -83,7 +86,11 @@ model.get(DeviceLockProperties.ON_USER_UNDERSTANDS_CLICKED)); return; } - view.getContinueButton().setText(R.string.device_lock_create_lock_button); + if (SigninFeatureMap.isEnabled(SigninFeatures.UNO_FOR_AUTO)) { + view.getContinueButton().setText(R.string.history_sync_primary_action); + } else { + view.getContinueButton().setText(R.string.device_lock_create_lock_button); + } if (model.get(DeviceLockProperties.DEVICE_SUPPORTS_PIN_CREATION_INTENT)) { view.getContinueButton() .setOnClickListener( @@ -101,11 +108,13 @@ view.getTitle().setTextAppearance(R.style.TextAppearance_Headline_Primary); view.getDescription().setTextAppearance(R.style.TextAppearance_TextMedium_Primary); view.getNoticeText().setTextAppearance(R.style.TextAppearance_TextMedium_Primary); - view.getNoticeText() - .setDrawableTintColor( - AppCompatResources.getColorStateList( - view.getContext(), - R.color.default_icon_color_accent1_tint_list)); + if (!SigninFeatureMap.isEnabled(SigninFeatures.UNO_FOR_AUTO)) { + ((TextViewWithCompoundDrawables) view.getNoticeText()) + .setDrawableTintColor( + AppCompatResources.getColorStateList( + view.getContext(), + R.color.default_icon_color_accent1_tint_list)); + } view.getContinueButton().setEnabled(true); view.getDismissButton().setEnabled(true); } else { @@ -113,10 +122,13 @@ view.getTitle().setTextAppearance(R.style.TextAppearance_Headline_Disabled); view.getDescription().setTextAppearance(R.style.TextAppearance_TextMedium_Disabled); view.getNoticeText().setTextAppearance(R.style.TextAppearance_TextMedium_Disabled); - view.getNoticeText() - .setDrawableTintColor( - AppCompatResources.getColorStateList( - view.getContext(), R.color.default_text_color_disabled_list)); + if (!SigninFeatureMap.isEnabled(SigninFeatures.UNO_FOR_AUTO)) { + ((TextViewWithCompoundDrawables) view.getNoticeText()) + .setDrawableTintColor( + AppCompatResources.getColorStateList( + view.getContext(), + R.color.default_text_color_disabled_list)); + } view.getContinueButton().setEnabled(false); view.getDismissButton().setEnabled(false); } @@ -130,7 +142,11 @@ .setOnClickListener( model.get(DeviceLockProperties.ON_USE_WITHOUT_AN_ACCOUNT_CLICKED)); } else { - view.getDismissButton().setText(R.string.dialog_not_now); + if (SigninFeatureMap.isEnabled(SigninFeatures.UNO_FOR_AUTO)) { + view.getDismissButton().setText(R.string.history_sync_secondary_action); + } else { + view.getDismissButton().setText(R.string.dialog_not_now); + } view.getDismissButton() .setOnClickListener(model.get(DeviceLockProperties.ON_DISMISS_CLICKED)); }
diff --git a/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinatorTest.java b/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinatorTest.java index 281c7130..467556e 100644 --- a/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinatorTest.java +++ b/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockCoordinatorTest.java
@@ -27,14 +27,17 @@ import org.chromium.base.test.BaseActivityTestRule; import org.chromium.base.test.util.ApplicationTestUtils; import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.Features; import org.chromium.chrome.browser.device_reauth.ReauthenticatorBridge; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.components.browser_ui.device_lock.DeviceLockActivityLauncher; +import org.chromium.components.signin.SigninFeatures; import org.chromium.ui.test.util.BlankUiTestActivity; /** Tests for {@link DeviceLockCoordinator}. */ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.UNIT_TESTS) +@Features.EnableFeatures(SigninFeatures.UNO_FOR_AUTO) public class DeviceLockCoordinatorTest { @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
diff --git a/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockViewBinderTest.java b/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockViewBinderTest.java index 63db8b11..386ed44a 100644 --- a/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockViewBinderTest.java +++ b/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockViewBinderTest.java
@@ -37,11 +37,13 @@ import org.chromium.base.test.BaseActivityTestRule; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.DisabledTest; +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.flags.ChromeFeatureList; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.components.browser_ui.device_lock.DeviceLockActivityLauncher; +import org.chromium.components.signin.SigninFeatures; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; import org.chromium.ui.test.util.BlankUiTestActivity; @@ -51,6 +53,7 @@ /** Tests for {@link DeviceLockViewBinder}. */ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.UNIT_TESTS) +@Features.EnableFeatures(SigninFeatures.UNO_FOR_AUTO) public class DeviceLockViewBinderTest { @ClassRule public static BaseActivityTestRule<BlankUiTestActivity> sActivityTestRule = @@ -168,7 +171,7 @@ mView.getNoticeText().getText()); assertEquals( "The continue button should match the version for creating a device lock.", - sActivity.getResources().getString(R.string.device_lock_create_lock_button), + sActivity.getResources().getString(R.string.history_sync_primary_action), mView.getContinueButton().getText()); assertEquals( "The continue button should always be visible.", @@ -227,14 +230,15 @@ @Test @UiThreadTest @SmallTest - public void testDeviceLockView_inSignInFlowWithNoPreExistingLock_dismissButtonHasNotNowText() { + public void + testDeviceLockView_inSignInFlowWithNoPreExistingLock_dismissButtonHasNoThanksText() { mViewModel.set(SOURCE, DeviceLockActivityLauncher.Source.SYNC_CONSENT); mViewModel.set(PREEXISTING_DEVICE_LOCK, false); assertEquals( "The dismiss button should show 'not now' text when in the sign in flow.", mView.getDismissButton().getText(), - sActivity.getResources().getString(R.string.dialog_not_now)); + sActivity.getResources().getString(R.string.history_sync_secondary_action)); } @Test
diff --git a/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockCoordinatorTest.java b/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockCoordinatorTest.java index 4269d0b..de13a57 100644 --- a/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockCoordinatorTest.java +++ b/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockCoordinatorTest.java
@@ -30,8 +30,10 @@ import org.chromium.base.test.BaseActivityTestRule; import org.chromium.base.test.util.ApplicationTestUtils; import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.Features; import org.chromium.base.test.util.HistogramWatcher; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.components.signin.SigninFeatures; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; import org.chromium.ui.test.util.BlankUiTestActivity; @@ -42,6 +44,7 @@ /** Tests for {@link MissingDeviceLockCoordinator}. */ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.UNIT_TESTS) +@Features.EnableFeatures(SigninFeatures.UNO_FOR_AUTO) public class MissingDeviceLockCoordinatorTest { @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
diff --git a/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockViewBinderTest.java b/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockViewBinderTest.java index c0029f9..e56ac15 100644 --- a/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockViewBinderTest.java +++ b/chrome/browser/ui/android/device_lock/javatests/src/org/chromium/chrome/browser/ui/device_lock/MissingDeviceLockViewBinderTest.java
@@ -28,7 +28,9 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseActivityTestRule; import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.Features; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.components.signin.SigninFeatures; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; import org.chromium.ui.test.util.BlankUiTestActivity; @@ -38,6 +40,7 @@ /** Tests for {@link MissingDeviceLockViewBinder}. */ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.UNIT_TESTS) +@Features.EnableFeatures(SigninFeatures.UNO_FOR_AUTO) public class MissingDeviceLockViewBinderTest { @ClassRule public static BaseActivityTestRule<BlankUiTestActivity> sActivityTestRule =
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/signin_promo/NtpSigninPromoDelegate.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/signin_promo/NtpSigninPromoDelegate.java index c6f39e7b..470c374c76 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/signin_promo/NtpSigninPromoDelegate.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/signin_promo/NtpSigninPromoDelegate.java
@@ -30,6 +30,7 @@ // 14 days in hours. @VisibleForTesting static final int NTP_SYNC_PROMO_NTP_SINCE_FIRST_TIME_SHOWN_LIMIT_HOURS = 336; @VisibleForTesting static final int NTP_SYNC_PROMO_RESET_AFTER_DAYS = 30; + private static final int NTP_SYNC_PROMO_INCREASE_SHOW_COUNT_AFTER_MINUTES = 30; /** * If the signin promo card has been hidden for longer than the {@link @@ -116,6 +117,22 @@ @Override void recordImpression() { + final long currentTime = System.currentTimeMillis(); + final long lastShownTime = + ChromeSharedPreferences.getInstance() + .readLong(ChromePreferenceKeys.SIGNIN_PROMO_NTP_LAST_SHOWN_TIME, 0L); + if (currentTime - lastShownTime + < NTP_SYNC_PROMO_INCREASE_SHOW_COUNT_AFTER_MINUTES * DateUtils.MINUTE_IN_MILLIS) { + return; + } + if (ChromeSharedPreferences.getInstance() + .readLong(ChromePreferenceKeys.SIGNIN_PROMO_NTP_FIRST_SHOWN_TIME) + == 0) { + ChromeSharedPreferences.getInstance() + .writeLong(ChromePreferenceKeys.SIGNIN_PROMO_NTP_FIRST_SHOWN_TIME, currentTime); + } + ChromeSharedPreferences.getInstance() + .writeLong(ChromePreferenceKeys.SIGNIN_PROMO_NTP_LAST_SHOWN_TIME, currentTime); ChromeSharedPreferences.getInstance().incrementInt(getPromoShowCountPreferenceName()); }
diff --git a/chrome/browser/ui/ash/web_view/BUILD.gn b/chrome/browser/ui/ash/web_view/BUILD.gn index 05491b1a..304e0e8 100644 --- a/chrome/browser/ui/ash/web_view/BUILD.gn +++ b/chrome/browser/ui/ash/web_view/BUILD.gn
@@ -21,7 +21,6 @@ "//base", "//chrome/browser/media/webrtc", "//chrome/browser/profiles:profile", - "//chrome/browser/ui/ash/new_window:new_window", "//content/public/browser", "//ui/aura", "//ui/base",
diff --git a/chrome/browser/ui/ash/web_view/DEPS b/chrome/browser/ui/ash/web_view/DEPS index 61a7308..f1f4dbc8 100644 --- a/chrome/browser/ui/ash/web_view/DEPS +++ b/chrome/browser/ui/ash/web_view/DEPS
@@ -12,12 +12,5 @@ # Whenever possible, avoid adding new //chrome dependencies to this list. "+chrome/browser/media/webrtc", "+chrome/browser/profiles", - "+chrome/browser/ui/ash/new_window", "+chrome/test", ] - -specific_include_rules = { - "ash_web_view_impl_browsertest.cc": [ - "+chrome/browser/ui/browser.h" - ] -}
diff --git a/chrome/browser/ui/ash/web_view/ash_web_view_impl.cc b/chrome/browser/ui/ash/web_view/ash_web_view_impl.cc index 44be635..05fa4a72 100644 --- a/chrome/browser/ui/ash/web_view/ash_web_view_impl.cc +++ b/chrome/browser/ui/ash/web_view/ash_web_view_impl.cc
@@ -4,13 +4,11 @@ #include "chrome/browser/ui/ash/web_view/ash_web_view_impl.h" -#include "ash/public/cpp/new_window_delegate.h" #include "ash/public/cpp/window_properties.h" #include "base/task/sequenced_task_runner.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/ash/new_window/chrome_new_window_client.h" #include "content/public/browser/focused_node_details.h" #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/media_session.h" @@ -147,24 +145,6 @@ source, params, std::move(navigation_handle_callback)); } -void AshWebViewImpl::ActivateContents(content::WebContents* contents) { - // In cases where the widget is not activatable, an `activation_url` may be - // provided to show instead. - // This is currently used for Focus Mode YTM for when the user clicks on the - // media controls view. Since the media window is a custom hidden window, a - // separately provided URL tab (navigating to `activation_url`) is shown when - // the hidden media window is activated. - if (!GetWidget()->CanActivate() && !params_.activation_url.is_empty()) { - ChromeNewWindowClient::Get()->OpenUrl( - params_.activation_url, - ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction, - ash::NewWindowDelegate::Disposition::kSwitchToTab); - return; - } - - content::WebContentsDelegate::ActivateContents(contents); -} - void AshWebViewImpl::ResizeDueToAutoResize(content::WebContents* web_contents, const gfx::Size& new_size) { DCHECK_EQ(web_contents_.get(), web_contents);
diff --git a/chrome/browser/ui/ash/web_view/ash_web_view_impl.h b/chrome/browser/ui/ash/web_view/ash_web_view_impl.h index 4fd8dff1..b078a4a 100644 --- a/chrome/browser/ui/ash/web_view/ash_web_view_impl.h +++ b/chrome/browser/ui/ash/web_view/ash_web_view_impl.h
@@ -66,7 +66,6 @@ const content::OpenURLParams& params, base::OnceCallback<void(content::NavigationHandle&)> navigation_handle_callback) override; - void ActivateContents(content::WebContents* contents) override; void ResizeDueToAutoResize(content::WebContents* web_contents, const gfx::Size& new_size) override; bool TakeFocus(content::WebContents* web_contents, bool reverse) override;
diff --git a/chrome/browser/ui/ash/web_view/ash_web_view_impl_browsertest.cc b/chrome/browser/ui/ash/web_view/ash_web_view_impl_browsertest.cc index 5e53e5d..d9d93dbdd 100644 --- a/chrome/browser/ui/ash/web_view/ash_web_view_impl_browsertest.cc +++ b/chrome/browser/ui/ash/web_view/ash_web_view_impl_browsertest.cc
@@ -12,13 +12,11 @@ #include "base/run_loop.h" #include "base/scoped_observation.h" #include "base/strings/stringprintf.h" -#include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/test/browser_test.h" -#include "content/public/test/test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/view.h" @@ -99,16 +97,12 @@ // Helpers --------------------------------------------------------------------- -std::unique_ptr<views::Widget> CreateWidget(bool activatable = true) { +std::unique_ptr<views::Widget> CreateWidget() { auto widget = std::make_unique<views::Widget>(); views::Widget::InitParams params( views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET, views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); - params.activatable = activatable - ? views::Widget::InitParams::Activatable::kDefault - : views::Widget::InitParams::Activatable::kNo; - widget->Init(std::move(params)); return widget; } @@ -316,33 +310,3 @@ EXPECT_DOUBLE_EQ( 1.0, content::HostZoomMap::GetZoomLevel(web_view_impl->web_contents())); } - -// Tests that AshWebViewImpl will open a browser window if the AshWebView is -// activated (while the widget is not activatable) and provided an -// `activation_url`. -IN_PROC_BROWSER_TEST_F(AshWebViewImplBrowserTest, ShouldOpenNewWindow) { - auto widget = CreateWidget(/*activatable=*/false); - AshWebView::InitParams init_params; - const GURL destination_url("https://www.google.com"); - init_params.activation_url = destination_url; - - AshWebView* web_view = - widget->SetContentsView(AshWebViewFactory::Get()->Create(init_params)); - AshWebViewImpl* web_view_impl = static_cast<AshWebViewImpl*>(web_view); - - web_view->Navigate(CreateDataUrl()); - EXPECT_DID_STOP_LOADING(web_view); - - content::WebContents* web_contents = web_view_impl->web_contents(); - web_contents->GetDelegate()->ActivateContents(web_contents); - - // Wait for the browser tab to load. - content::RunAllTasksUntilIdle(); - - // Verify that the browser was launched with the correct url as the active - // tab. - ASSERT_TRUE(browser()); - EXPECT_EQ( - destination_url, - browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL()); -}
diff --git a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc index d6ec96b..0da2387 100644 --- a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc +++ b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc
@@ -21,18 +21,13 @@ using bookmarks::BookmarkModel; using bookmarks::BookmarkNode; -namespace { - -// Max number of most recently used folders. -const size_t kMaxMRUFolders = 5; - -} // namespace - struct RecentlyUsedFoldersComboModel::Item { enum Type { TYPE_NODE, TYPE_ALL_BOOKMARKS_NODE, TYPE_SEPARATOR, + TYPE_ACCOUNT_BOOKMARK_HEADING, + TYPE_DEVICE_BOOKMARK_HEADING, TYPE_CHOOSE_ANOTHER_FOLDER }; @@ -62,34 +57,41 @@ const BookmarkNode* node) : bookmark_model_(model), parent_node_(node->parent()) { bookmark_model_->AddObserver(this); - // Use + 2 to account for bookmark bar and other node. - std::vector<const BookmarkNode*> nodes = - bookmarks::GetMostRecentlyModifiedUserFolders(model, kMaxMRUFolders + 2); - for (size_t i = 0; i < nodes.size(); ++i) - items_.push_back(Item(nodes[i], Item::TYPE_NODE)); + const bookmarks::RecentlyUsedFolders mru_bookmarks = + bookmarks::GetMostRecentlyUsedFoldersForDisplay(model, node); - // We special case the placement of these, so remove them from the list, then - // fix up the order. - RemoveNode(model->bookmark_bar_node()); - RemoveNode(model->mobile_node()); - RemoveNode(model->other_node()); - RemoveNode(node->parent()); + if (!mru_bookmarks.account_nodes.empty()) { + const bool show_labels = !mru_bookmarks.local_nodes.empty(); - // Make the parent the first item, unless it's a permanent node, which is - // added below. - if (!model->is_permanent_node(node->parent())) - items_.insert(items_.begin(), Item(node->parent(), Item::TYPE_NODE)); + // Add account nodes to `items_`. + if (show_labels) { + items_.emplace_back(nullptr, Item::TYPE_ACCOUNT_BOOKMARK_HEADING); + } - // Make sure we only have kMaxMRUFolders in the first chunk. - if (items_.size() > kMaxMRUFolders) - items_.erase(items_.begin() + kMaxMRUFolders, items_.end()); + for (const BookmarkNode* mru_node : mru_bookmarks.account_nodes) { + items_.emplace_back(mru_node, mru_node == model->other_node() + ? Item::TYPE_ALL_BOOKMARKS_NODE + : Item::TYPE_NODE); + } - // And put the bookmark bar and other nodes at the end of the list. - items_.emplace_back(model->bookmark_bar_node(), Item::TYPE_NODE); - items_.emplace_back(model->other_node(), Item::TYPE_ALL_BOOKMARKS_NODE); - if (model->mobile_node()->IsVisible()) - items_.emplace_back(model->mobile_node(), Item::TYPE_NODE); + // Add local nodes to `items_`. + if (show_labels) { + items_.emplace_back(nullptr, Item::TYPE_DEVICE_BOOKMARK_HEADING); + } + + for (const BookmarkNode* mru_node : mru_bookmarks.local_nodes) { + items_.emplace_back(mru_node, mru_node == model->other_node() + ? Item::TYPE_ALL_BOOKMARKS_NODE + : Item::TYPE_NODE); + } + } else { + for (const BookmarkNode* mru_node : mru_bookmarks.local_nodes) { + items_.emplace_back(mru_node, Item::TYPE_NODE); + } + } + + // Add a separator + choose another folder last regardless of account/local. items_.emplace_back(nullptr, Item::TYPE_SEPARATOR); items_.emplace_back(nullptr, Item::TYPE_CHOOSE_ANOTHER_FOLDER); } @@ -106,6 +108,10 @@ switch (items_[index].type) { case Item::TYPE_NODE: return items_[index].node->GetTitle(); + case Item::TYPE_ACCOUNT_BOOKMARK_HEADING: + return l10n_util::GetStringUTF16(IDS_BOOKMARKS_ACCOUNT_BOOKMARKS); + case Item::TYPE_DEVICE_BOOKMARK_HEADING: + return l10n_util::GetStringUTF16(IDS_BOOKMARKS_DEVICE_BOOKMARKS); case Item::TYPE_ALL_BOOKMARKS_NODE: return l10n_util::GetStringUTF16(IDS_BOOKMARKS_ALL_BOOKMARKS); case Item::TYPE_SEPARATOR: @@ -122,6 +128,20 @@ return items_[index].type == Item::TYPE_SEPARATOR; } +bool RecentlyUsedFoldersComboModel::IsItemTitleAt(size_t index) const { + switch (items_[index].type) { + case Item::TYPE_ACCOUNT_BOOKMARK_HEADING: + case Item::TYPE_DEVICE_BOOKMARK_HEADING: + return true; + case Item::TYPE_NODE: + case Item::TYPE_SEPARATOR: + case Item::TYPE_ALL_BOOKMARKS_NODE: + case Item::TYPE_CHOOSE_ANOTHER_FOLDER: + return false; + } + NOTREACHED(); +} + std::optional<size_t> RecentlyUsedFoldersComboModel::GetDefaultIndex() const { // TODO(pbos): Ideally we shouldn't have to handle `parent_node_` removal // here, the dialog should instead close immediately (and destroy `this`).
diff --git a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h index dc2aa2d..7d5b611f 100644 --- a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h +++ b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h
@@ -37,6 +37,7 @@ size_t GetItemCount() const override; std::u16string GetItemAt(size_t index) const override; bool IsItemSeparatorAt(size_t index) const override; + bool IsItemTitleAt(size_t index) const override; std::optional<size_t> GetDefaultIndex() const override; // Overridden from bookmarks::BookmarkModelObserver:
diff --git a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h index 51eedd9..dce7ea8 100644 --- a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h +++ b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h
@@ -12,6 +12,7 @@ #include "base/gtest_prod_util.h" #include "chrome/browser/status_icons/desktop_notification_balloon.h" #include "chrome/browser/status_icons/status_icon.h" +#include "chrome/browser/status_icons/status_tray.h" @class MenuControllerCocoa; @class NSStatusItem; @@ -33,9 +34,21 @@ const std::u16string& title, const std::u16string& contents, const message_center::NotifierId& notifier_id) override; + void SetOpenMenuWithSecondaryClick( + bool open_menu_with_secondary_click) override; bool HasStatusIconMenu(); + // When open_menu_with_secondary_click_ is true, do not set the status item's + // menu, so that left click will not open a menu. When a secondary click is + // detected, this function is called which creates and sets the menu on the + // status item, simulates a click, and then unsets the menu afterwards. + void CreateAndOpenMenu(); + + bool open_menu_with_secondary_click() { + return open_menu_with_secondary_click_; + } + protected: // Overridden from StatusIcon. void UpdatePlatformContextMenu(StatusIconMenuModel* model) override; @@ -43,6 +56,7 @@ private: FRIEND_TEST_ALL_PREFIXES(StatusIconMacTest, CreateMenu); FRIEND_TEST_ALL_PREFIXES(StatusIconMacTest, MenuToolTip); + FRIEND_TEST_ALL_PREFIXES(StatusIconMacTest, SecondaryClickMenuNoToolTip); void SetToolTip(NSString* tool_tip); void CreateMenu(ui::MenuModel* model, NSString* tool_tip); @@ -61,6 +75,18 @@ // Status menu shown when right-clicking the system icon, if it has been // created by |UpdatePlatformContextMenu|. MenuControllerCocoa* __strong menu_; + + // Boolean which determines whether the menu should be opened with secondary + // clicks. When true, left click will dispatch a click event even if a menu + // exists, and right click/control-click will open the menu. Additionally, the + // tooltip will be shown when hovering the status icon and not as an entry in + // the menu. + bool open_menu_with_secondary_click_ = false; + + // Stores the menu model so that it can be created later in + // CreateAndOpenMenu(). Only used when open_menu_with_secondary_click_ is + // true. + raw_ptr<ui::MenuModel> menu_model_ = nullptr; }; -#endif // CHROME_BROWSER_UI_COCOA_STATUS_ICONS_STATUS_ICON_MAC_H_ +#endif // CHROME_BROWSER_UI_COCOA_STATUS_ICONS_STATUS_ICON_MAC_H_
diff --git a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm index e33f89b..f01c4df 100644 --- a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm +++ b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm
@@ -10,6 +10,7 @@ #include "base/mac/mac_util.h" #include "base/memory/raw_ptr.h" #include "base/strings/sys_string_conversions.h" +#include "chrome/browser/status_icons/status_tray.h" #include "skia/ext/skia_utils_mac.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/image/image_skia.h" @@ -32,12 +33,24 @@ } - (void)handleClick:(id)sender { - // Pass along the click notification to our owner. DCHECK(_statusIcon); + // Bring up the status icon menu if there is one, relay the click event // otherwise. - if (!_statusIcon->HasStatusIconMenu()) + if (!_statusIcon->HasStatusIconMenu()) { _statusIcon->DispatchClickEvent(); + } else if (_statusIcon->open_menu_with_secondary_click()) { + NSEvent* event = [NSApp currentEvent]; + BOOL secondary_click = + ([event type] == NSEventTypeLeftMouseDown && + [event modifierFlags] & NSEventModifierFlagControl) || + ([event type] == NSEventTypeRightMouseUp); + if (secondary_click) { + _statusIcon->CreateAndOpenMenu(); + } else if ([event type] == NSEventTypeLeftMouseDown) { + _statusIcon->DispatchClickEvent(); + } + } } @end @@ -82,7 +95,7 @@ // If we have a status icon menu, make the tool tip part of the menu instead // of a pop-up tool tip when hovering the mouse over the image. tool_tip_ = base::SysUTF16ToNSString(tool_tip); - if (menu_) { + if (menu_ && !open_menu_with_secondary_click_) { SetToolTip(nil); CreateMenu([menu_ model], tool_tip_); } else { @@ -99,13 +112,29 @@ contents, notifier_id); } +void StatusIconMac::SetOpenMenuWithSecondaryClick( + bool open_menu_with_secondary_click) { + open_menu_with_secondary_click_ = open_menu_with_secondary_click; + [[item() button] + sendActionOn:(NSEventMaskLeftMouseDown | NSEventMaskRightMouseUp)]; +} + bool StatusIconMac::HasStatusIconMenu() { - return menu_ != nil; + return open_menu_with_secondary_click_ ? menu_model_ : menu_ != nil; +} + +void StatusIconMac::CreateAndOpenMenu() { + CreateMenu(menu_model_, nil); + [[item() button] performClick:nil]; + [item() setMenu:nil]; } void StatusIconMac::UpdatePlatformContextMenu(StatusIconMenuModel* model) { if (!model) { menu_ = nil; + } else if (open_menu_with_secondary_click_) { + SetToolTip(tool_tip_); + menu_model_ = model; } else { SetToolTip(nil); CreateMenu(model, tool_tip_);
diff --git a/chrome/browser/ui/cocoa/status_icons/status_icon_mac_unittest.mm b/chrome/browser/ui/cocoa/status_icons/status_icon_mac_unittest.mm index 7e57328..91cb254 100644 --- a/chrome/browser/ui/cocoa/status_icons/status_icon_mac_unittest.mm +++ b/chrome/browser/ui/cocoa/status_icons/status_icon_mac_unittest.mm
@@ -15,6 +15,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" #include "ui/base/resource/resource_bundle.h" +#import "ui/menus/cocoa/menu_controller.h" class SkBitmap; @@ -63,3 +64,21 @@ NSMenuItem* menu_item = [icon->item().menu itemAtIndex:1]; EXPECT_NSEQ(base::SysUTF16ToNSString(menu_title), menu_item.title); } + +TEST_F(StatusIconMacTest, SecondaryClickMenuNoToolTip) { + // Create a status item with a secondary click menu and set a tool tip. Verify + // the tool tip is not inserted as the first menu item. + const char16_t menu_title[] = u"Menu Title"; + const char16_t tool_tip[] = u"Tool tip"; + std::unique_ptr<StatusIconMenuModel> model = + std::make_unique<StatusIconMenuModel>(nullptr); + model->AddItem(0, menu_title); + + std::unique_ptr<StatusIconMac> icon = std::make_unique<StatusIconMac>(); + icon->SetToolTip(tool_tip); + icon->SetOpenMenuWithSecondaryClick(true); + icon->SetContextMenu(std::move(model)); + EXPECT_EQ(0, icon->menu_.menu.numberOfItems); + + EXPECT_NSEQ(base::SysUTF16ToNSString(tool_tip), icon->item().button.toolTip); +}
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h index dff71d0..5b990c9 100644 --- a/chrome/browser/ui/color/chrome_color_id.h +++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -588,9 +588,6 @@ /* Share-this-tab dialog colors. */ \ E_CPONLY(kColorShareThisTabAudioToggleBackground) \ E_CPONLY(kColorShareThisTabSourceViewBorder) \ - /* Experimentation */ \ - E_CPONLY(kColorShoppingPageActionIconBackgroundVariant) \ - E_CPONLY(kColorShoppingPageActionIconForegroundVariant) \ /* Side panel colors. */ \ E_CPONLY(kColorSidePanelBackground) \ E_CPONLY(kColorSidePanelBadgeBackground) \
diff --git a/chrome/browser/ui/color/chrome_color_mixer.cc b/chrome/browser/ui/color/chrome_color_mixer.cc index 806c7b7..cc02478 100644 --- a/chrome/browser/ui/color/chrome_color_mixer.cc +++ b/chrome/browser/ui/color/chrome_color_mixer.cc
@@ -385,10 +385,6 @@ mixer[kColorShareThisTabAudioToggleBackground] = { ui::kColorSubtleEmphasisBackground}; mixer[kColorShareThisTabSourceViewBorder] = {ui::kColorMidground}; - mixer[kColorShoppingPageActionIconBackgroundVariant] = { - ui::kColorSysSecondary}; - mixer[kColorShoppingPageActionIconForegroundVariant] = { - ui::kColorSysOnSecondary}; mixer[kColorSidePanelBackground] = {kColorToolbar}; mixer[kColorSidePanelContentAreaSeparator] = {ui::kColorSeparator}; mixer[kColorSidePanelComboboxEntryIcon] = {ui::kColorIcon};
diff --git a/chrome/browser/ui/lens/lens_overlay_live_test.cc b/chrome/browser/ui/lens/lens_overlay_live_test.cc index 9847be4..f09661fa 100644 --- a/chrome/browser/ui/lens/lens_overlay_live_test.cc +++ b/chrome/browser/ui/lens/lens_overlay_live_test.cc
@@ -102,24 +102,6 @@ findAndClickDivWithClass(document.body); )"; -constexpr char kFindDivWithClassScript[] = R"( - function kFindDivWithClassScript(parentElement) { - const div = parentElement.querySelector('div.' + $1); - if (div) { - return true; - } - for (const child of parentElement.children) { - if (kFindDivWithClassScript(child) || - (child.shadowRoot && - kFindDivWithClassScript(child.shadowRoot))) { - return true; - } - } - return false; - } - kFindDivWithClassScript(document.body); -)"; - // Helper script to fetch an element with a certain ID and click on it. constexpr char kFindAndClickElementWithIDScript[] = R"( function findAndClickElementWithID(root, id) { @@ -146,11 +128,6 @@ findAndClickElementWithID(document, $1); )"; -// Wait for an animation frame as it takes one to wait for the translated lines -// to render properly. -constexpr char kWaitForAnimationFrame[] = - "() => new Promise(resolve => requestAnimationFrame(() => resolve(true)))"; - const char kNpsUrl[] = "https://www.nps.gov/articles/route-66-overview.htm"; const char kNpsObjectUrl[] = "https://www.nps.gov/common/commonspot/templates/images/graphics/404/" @@ -159,7 +136,7 @@ "https://www.nps.gov/subjects/historicpreservationfund/en-espanol.htm"; } // namespace -// Live tests for Companion. +// Live tests for Lens Overlay. // These tests can be run with: // browser_tests --gtest_filter=LensOverlayLiveTest.* --run-live-tests class LensOverlayLiveTest : public signin::test::LiveTest { @@ -310,37 +287,6 @@ ".*source=chrome.cr.menu.*&gsc=2&hl=.*&biw=\\d+&bih=\\d+")); } - void ClickTranslateButtonAndThenText() { - // Find and click the translate enable button when it appears on the - // overlay. - ASSERT_TRUE(base::test::RunUntil([&]() { - return EvalJs(content::JsReplace(kFindAndClickElementWithIDScript, - kTranslateEnableButtonID)) - .ExtractBool(); - })); - - // After, wait for the translated lines to appear. - ASSERT_TRUE(base::test::RunUntil([&]() { - return EvalJs(content::JsReplace(kFindDivWithClassScript, - kDivTranslatedLineClass)) - .ExtractBool(); - })); - - // The translated lines render and then need one animation frame in order - // for the overlay to compute their bounding boxes for highlighted lines. If - // the overlay does not wait for this computation, then an assertion error - // will be thrown. - ASSERT_TRUE(content::ExecJs(GetOverlayWebContents()->GetPrimaryMainFrame(), - kWaitForAnimationFrame)); - - // Click on the translated line. - ASSERT_TRUE(base::test::RunUntil([&]() { - return EvalJs(content::JsReplace(kFindAndClickDivWithClassScript, - kDivTranslatedLineClass)) - .ExtractBool(); - })); - } - virtual void SetUpFeatureList() { feature_list_.InitAndEnableFeatureWithParameters( lens::features::kLensOverlay, @@ -603,10 +549,45 @@ VerifySidePanelLoaded(); } -IN_PROC_BROWSER_TEST_F(LensOverlayLiveTest, TranslateScreen_SignedInAndSynced) { - base::test::ScopedFeatureList features; - features.InitAndEnableFeature(lens::features::kLensOverlayTranslateButton); +// Live tests for LensOverlayTranslateButton. +class LensOverlayTranslateLiveTest : public LensOverlayLiveTest { + public: + void ClickTranslateButtonAndThenText() { + // Find and click the translate enable button when it appears on the + // overlay. + ASSERT_TRUE(base::test::RunUntil([&]() { + return EvalJs(content::JsReplace(kFindAndClickElementWithIDScript, + kTranslateEnableButtonID)) + .ExtractBool(); + })); + // The translated lines render and need some time in order + // for the overlay to compute their bounding boxes for highlighted lines. + // For this reason, keep clicking on the line until the side panel actually + // opens. + auto* controller = browser() + ->tab_strip_model() + ->GetActiveTab() + ->GetTabFeatures() + ->lens_overlay_controller(); + ASSERT_TRUE(base::test::RunUntil([&]() { + EvalJs(content::JsReplace(kFindAndClickDivWithClassScript, + kDivTranslatedLineClass)); + return controller->state() == State::kOverlayAndResults; + })); + } + + void SetUpFeatureList() override { + feature_list_.InitWithFeaturesAndParameters( + {{lens::features::kLensOverlay, + {{"enable-shimmer", "false"}, {"use-blur", "false"}}}, + {features::kLensOverlayTranslateButton, {}}}, + {}); + } +}; + +IN_PROC_BROWSER_TEST_F(LensOverlayTranslateLiveTest, + TranslateScreen_SignedInAndSynced) { std::optional<signin::TestAccountSigninCredentials> test_account = GetTestAccounts()->GetAccount("INTELLIGENCE_ACCOUNT"); // Sign in and sync to opted in test account. @@ -646,10 +627,8 @@ VerifySidePanelLoaded(); } -IN_PROC_BROWSER_TEST_F(LensOverlayLiveTest, TranslateScreen_SignedInNotSynced) { - base::test::ScopedFeatureList features; - features.InitAndEnableFeature(lens::features::kLensOverlayTranslateButton); - +IN_PROC_BROWSER_TEST_F(LensOverlayTranslateLiveTest, + TranslateScreen_SignedInNotSynced) { std::optional<signin::TestAccountSigninCredentials> test_account = GetTestAccounts()->GetAccount("INTELLIGENCE_ACCOUNT"); // Sign in but do not sync to opted in test account. @@ -689,10 +668,8 @@ VerifySidePanelLoaded(); } -IN_PROC_BROWSER_TEST_F(LensOverlayLiveTest, TranslateScreen_SignedOut) { - base::test::ScopedFeatureList features; - features.InitAndEnableFeature(lens::features::kLensOverlayTranslateButton); - +IN_PROC_BROWSER_TEST_F(LensOverlayTranslateLiveTest, + TranslateScreen_SignedOut) { // Navigate to a website and wait for paint before starting controller. WaitForPaint(kNpsTranslateUrl); EXPECT_TRUE(content::WaitForLoadStop(web_contents())); @@ -713,7 +690,7 @@ ASSERT_EQ(side_panel_coordinator()->GetCurrentEntryId(), std::nullopt); ASSERT_TRUE(content::WaitForLoadStop(GetOverlayWebContents())); - // Confirm that the WebUI has reported that it is ready. This means the local + // Confirm that the WebUI has reported that i1t is ready. This means the local // DOM should be initialized on our WebUI. WaitForHistogram("Lens.Overlay.TimeToWebUIReady");
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc index 1131948..587db02 100644 --- a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc +++ b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc
@@ -108,8 +108,8 @@ TemplateURLData policy_turl; policy_turl.SetKeyword(policy_search_keyword()); - policy_turl.created_by_policy = - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider; + policy_turl.policy_origin = + TemplateURLData::PolicyOrigin::kDefaultSearchProvider; factory_util.model()->Add(std::make_unique<TemplateURL>(policy_turl)); TemplateURLData starter_pack_turl;
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc index b8e656f..69fbb9a 100644 --- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc +++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -1492,8 +1492,8 @@ TemplateURLServiceFactory::GetForProfile(browser()->profile()) ->GetTemplateURLForKeyword(kSiteSearchPolicyKeyword); ASSERT_TRUE(turl); - EXPECT_EQ(turl->created_by_policy(), - TemplateURLData::CreatedByPolicy::kSiteSearch); + EXPECT_EQ(turl->policy_origin(), + TemplateURLData::PolicyOrigin::kSiteSearch); EXPECT_EQ(turl->short_name(), kSiteSearchPolicyName); EXPECT_EQ(turl->url(), kSiteSearchPolicyURL); EXPECT_FALSE(turl->featured_by_policy()); @@ -1538,8 +1538,8 @@ TemplateURLServiceFactory::GetForProfile(browser()->profile()) ->GetTemplateURLForKeyword(kSiteSearchPolicyKeywordWithAtPrefix); ASSERT_TRUE(turl); - EXPECT_EQ(turl->created_by_policy(), - TemplateURLData::CreatedByPolicy::kSiteSearch); + EXPECT_EQ(turl->policy_origin(), + TemplateURLData::PolicyOrigin::kSiteSearch); EXPECT_EQ(turl->short_name(), kSiteSearchPolicyName); EXPECT_EQ(turl->url(), kSiteSearchPolicyURL); EXPECT_TRUE(turl->featured_by_policy()); @@ -1587,8 +1587,8 @@ TemplateURLServiceFactory::GetForProfile(browser()->profile()) ->GetTemplateURLForKeyword(kSiteSearchPolicyKeywordWithAtPrefix); ASSERT_TRUE(turl); - EXPECT_EQ(turl->created_by_policy(), - TemplateURLData::CreatedByPolicy::kSiteSearch); + EXPECT_EQ(turl->policy_origin(), + TemplateURLData::PolicyOrigin::kSiteSearch); EXPECT_EQ(turl->short_name(), kSiteSearchPolicyName); EXPECT_EQ(turl->url(), kSiteSearchPolicyURL); EXPECT_TRUE(turl->featured_by_policy()); @@ -1659,8 +1659,8 @@ TemplateURLServiceFactory::GetForProfile(browser()->profile()) ->GetTemplateURLForKeyword(kSearchAggregatorPolicyKeyword); ASSERT_TRUE(turl); - EXPECT_EQ(turl->created_by_policy(), - TemplateURLData::CreatedByPolicy::kSearchAggregator); + EXPECT_EQ(turl->policy_origin(), + TemplateURLData::PolicyOrigin::kSearchAggregator); EXPECT_EQ(turl->short_name(), kSearchAggregatorPolicyName); EXPECT_EQ(turl->url(), kSearchAggregatorPolicySearchUrl); EXPECT_EQ(turl->suggestions_url(), kSearchAggregatorPolicySuggestUrl); @@ -1712,8 +1712,8 @@ ->GetTemplateURLForKeyword( kSearchAggregatorPolicyKeywordWithAtPrefix); ASSERT_TRUE(turl); - EXPECT_EQ(turl->created_by_policy(), - TemplateURLData::CreatedByPolicy::kSearchAggregator); + EXPECT_EQ(turl->policy_origin(), + TemplateURLData::PolicyOrigin::kSearchAggregator); EXPECT_EQ(turl->short_name(), kSearchAggregatorPolicyName); EXPECT_EQ(turl->url(), kSearchAggregatorPolicySearchUrl); EXPECT_EQ(turl->suggestions_url(), kSearchAggregatorPolicySuggestUrl); @@ -1770,8 +1770,8 @@ ->GetTemplateURLForKeyword( kSearchAggregatorPolicyKeywordWithAtPrefix); ASSERT_TRUE(turl); - EXPECT_EQ(turl->created_by_policy(), - TemplateURLData::CreatedByPolicy::kSearchAggregator); + EXPECT_EQ(turl->policy_origin(), + TemplateURLData::PolicyOrigin::kSearchAggregator); EXPECT_EQ(turl->short_name(), kSearchAggregatorPolicyName); EXPECT_EQ(turl->url(), kSearchAggregatorPolicySearchUrl); EXPECT_EQ(turl->suggestions_url(), kSearchAggregatorPolicySuggestUrl);
diff --git a/chrome/browser/ui/search_engines/keyword_editor_controller.cc b/chrome/browser/ui/search_engines/keyword_editor_controller.cc index a686767e..cacac31 100644 --- a/chrome/browser/ui/search_engines/keyword_editor_controller.cc +++ b/chrome/browser/ui/search_engines/keyword_editor_controller.cc
@@ -95,13 +95,9 @@ } bool KeywordEditorController::IsManaged(const TemplateURL* url) const { - return (url->created_by_policy() == - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider && + return (url->CreatedByDefaultSearchProviderPolicy() && url->enforced_by_policy()) || - (url->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSiteSearch) || - (url->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSearchAggregator); + url->CreatedByNonDefaultSearchProviderPolicy(); } void KeywordEditorController::RemoveTemplateURL(int index) {
diff --git a/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc b/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc index 6492848..285e51a7 100644 --- a/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc +++ b/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc
@@ -81,8 +81,8 @@ managed_engine.SetShortName(kManaged); managed_engine.SetKeyword(kManaged); managed_engine.SetURL(url); - managed_engine.created_by_policy = - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider; + managed_engine.policy_origin = + TemplateURLData::PolicyOrigin::kDefaultSearchProvider; managed_engine.enforced_by_policy = is_mandatory; is_mandatory ? SetManagedDefaultSearchPreferences(managed_engine, true, &profile_) @@ -388,12 +388,11 @@ data.SetShortName(test_case.short_name); data.is_active = test_case.is_active ? TemplateURLData::ActiveStatus::kTrue : TemplateURLData::ActiveStatus::kFalse; - data.created_by_policy = - test_case.created_by_search_aggregator_policy - ? TemplateURLData::CreatedByPolicy::kSearchAggregator - : test_case.created_by_site_search_policy - ? TemplateURLData::CreatedByPolicy::kSiteSearch - : TemplateURLData::CreatedByPolicy::kNoPolicy; + data.policy_origin = test_case.created_by_search_aggregator_policy + ? TemplateURLData::PolicyOrigin::kSearchAggregator + : test_case.created_by_site_search_policy + ? TemplateURLData::PolicyOrigin::kSiteSearch + : TemplateURLData::PolicyOrigin::kNoPolicy; data.featured_by_policy = test_case.featured_by_policy; data.safe_for_autoreplace = test_case.safe_for_autoreplace; return std::make_unique<TemplateURL>(data);
diff --git a/chrome/browser/ui/search_engines/template_url_table_model.cc b/chrome/browser/ui/search_engines/template_url_table_model.cc index f6a081d..90c7181e 100644 --- a/chrome/browser/ui/search_engines/template_url_table_model.cc +++ b/chrome/browser/ui/search_engines/template_url_table_model.cc
@@ -65,8 +65,7 @@ auto get_sort_key = [this](const TemplateURL* engine) { return std::make_tuple( // Enterprise site search engines are shown before other engines. - engine->created_by_policy() != - TemplateURLData::CreatedByPolicy::kSiteSearch, + engine->policy_origin() != TemplateURLData::PolicyOrigin::kSiteSearch, // Try to compare short names ignoring case and diacriticals. collator_ ? GetShortNameSortKey(engine->short_name()) : std::string(), // If a collator is not available, fallback to regular string
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc b/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc index eaf4e3351e..77fc25b 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc +++ b/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc
@@ -48,14 +48,11 @@ return tab_strip; } -// Returns the local tab group ID from the PersistentMessage. Asserts tab -// group metadata exists and contains the group ID. -LocalTabGroupID UnwrapTabGroupID(PersistentMessage message) { +// Returns the local tab group ID from the PersistentMessage. +std::optional<LocalTabGroupID> UnwrapTabGroupID(PersistentMessage message) { auto tab_group_metadata = message.attribution.tab_group_metadata; CHECK(tab_group_metadata.has_value()); - auto local_tab_group_id = tab_group_metadata->local_tab_group_id; - CHECK(local_tab_group_id.has_value()); - return local_tab_group_id.value(); + return tab_group_metadata->local_tab_group_id; } // Returns the tab strip index of the tab. If the sync service is not @@ -103,21 +100,30 @@ Profile* profile) { // Get tab group ID. auto local_tab_group_id = UnwrapTabGroupID(message); + if (!local_tab_group_id) { + // The LocalTabGroupID is not guaranteed to be available from the + // MessagingBackenddService, so we need to handle this case gracefully. + return std::nullopt; + } // Get tab ID. auto tab_metadata = message.attribution.tab_metadata; CHECK(tab_metadata.has_value()); auto local_tab_id = tab_metadata->local_tab_id; - CHECK(local_tab_id.has_value()); + if (!local_tab_id.has_value()) { + // The LocalTabID is not guaranteed to be available from the + // MessagingBackenddService, so we need to handle this case gracefully. + return std::nullopt; + } // Get tab index. auto tabstrip_index = - GetTabStripIndex(*local_tab_id, local_tab_group_id, profile); + GetTabStripIndex(*local_tab_id, *local_tab_group_id, profile); if (!tabstrip_index.has_value()) { return std::nullopt; } - return TabInfo(*local_tab_id, local_tab_group_id, *tabstrip_index); + return TabInfo(*local_tab_id, *local_tab_group_id, *tabstrip_index); } } // namespace @@ -127,10 +133,15 @@ MessageDisplayStatus display) { // DIRTY_TAB_GROUP notifications may not have tab metadata. Only the // group metadata is needed here. - LocalTabGroupID local_tab_group_id = UnwrapTabGroupID(message); + std::optional<LocalTabGroupID> local_tab_group_id = UnwrapTabGroupID(message); + if (!local_tab_group_id) { + // The LocalTabGroupID is not guaranteed to be available from the + // MessagingBackenddService, so we need to handle this case gracefully. + return; + } - GetTabStripWithGroup(local_tab_group_id) - ->SetTabGroupNeedsAttention(local_tab_group_id, + GetTabStripWithGroup(*local_tab_group_id) + ->SetTabGroupNeedsAttention(*local_tab_group_id, display == MessageDisplayStatus::kDisplay); }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc index fb3a58f..89784b38 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
@@ -37,15 +37,18 @@ #include "components/feature_engagement/public/feature_constants.h" #include "components/feature_engagement/test/mock_tracker.h" #include "components/signin/public/identity_manager/identity_test_utils.h" +#include "components/sync/base/features.h" #include "components/sync/test/test_sync_service.h" #include "components/ukm/test_ukm_recorder.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "ui/base/interaction/element_identifier.h" #include "ui/base/interaction/element_tracker.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" +#include "ui/views/controls/combobox/combobox.h" #include "ui/views/interaction/element_tracker_views.h" #include "ui/views/test/widget_test.h" #include "ui/views/widget/unique_widget_ptr.h" + using bookmarks::BookmarkModel; namespace { @@ -140,14 +143,17 @@ const bookmarks::BookmarkNode* GetBookmark() { return bookmark_node_; } - PriceTrackingView* GetPriceTrackingView() { + views::View* GetViewInBookmarkBubble(ui::ElementIdentifier id) { const ui::ElementContext context = views::ElementTrackerViews::GetContextForView( BookmarkBubbleView::bookmark_bubble()->GetAnchorView()); - views::View* matched_view = - views::ElementTrackerViews::GetInstance()->GetFirstMatchingView( - kPriceTrackingBookmarkViewElementId, context); + return views::ElementTrackerViews::GetInstance()->GetFirstMatchingView( + id, context); + } + PriceTrackingView* GetPriceTrackingView() { + views::View* const matched_view = + GetViewInBookmarkBubble(kPriceTrackingBookmarkViewElementId); return matched_view ? views::AsViewClass<PriceTrackingView>(matched_view) : nullptr; } @@ -416,7 +422,7 @@ const ui::ElementContext context = views::ElementTrackerViews::GetContextForView( BookmarkBubbleView::bookmark_bubble()->GetAnchorView()); - views::View* iph_root = + views::View* const iph_root = views::ElementTrackerViews::GetInstance()->GetFirstMatchingView( commerce::kShoppingCollectionIPHViewId, context); @@ -425,3 +431,29 @@ EXPECT_FALSE( BookmarkBubbleView::bookmark_bubble()->GetFootnoteViewForTesting()); } + +class BookmarkBubbleViewWithAccountBookmarksTest + : public BookmarkBubbleViewTestBase { + public: + BookmarkBubbleViewWithAccountBookmarksTest() { + test_features_.InitAndEnableFeature( + syncer::kSyncEnableBookmarksInTransportMode); + } +}; + +// Verifies that the bookmark bubble correctly instantiates a combobox that +// separates account bookmarks and local bookmarks with headers. It also +// verifies that RecentlyUsedFoldersComboModel correctly reports those as +// "title" items and that ComboboxMenuModel correctly translates that to a +// TYPE_TITLE item that can be rendered differently when the popup menu is +// displayed. +TEST_F(BookmarkBubbleViewWithAccountBookmarksTest, + ComboboxUsesTitlesForHeaders) { + GetBookmarkModel()->CreateAccountPermanentFolders(); + CreateBubbleView(); + EXPECT_EQ(ui::MenuModel::TYPE_TITLE, + views::AsViewClass<views::Combobox>( + GetViewInBookmarkBubble(kBookmarkFolderFieldId)) + ->menu_model_for_testing() + ->GetTypeAt(0)); +}
diff --git a/chrome/browser/ui/views/commerce/price_insights_icon_view.cc b/chrome/browser/ui/views/commerce/price_insights_icon_view.cc index 40fd0fa..c542e8d 100644 --- a/chrome/browser/ui/views/commerce/price_insights_icon_view.cc +++ b/chrome/browser/ui/views/commerce/price_insights_icon_view.cc
@@ -42,11 +42,6 @@ SetProperty(views::kElementIdentifierKey, kPriceInsightsChipElementId); GetViewAccessibility().SetName( l10n_util::GetStringUTF16(IDS_SHOPPING_INSIGHTS_ICON_TOOLTIP_TEXT)); - - if (base::FeatureList::IsEnabled(commerce::kShoppingIconColorVariant)) { - SetCustomForegroundColorId(kColorShoppingPageActionIconForegroundVariant); - SetCustomBackgroundColorId(kColorShoppingPageActionIconBackgroundVariant); - } } PriceInsightsIconView::~PriceInsightsIconView() = default;
diff --git a/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc b/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc index 2a3ade6..765bd9b 100644 --- a/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc +++ b/chrome/browser/ui/views/commerce/price_tracking_icon_view.cc
@@ -86,14 +86,6 @@ SetProperty(views::kElementIdentifierKey, kPriceTrackingChipElementId); GetViewAccessibility().SetName( l10n_util::GetStringUTF16(IDS_OMNIBOX_TRACK_PRICE)); - - SetUseTonalColorsWhenExpanded( - base::FeatureList::IsEnabled(commerce::kPriceTrackingIconColors)); - - if (base::FeatureList::IsEnabled(commerce::kShoppingIconColorVariant)) { - SetCustomForegroundColorId(kColorShoppingPageActionIconForegroundVariant); - SetCustomBackgroundColorId(kColorShoppingPageActionIconBackgroundVariant); - } } PriceTrackingIconView::~PriceTrackingIconView() = default;
diff --git a/chrome/browser/ui/views/glic/glic_view.cc b/chrome/browser/ui/views/glic/glic_view.cc index 36fa299..711f74a 100644 --- a/chrome/browser/ui/views/glic/glic_view.cc +++ b/chrome/browser/ui/views/glic/glic_view.cc
@@ -56,4 +56,18 @@ return {std::move(widget), raw_glic_view}; } + +void GlicView::SetDraggableAreas( + const std::vector<gfx::Rect>& draggable_areas) { + draggable_areas_.assign(draggable_areas.begin(), draggable_areas.end()); +} + +bool GlicView::IsPointWithinDraggableArea(const gfx::Point& point) { + for (const gfx::Rect& rect : draggable_areas_) { + if (rect.Contains(point)) { + return true; + } + } + return false; +} } // namespace glic
diff --git a/chrome/browser/ui/views/glic/glic_view.h b/chrome/browser/ui/views/glic/glic_view.h index 6a1d9914..0b5d9669 100644 --- a/chrome/browser/ui/views/glic/glic_view.h +++ b/chrome/browser/ui/views/glic/glic_view.h
@@ -36,10 +36,17 @@ Profile* profile, const gfx::Rect& initial_bounds); + void SetDraggableAreas(const std::vector<gfx::Rect>& draggable_areas); + + bool IsPointWithinDraggableArea(const gfx::Point& point); + views::WebView* web_view() { return web_view_; } private: raw_ptr<GlicWebView> web_view_; + // Defines the areas of the view from which it can be dragged. These areas can + // be updated by the glic web client. + std::vector<gfx::Rect> draggable_areas_; // Ensures that the profile associated with this view isn't destroyed while // it is visible.
diff --git a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc index 6250612..0cb422d4b 100644 --- a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
@@ -11,6 +11,7 @@ #include "base/functional/callback.h" #include "base/functional/callback_forward.h" #include "base/scoped_observation.h" +#include "base/strings/strcat.h" #include "base/task/thread_pool/thread_pool_instance.h" #include "base/test/bind.h" #include "base/test/metrics/user_action_tester.h" @@ -309,26 +310,21 @@ const auto* const test_info = testing::UnitTest::GetInstance()->current_test_info(); + // Verify against the Skia gold result baseline from crrev.com/c/6092068. + // TODO(crbug.com/384567062): Support set_baseline() in UiBrowserTest. + const std::string screenshot_name = base::StrCat( + {test_info->test_suite_name(), "_", test_info->name(), "_6092068"}); return VerifyPixelUi(location_bar, test_info->test_suite_name(), - test_info->name()) != ui::test::ActionResult::kFailed; + screenshot_name) != ui::test::ActionResult::kFailed; } - void WaitForUserDismissal() override { - // Consider closing the browser to be dismissal. - ui_test_utils::WaitForBrowserToClose(); - } + void WaitForUserDismissal() override {} private: base::test::ScopedFeatureList scoped_feature_list_; }; -// TODO(crbug.com/340814277): Flaky on Windows. -#if BUILDFLAG(IS_WIN) -#define MAYBE_InvokeUi_default DISABLED_InvokeUi_default -#else -#define MAYBE_InvokeUi_default InvokeUi_default -#endif -IN_PROC_BROWSER_TEST_P(IntentChipButtonBrowserUiTest, MAYBE_InvokeUi_default) { +IN_PROC_BROWSER_TEST_P(IntentChipButtonBrowserUiTest, InvokeUi_default) { ShowAndVerifyUi(); }
diff --git a/chrome/browser/ui/webauthn/sheet_models.cc b/chrome/browser/ui/webauthn/sheet_models.cc index 7897f8dd..74f6795 100644 --- a/chrome/browser/ui/webauthn/sheet_models.cc +++ b/chrome/browser/ui/webauthn/sheet_models.cc
@@ -1381,6 +1381,16 @@ RecordOnboardingEvent(webauthn::metrics::OnboardingEvents::kFailure); } webauthn::user_actions::RecordGpmFailureShown(); + switch (dialog_model->request_type) { + case device::FidoRequestType::kGetAssertion: + RecordGPMGetAssertionEvent( + webauthn::metrics::GPMGetAssertionEvents::kFailure); + break; + case device::FidoRequestType::kMakeCredential: + RecordGPMMakeCredentialEvent( + webauthn::metrics::GPMMakeCredentialEvents::kFailure); + break; + } } AuthenticatorGPMErrorSheetModel::~AuthenticatorGPMErrorSheetModel() = default;
diff --git a/chrome/browser/ui/webui/BUILD.gn b/chrome/browser/ui/webui/BUILD.gn index 73bb6d8..281c5e7 100644 --- a/chrome/browser/ui/webui/BUILD.gn +++ b/chrome/browser/ui/webui/BUILD.gn
@@ -63,6 +63,30 @@ } } +source_set("internal_webui_config") { + sources = [ + "internal_debug_pages_disabled/internal_debug_pages_disabled_ui.cc", + "internal_debug_pages_disabled/internal_debug_pages_disabled_ui.h", + "internal_webui_config.cc", + "internal_webui_config.h", + ] + + public_deps = [ "//base" ] + + deps = [ + "//chrome/app:branded_strings", + "//chrome/app:generated_resources", + "//chrome/browser:browser_process", + "//chrome/browser/profiles:profile", + "//chrome/browser/resources:dev_ui_resources", + "//chrome/common", + "//components/prefs", + "//content/public/browser", + "//content/public/common", + "//url", + ] +} + source_set("webui_util") { sources = [ "webui_util.cc",
diff --git a/chrome/browser/ui/webui/ash/scanner_feedback_dialog/scanner_feedback_dialog.cc b/chrome/browser/ui/webui/ash/scanner_feedback_dialog/scanner_feedback_dialog.cc index 650ecaf4..580541a 100644 --- a/chrome/browser/ui/webui/ash/scanner_feedback_dialog/scanner_feedback_dialog.cc +++ b/chrome/browser/ui/webui/ash/scanner_feedback_dialog/scanner_feedback_dialog.cc
@@ -4,16 +4,31 @@ #include "chrome/browser/ui/webui/ash/scanner_feedback_dialog/scanner_feedback_dialog.h" +#include <utility> +#include <variant> + +#include "ash/public/cpp/scanner/scanner_feedback_info.h" +#include "ash/webui/scanner_feedback_ui/scanner_feedback_browser_context_data.h" +#include "ash/webui/scanner_feedback_ui/scanner_feedback_page_handler.h" +#include "ash/webui/scanner_feedback_ui/scanner_feedback_untrusted_ui.h" #include "ash/webui/scanner_feedback_ui/url_constants.h" +#include "base/check.h" +#include "base/check_deref.h" +#include "base/functional/bind.h" +#include "base/functional/callback_helpers.h" #include "chrome/browser/ui/webui/ash/system_web_dialog/system_web_dialog_delegate.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui_controller.h" #include "ui/gfx/geometry/size.h" #include "url/gurl.h" namespace ash { -ScannerFeedbackDialog::ScannerFeedbackDialog() +ScannerFeedbackDialog::ScannerFeedbackDialog(ScannerFeedbackInfo info) : SystemWebDialogDelegate(GURL(kScannerFeedbackUntrustedUrl), - /*title=*/u"") { + /*title=*/u""), + feedback_info_(std::move(info)) { set_show_close_button(false); // Taken from orca-feedback.ts's `IDEAL_WIDTH` and `IDEAL_HEIGHT`. set_dialog_size(gfx::Size(/*width=*/512, /*height=*/600)); @@ -21,4 +36,43 @@ ScannerFeedbackDialog::~ScannerFeedbackDialog() = default; +void ScannerFeedbackDialog::OnDialogShown(content::WebUI* webui) { + // This is called from `ui::WebDialogUIBase::HandleRenderFrameCreated`, right + // after the `content::RenderFrameHost` is created - before any JavaScript is + // run. + SystemWebDialogDelegate::OnDialogShown(webui); + + auto* controller = + CHECK_DEREF(webui->GetController()).GetAs<ScannerFeedbackUntrustedUI>(); + + CHECK(controller); + + auto* feedback_info = std::get_if<ScannerFeedbackInfo>(&feedback_info_); + // `OnDialogShown` should never be called multiple times. If it was previously + // called, a UAF may occur after the previous dialog is closed - as that would + // destroy `this` while the new `SystemWebDialogView` is still storing a (now + // invalid) pointer to `this`. + CHECK(feedback_info); + + CHECK(webui); + content::WebContents* web_contents = webui->GetWebContents(); + CHECK(web_contents); + content::BrowserContext* browser_context = web_contents->GetBrowserContext(); + CHECK(browser_context); + + base::ScopedClosureRunner feedback_info_cleanup = + SetScannerFeedbackInfoForBrowserContext(*browser_context, + controller->page_handler().id(), + std::move(*feedback_info)); + + feedback_info_ = std::move(feedback_info_cleanup); + + ScannerFeedbackPageHandler& page_handler = controller->page_handler(); + + // This is safe to run twice, as `Widget::Close()` explicitly handles the case + // where a widget is attempted to be closed while it is already closed. + page_handler.SetCloseDialogCallback(base::BindRepeating( + &ScannerFeedbackDialog::Close, weak_ptr_factory_.GetWeakPtr())); +} + } // namespace ash
diff --git a/chrome/browser/ui/webui/ash/scanner_feedback_dialog/scanner_feedback_dialog.h b/chrome/browser/ui/webui/ash/scanner_feedback_dialog/scanner_feedback_dialog.h index d4d5d85a..63d99b8f 100644 --- a/chrome/browser/ui/webui/ash/scanner_feedback_dialog/scanner_feedback_dialog.h +++ b/chrome/browser/ui/webui/ash/scanner_feedback_dialog/scanner_feedback_dialog.h
@@ -5,8 +5,17 @@ #ifndef CHROME_BROWSER_UI_WEBUI_ASH_SCANNER_FEEDBACK_DIALOG_SCANNER_FEEDBACK_DIALOG_H_ #define CHROME_BROWSER_UI_WEBUI_ASH_SCANNER_FEEDBACK_DIALOG_SCANNER_FEEDBACK_DIALOG_H_ +#include <variant> + +#include "ash/public/cpp/scanner/scanner_feedback_info.h" +#include "base/functional/callback_helpers.h" +#include "base/memory/weak_ptr.h" #include "chrome/browser/ui/webui/ash/system_web_dialog/system_web_dialog_delegate.h" +namespace content { +class WebUI; +} + namespace ash { // Dialog delegate for the Scanner feedback form WebUI. @@ -16,12 +25,24 @@ // be destroyed when the dialog is closed. class ScannerFeedbackDialog : public SystemWebDialogDelegate { public: - ScannerFeedbackDialog(); + explicit ScannerFeedbackDialog(ScannerFeedbackInfo info); ScannerFeedbackDialog(const ScannerFeedbackDialog&) = delete; ScannerFeedbackDialog& operator=(const ScannerFeedbackDialog&) = delete; ~ScannerFeedbackDialog() override; + + // SystemWebDialogDelegate: + void OnDialogShown(content::WebUI* webui) override; + + private: + // Set to a `ScannerFeedbackInfo` on construction. + // `OnDialogShown` will move the `ScannerFeedbackInfo` into the WebUI's + // browser context, and set this to `base::ScopedClosureRunner` to clean it + // up once the dialog is closed. + std::variant<ScannerFeedbackInfo, base::ScopedClosureRunner> feedback_info_; + + base::WeakPtrFactory<ScannerFeedbackDialog> weak_ptr_factory_{this}; }; } // namespace ash
diff --git a/chrome/browser/ui/webui/ash/settings/constants/constants_util.cc b/chrome/browser/ui/webui/ash/settings/constants/constants_util.cc index 20a55b9..90a764b 100644 --- a/chrome/browser/ui/webui/ash/settings/constants/constants_util.cc +++ b/chrome/browser/ui/webui/ash/settings/constants/constants_util.cc
@@ -6,7 +6,6 @@ #include <vector> -#include "ash/constants/ash_features.h" #include "base/no_destructor.h" namespace ash::settings { @@ -39,28 +38,11 @@ return all; } -void IncludeRevampSectionsOnly(std::vector<mojom::Section>& sections) { - std::erase_if(sections, [](mojom::Section section) { - // An old Section can be filtered out once it has been fully incorporated - // into the new revamp Section. - return section == mojom::Section::kLanguagesAndInput; - }); -} - -void RemoveRevampSections(std::vector<mojom::Section>& sections) { - std::erase(sections, mojom::Section::kSystemPreferences); -} - } // namespace const std::vector<mojom::Section>& AllSections() { static const base::NoDestructor<std::vector<mojom::Section>> all_sections([] { std::vector<mojom::Section> sections = All<mojom::Section>(); - if (ash::features::IsOsSettingsRevampWayfindingEnabled()) { - IncludeRevampSectionsOnly(sections); - } else { - RemoveRevampSections(sections); - } return sections; }());
diff --git a/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc b/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc index 22485d1..9c7ab23 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc
@@ -32,7 +32,6 @@ namespace mojom { using ::chromeos::settings::mojom::kAppLanguagesSubpagePath; -using ::chromeos::settings::mojom::kLanguagesAndInputSectionPath; using ::chromeos::settings::mojom::kLanguagesSubpagePath; using ::chromeos::settings::mojom::kSystemPreferencesSectionPath; using ::chromeos::settings::mojom::Section;
diff --git a/chrome/browser/ui/webui/data_sharing_internals/data_sharing_internals_ui.cc b/chrome/browser/ui/webui/data_sharing_internals/data_sharing_internals_ui.cc index fdcd18cc..1799b5a4 100644 --- a/chrome/browser/ui/webui/data_sharing_internals/data_sharing_internals_ui.cc +++ b/chrome/browser/ui/webui/data_sharing_internals/data_sharing_internals_ui.cc
@@ -15,8 +15,7 @@ #include "content/public/browser/web_ui_data_source.h" DataSharingInternalsUIConfig::DataSharingInternalsUIConfig() - : DefaultWebUIConfig(content::kChromeUIScheme, - chrome::kChromeUIDataSharingInternalsHost) {} + : DefaultInternalWebUIConfig(chrome::kChromeUIDataSharingInternalsHost) {} DataSharingInternalsUIConfig::~DataSharingInternalsUIConfig() = default;
diff --git a/chrome/browser/ui/webui/data_sharing_internals/data_sharing_internals_ui.h b/chrome/browser/ui/webui/data_sharing_internals/data_sharing_internals_ui.h index d6af97e..f08bddc1 100644 --- a/chrome/browser/ui/webui/data_sharing_internals/data_sharing_internals_ui.h +++ b/chrome/browser/ui/webui/data_sharing_internals/data_sharing_internals_ui.h
@@ -6,16 +6,16 @@ #define CHROME_BROWSER_UI_WEBUI_DATA_SHARING_INTERNALS_DATA_SHARING_INTERNALS_UI_H_ #include "chrome/browser/ui/webui/data_sharing_internals/data_sharing_internals.mojom.h" +#include "chrome/browser/ui/webui/internal_webui_config.h" #include "components/data_sharing/public/protocol/group_data.mojom.h" #include "content/public/browser/web_ui_controller.h" -#include "content/public/browser/webui_config.h" #include "ui/webui/mojo_web_ui_controller.h" class DataSharingInternalsPageHandlerImpl; class DataSharingInternalsUI; class DataSharingInternalsUIConfig - : public content::DefaultWebUIConfig<DataSharingInternalsUI> { + : public webui::DefaultInternalWebUIConfig<DataSharingInternalsUI> { public: DataSharingInternalsUIConfig(); ~DataSharingInternalsUIConfig() override;
diff --git a/chrome/browser/ui/webui/discards/discards_ui.h b/chrome/browser/ui/webui/discards/discards_ui.h index eee3e6db..d009906 100644 --- a/chrome/browser/ui/webui/discards/discards_ui.h +++ b/chrome/browser/ui/webui/discards/discards_ui.h
@@ -9,19 +9,17 @@ #include "chrome/browser/ui/webui/discards/discards.mojom-forward.h" #include "chrome/browser/ui/webui/discards/site_data.mojom-forward.h" +#include "chrome/browser/ui/webui/internal_webui_config.h" #include "chrome/common/webui_url_constants.h" -#include "content/public/browser/webui_config.h" -#include "content/public/common/url_constants.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "ui/webui/mojo_web_ui_controller.h" class DiscardsUI; -class DiscardsUIConfig : public content::DefaultWebUIConfig<DiscardsUI> { +class DiscardsUIConfig : public webui::DefaultInternalWebUIConfig<DiscardsUI> { public: DiscardsUIConfig() - : DefaultWebUIConfig(content::kChromeUIScheme, - chrome::kChromeUIDiscardsHost) {} + : DefaultInternalWebUIConfig(chrome::kChromeUIDiscardsHost) {} }; // Controller for chrome://discards. Corresponding resources are in
diff --git a/chrome/browser/ui/webui/glic/glic.mojom b/chrome/browser/ui/webui/glic/glic.mojom index 01c2fe3..3115532 100644 --- a/chrome/browser/ui/webui/glic/glic.mojom +++ b/chrome/browser/ui/webui/glic/glic.mojom
@@ -62,6 +62,9 @@ // Set the bounds of the widget hosting the WebUI to the given size. ResizeWidget(gfx.mojom.Size size) => (gfx.mojom.Size? actual_size); + // Set the areas of the Glic panel from which it should be draggable. If + // `draggable_areas` is empty, the panel will use the top bar area by default. + SetPanelDraggableAreas(array<gfx.mojom.Rect> draggable_areas); }; // Access from the browser to the Glic web client by proxy of the WebUI page. @@ -134,4 +137,4 @@ string mime_type; // Image annotations for this screenshot. ImageOriginAnnotations origin_annotations; -}; +}; \ No newline at end of file
diff --git a/chrome/browser/ui/webui/glic/glic_page_handler.cc b/chrome/browser/ui/webui/glic/glic_page_handler.cc index af3dadfd..48f775ba 100644 --- a/chrome/browser/ui/webui/glic/glic_page_handler.cc +++ b/chrome/browser/ui/webui/glic/glic_page_handler.cc
@@ -51,6 +51,18 @@ std::move(callback).Run(actual_size); } + void SetPanelDraggableAreas( + const std::vector<gfx::Rect>& draggable_areas) override { + if (!draggable_areas.empty()) { + glic_service_->SetPanelDraggableAreas(draggable_areas); + + } else { + // Default to the top bar area of the panel. + // TODO(cuianthony): Define panel dimensions constants in shared location. + glic_service_->SetPanelDraggableAreas({{0, 0, 400, 80}}); + } + } + void GetContextFromFocusedTab( bool include_inner_text, bool include_viewport_screenshot,
diff --git a/chrome/browser/ui/webui/location_internals/location_internals_ui.h b/chrome/browser/ui/webui/location_internals/location_internals_ui.h index a03f4f5..fe7173c 100644 --- a/chrome/browser/ui/webui/location_internals/location_internals_ui.h +++ b/chrome/browser/ui/webui/location_internals/location_internals_ui.h
@@ -5,10 +5,9 @@ #ifndef CHROME_BROWSER_UI_WEBUI_LOCATION_INTERNALS_LOCATION_INTERNALS_UI_H_ #define CHROME_BROWSER_UI_WEBUI_LOCATION_INTERNALS_LOCATION_INTERNALS_UI_H_ +#include "chrome/browser/ui/webui/internal_webui_config.h" #include "chrome/browser/ui/webui/location_internals/location_internals.mojom-forward.h" #include "chrome/common/webui_url_constants.h" -#include "content/public/browser/webui_config.h" -#include "content/public/common/url_constants.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "ui/webui/mojo_web_ui_controller.h" @@ -17,11 +16,10 @@ // WebUIConfig for chrome://location-internals class LocationInternalsUIConfig - : public content::DefaultWebUIConfig<LocationInternalsUI> { + : public webui::DefaultInternalWebUIConfig<LocationInternalsUI> { public: LocationInternalsUIConfig() - : DefaultWebUIConfig(content::kChromeUIScheme, - chrome::kChromeUILocationInternalsHost) {} + : DefaultInternalWebUIConfig(chrome::kChromeUILocationInternalsHost) {} }; // The WebUI for chrome://location-internals
diff --git a/chrome/browser/ui/webui/media_router/media_router_internals_ui.h b/chrome/browser/ui/webui/media_router/media_router_internals_ui.h index 65e31aa8..94427124 100644 --- a/chrome/browser/ui/webui/media_router/media_router_internals_ui.h +++ b/chrome/browser/ui/webui/media_router/media_router_internals_ui.h
@@ -5,9 +5,9 @@ #ifndef CHROME_BROWSER_UI_WEBUI_MEDIA_ROUTER_MEDIA_ROUTER_INTERNALS_UI_H_ #define CHROME_BROWSER_UI_WEBUI_MEDIA_ROUTER_MEDIA_ROUTER_INTERNALS_UI_H_ +#include "chrome/browser/ui/webui/internal_webui_config.h" #include "chrome/common/webui_url_constants.h" #include "content/public/browser/web_ui_controller.h" -#include "content/public/browser/webui_config.h" #include "content/public/common/url_constants.h" namespace media_router { @@ -15,11 +15,10 @@ class MediaRouterInternalsUI; class MediaRouterInternalsUIConfig - : public content::DefaultWebUIConfig<MediaRouterInternalsUI> { + : public webui::DefaultInternalWebUIConfig<MediaRouterInternalsUI> { public: MediaRouterInternalsUIConfig() - : DefaultWebUIConfig(content::kChromeUIScheme, - chrome::kChromeUIMediaRouterInternalsHost) {} + : DefaultInternalWebUIConfig(chrome::kChromeUIMediaRouterInternalsHost) {} // content::WebUIConfig: bool IsWebUIEnabled(content::BrowserContext* browser_context) override;
diff --git a/chrome/browser/ui/webui/on_device_internals/on_device_internals_ui.h b/chrome/browser/ui/webui/on_device_internals/on_device_internals_ui.h index 46b6973..e76c71b 100644 --- a/chrome/browser/ui/webui/on_device_internals/on_device_internals_ui.h +++ b/chrome/browser/ui/webui/on_device_internals/on_device_internals_ui.h
@@ -6,9 +6,9 @@ #define CHROME_BROWSER_UI_WEBUI_ON_DEVICE_INTERNALS_ON_DEVICE_INTERNALS_UI_H_ #include "base/memory/weak_ptr.h" +#include "chrome/browser/ui/webui/internal_webui_config.h" #include "chrome/browser/ui/webui/on_device_internals/on_device_internals_page.mojom.h" #include "chrome/common/webui_url_constants.h" -#include "content/public/browser/webui_config.h" #include "content/public/common/url_constants.h" #include "services/on_device_model/public/mojom/on_device_model.mojom.h" #include "ui/webui/mojo_web_ui_controller.h" @@ -17,11 +17,10 @@ // WebUIConfig for chrome://on-device-internals class OnDeviceInternalsUIConfig - : public content::DefaultWebUIConfig<OnDeviceInternalsUI> { + : public webui::DefaultInternalWebUIConfig<OnDeviceInternalsUI> { public: OnDeviceInternalsUIConfig() - : DefaultWebUIConfig(content::kChromeUIScheme, - chrome::kChromeUIOnDeviceInternalsHost) {} + : DefaultInternalWebUIConfig(chrome::kChromeUIOnDeviceInternalsHost) {} // content::WebUIConfig: bool IsWebUIEnabled(content::BrowserContext* browser_context) override;
diff --git a/chrome/browser/ui/webui/profile_internals/profile_internals_ui.h b/chrome/browser/ui/webui/profile_internals/profile_internals_ui.h index dc2c775..9207a9a 100644 --- a/chrome/browser/ui/webui/profile_internals/profile_internals_ui.h +++ b/chrome/browser/ui/webui/profile_internals/profile_internals_ui.h
@@ -6,9 +6,9 @@ #define CHROME_BROWSER_UI_WEBUI_PROFILE_INTERNALS_PROFILE_INTERNALS_UI_H_ #include "build/build_config.h" +#include "chrome/browser/ui/webui/internal_webui_config.h" #include "chrome/common/webui_url_constants.h" #include "content/public/browser/web_ui_controller.h" -#include "content/public/browser/webui_config.h" #include "content/public/common/url_constants.h" #if BUILDFLAG(IS_ANDROID) @@ -20,11 +20,10 @@ class ProfileInternalsUI; class ProfileInternalsUIConfig - : public content::DefaultWebUIConfig<ProfileInternalsUI> { + : public webui::DefaultInternalWebUIConfig<ProfileInternalsUI> { public: ProfileInternalsUIConfig() - : DefaultWebUIConfig(content::kChromeUIScheme, - chrome::kChromeUIProfileInternalsHost) {} + : DefaultInternalWebUIConfig(chrome::kChromeUIProfileInternalsHost) {} }; // Controller for chrome://profile-internals page.
diff --git a/chrome/browser/ui/webui/safe_browsing/BUILD.gn b/chrome/browser/ui/webui/safe_browsing/BUILD.gn index 6696dfd..c149ed0 100644 --- a/chrome/browser/ui/webui/safe_browsing/BUILD.gn +++ b/chrome/browser/ui/webui/safe_browsing/BUILD.gn
@@ -10,6 +10,7 @@ "chrome_safe_browsing_ui.h", ] public_deps = [ + "//chrome/browser/ui/webui:internal_webui_config", "//components/safe_browsing/content/browser/web_ui", "//components/safe_browsing/core/common", "//content/public/browser",
diff --git a/chrome/browser/ui/webui/safe_browsing/chrome_safe_browsing_ui.h b/chrome/browser/ui/webui/safe_browsing/chrome_safe_browsing_ui.h index e8028cf8..0e097001 100644 --- a/chrome/browser/ui/webui/safe_browsing/chrome_safe_browsing_ui.h +++ b/chrome/browser/ui/webui/safe_browsing/chrome_safe_browsing_ui.h
@@ -5,10 +5,10 @@ #ifndef CHROME_BROWSER_UI_WEBUI_SAFE_BROWSING_CHROME_SAFE_BROWSING_UI_H_ #define CHROME_BROWSER_UI_WEBUI_SAFE_BROWSING_CHROME_SAFE_BROWSING_UI_H_ +#include "chrome/browser/ui/webui/internal_webui_config.h" #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h" #include "components/safe_browsing/core/common/web_ui_constants.h" #include "content/public/browser/web_ui.h" -#include "content/public/browser/webui_config.h" #include "content/public/common/url_constants.h" namespace safe_browsing { @@ -16,11 +16,10 @@ class ChromeSafeBrowsingUI; class ChromeSafeBrowsingUIConfig - : public content::DefaultWebUIConfig<ChromeSafeBrowsingUI> { + : public webui::DefaultInternalWebUIConfig<ChromeSafeBrowsingUI> { public: ChromeSafeBrowsingUIConfig() - : DefaultWebUIConfig(content::kChromeUIScheme, - safe_browsing::kChromeUISafeBrowsingHost) {} + : DefaultInternalWebUIConfig(safe_browsing::kChromeUISafeBrowsingHost) {} }; class ChromeSafeBrowsingUI : public SafeBrowsingUI {
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 79c9614..ee70403 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -1081,10 +1081,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) html_source->AddString( "osSettingsLanguagesPageUrl", - chrome::GetOSSettingsUrl( - ash::features::IsOsSettingsRevampWayfindingEnabled() - ? chromeos::settings::mojom::kLanguagesSubpagePath - : chromeos::settings::mojom::kLanguagesAndInputSectionPath) + chrome::GetOSSettingsUrl(chromeos::settings::mojom::kLanguagesSubpagePath) .spec()); #endif // BUILDFLAG(IS_CHROMEOS_ASH) }
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc index adb781d..b4c8e43 100644 --- a/chrome/browser/ui/webui/settings/settings_ui.cc +++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -493,11 +493,6 @@ is_restricted_notice_enabled); html_source->AddBoolean( - "privateStateTokensEnabled", - base::FeatureList::IsEnabled(network::features::kPrivateStateTokens) || - base::FeatureList::IsEnabled(network::features::kFledgePst)); - - html_source->AddBoolean( "safetyHubAbusiveNotificationRevocationEnabled", base::FeatureList::IsEnabled( safe_browsing::kSafetyHubAbusiveNotificationRevocation));
diff --git a/chrome/browser/ui/webui/user_actions/user_actions_ui.h b/chrome/browser/ui/webui/user_actions/user_actions_ui.h index 7a50df8..ab22a8a 100644 --- a/chrome/browser/ui/webui/user_actions/user_actions_ui.h +++ b/chrome/browser/ui/webui/user_actions/user_actions_ui.h
@@ -5,18 +5,17 @@ #ifndef CHROME_BROWSER_UI_WEBUI_USER_ACTIONS_USER_ACTIONS_UI_H_ #define CHROME_BROWSER_UI_WEBUI_USER_ACTIONS_USER_ACTIONS_UI_H_ -#include "chrome/common/url_constants.h" +#include "chrome/browser/ui/webui/internal_webui_config.h" #include "chrome/common/webui_url_constants.h" #include "content/public/browser/web_ui_controller.h" -#include "content/public/browser/webui_config.h" class UserActionsUI; -class UserActionsUIConfig : public content::DefaultWebUIConfig<UserActionsUI> { +class UserActionsUIConfig + : public webui::DefaultInternalWebUIConfig<UserActionsUI> { public: UserActionsUIConfig() - : DefaultWebUIConfig(content::kChromeUIScheme, - chrome::kChromeUIUserActionsHost) {} + : DefaultInternalWebUIConfig(chrome::kChromeUIUserActionsHost) {} }; // The UI for chrome://user-actions/
diff --git a/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.h b/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.h index cffea3ef..7351c44 100644 --- a/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.h +++ b/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.h
@@ -7,7 +7,6 @@ #include "chrome/browser/ui/webui/internal_webui_config.h" #include "chrome/common/webui_url_constants.h" -#include "content/public/common/url_constants.h" #include "ui/webui/mojo_web_ui_controller.h" #include "ui/webui/resources/cr_components/color_change_listener/color_change_listener.mojom.h"
diff --git a/chrome/browser/ui/webui/webui_js_error/webui_js_error_ui.h b/chrome/browser/ui/webui/webui_js_error/webui_js_error_ui.h index 839bdbc..a45e432f 100644 --- a/chrome/browser/ui/webui/webui_js_error/webui_js_error_ui.h +++ b/chrome/browser/ui/webui/webui_js_error/webui_js_error_ui.h
@@ -5,19 +5,17 @@ #ifndef CHROME_BROWSER_UI_WEBUI_WEBUI_JS_ERROR_WEBUI_JS_ERROR_UI_H_ #define CHROME_BROWSER_UI_WEBUI_WEBUI_JS_ERROR_WEBUI_JS_ERROR_UI_H_ +#include "chrome/browser/ui/webui/internal_webui_config.h" #include "chrome/common/webui_url_constants.h" #include "content/public/browser/web_ui_controller.h" -#include "content/public/browser/webui_config.h" -#include "content/public/common/url_constants.h" class WebUIJsErrorUI; class WebUIJsErrorUIConfig - : public content::DefaultWebUIConfig<WebUIJsErrorUI> { + : public webui::DefaultInternalWebUIConfig<WebUIJsErrorUI> { public: WebUIJsErrorUIConfig() - : DefaultWebUIConfig(content::kChromeUIScheme, - chrome::kChromeUIWebUIJsErrorHost) {} + : DefaultInternalWebUIConfig(chrome::kChromeUIWebUIJsErrorHost) {} }; // The WebUI that controls chrome://webuijserror.
diff --git a/chrome/browser/web_applications/commands/fetch_manifest_and_install_command.cc b/chrome/browser/web_applications/commands/fetch_manifest_and_install_command.cc index 0a4f8b60..7853534 100644 --- a/chrome/browser/web_applications/commands/fetch_manifest_and_install_command.cc +++ b/chrome/browser/web_applications/commands/fetch_manifest_and_install_command.cc
@@ -693,9 +693,21 @@ bool is_shortcut_created = IsShortcutCreated(app_lock_->registrar(), app_id); DCHECK(app_lock_); + + const WebAppTabHelper* tab_helper = + WebAppTabHelper::FromWebContents(web_contents_.get()); + bool is_in_app_window = false; + if (tab_helper) { + // The tab helper doesn't exist in unit tests. + is_in_app_window = tab_helper->is_in_app_window(); + } + + // TODO(https://crbug.com/383360269): Turn the is_in_app_window into a CHECK + // after all user installs can no longer overlap each other. const bool can_reparent_tab = app_lock_->ui_manager().CanReparentAppTabToWindow(app_id, - is_shortcut_created); + is_shortcut_created) && + !is_in_app_window; SCOPED_CRASH_KEY_NUMBER("PWA", "install_surface", static_cast<int>(install_surface_)); @@ -703,8 +715,6 @@ "PWA", "install_url", web_contents_->GetLastCommittedURL().possibly_invalid_spec()); SCOPED_CRASH_KEY_STRING64("PWA", "install_app_id", app_id); - WebAppTabHelper* tab_helper = - WebAppTabHelper::FromWebContents(web_contents_.get()); if (tab_helper) { SCOPED_CRASH_KEY_STRING64("PWA", "source_window_app_id", tab_helper->window_app_id().value_or("<none>"));
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc index b533b61..7a60eacf 100644 --- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc +++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -509,6 +509,16 @@ if (dialog_model_->in_onboarding_flow) { RecordOnboardingEvent(webauthn::metrics::OnboardingEvents::kSucceeded); } + switch (request_type) { + case device::FidoRequestType::kGetAssertion: + RecordGPMGetAssertionEvent( + webauthn::metrics::GPMGetAssertionEvents::kSuccess); + break; + case device::FidoRequestType::kMakeCredential: + RecordGPMMakeCredentialEvent( + webauthn::metrics::GPMMakeCredentialEvents::kSuccess); + break; + } webauthn::user_actions::RecordGpmSuccess(); } }
diff --git a/chrome/browser/webauthn/enclave_manager.cc b/chrome/browser/webauthn/enclave_manager.cc index b4c3ebc..ff227e4 100644 --- a/chrome/browser/webauthn/enclave_manager.cc +++ b/chrome/browser/webauthn/enclave_manager.cc
@@ -32,6 +32,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" +#include "base/metrics/histogram_functions.h" #include "base/notreached.h" #include "base/numerics/checked_math.h" #include "base/numerics/safe_conversions.h" @@ -2608,6 +2609,15 @@ trusted_vault_access_token_fetcher_frontend_->GetWeakPtr()))), identity_observer_( std::make_unique<IdentityObserver>(identity_manager_, this)) { + // Automatically load the enclave state shortly after startup so that any + // renewals will be considered without the user having to do something to + // trigger a WebAuthn operation. + load_timer_.Start( + FROM_HERE, base::Minutes(4), + base::BindOnce(&EnclaveManager::Load, weak_ptr_factory_.GetWeakPtr(), + base::DoNothing())); + // Also consider renewing the PIN every day, for users who keep Chrome open + // for long periods. renewal_timer_.Start(FROM_HERE, base::Hours(24), base::BindRepeating(&EnclaveManager::ConsiderPinRenewal, weak_ptr_factory_.GetWeakPtr())); @@ -3781,12 +3791,37 @@ secret_ = std::vector<uint8_t>(secret.begin(), secret.end()); } +// A list of PIN-renewal events that are reported to UMA. Do not renumber +// as the values are persisted. +enum class PinRenewalEvent { + kConsidered = 0, + kNothingToRenew = 1, + kConcurrentRenewal = 2, + kNotYetTime = 3, + kStarted = 4, + kSuccess = 5, + kFailure = 6, + + kMaxValue = kFailure, +}; + +static const char kPinRenewalHistogram[] = "WebAuthentication.PinRenewalEvent"; + void EnclaveManager::ConsiderPinRenewal() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::UmaHistogramEnumeration(kPinRenewalHistogram, + PinRenewalEvent::kConsidered); renewal_checks_++; - if (!user_ || !user_->registered() || !user_->has_wrapped_pin() || - is_renewing_) { + if (!user_ || !user_->registered() || !user_->has_wrapped_pin()) { + base::UmaHistogramEnumeration(kPinRenewalHistogram, + PinRenewalEvent::kNothingToRenew); + return; + } + + if (is_renewing_) { + base::UmaHistogramEnumeration(kPinRenewalHistogram, + PinRenewalEvent::kConcurrentRenewal); return; } @@ -3797,12 +3832,21 @@ FIDO_LOG(EVENT) << "Renewing GPM PIN based on time since last renewal"; renewal_attempts_++; is_renewing_ = true; + base::UmaHistogramEnumeration(kPinRenewalHistogram, + PinRenewalEvent::kStarted); RenewPIN(base::BindOnce(&EnclaveManager::OnRenewalComplete, weak_ptr_factory_.GetWeakPtr())); + } else { + base::UmaHistogramEnumeration(kPinRenewalHistogram, + PinRenewalEvent::kNotYetTime); } } void EnclaveManager::OnRenewalComplete(bool success) { + base::UmaHistogramEnumeration( + kPinRenewalHistogram, + success ? PinRenewalEvent::kSuccess : PinRenewalEvent::kFailure); + is_renewing_ = false; }
diff --git a/chrome/browser/webauthn/enclave_manager.h b/chrome/browser/webauthn/enclave_manager.h index 517c26c..886d872d 100644 --- a/chrome/browser/webauthn/enclave_manager.h +++ b/chrome/browser/webauthn/enclave_manager.h
@@ -404,6 +404,7 @@ std::unique_ptr<StateMachine> state_machine_; std::vector<base::OnceClosure> load_callbacks_; std::deque<std::unique_ptr<PendingAction>> pending_actions_; + base::OneShotTimer load_timer_; base::RepeatingTimer renewal_timer_; unsigned renewal_checks_ = 0; unsigned renewal_attempts_ = 0;
diff --git a/chrome/browser/webauthn/enclave_manager_factory.cc b/chrome/browser/webauthn/enclave_manager_factory.cc index b7ee1ea..6b449326 100644 --- a/chrome/browser/webauthn/enclave_manager_factory.cc +++ b/chrome/browser/webauthn/enclave_manager_factory.cc
@@ -89,3 +89,15 @@ : profile->GetDefaultStoragePartition() ->GetURLLoaderFactoryForBrowserProcess()); } + +bool EnclaveManagerFactory::ServiceIsCreatedWithBrowserContext() const { + // In order that the GPM PIN can be considered for renewal, the + // EnclaveManager should be created when a Profile is created. At the time of + // writing, this happens because a `TrustedVaultEncryptionKeysTabHelper` is + // created for each tab, and that triggers the creation of the EnclaveManager + // too. + // + // It would be nice to return `true` here to ensure the creation in a more + // direct fashion, but this appears to upset a large number of tests. + return false; +}
diff --git a/chrome/browser/webauthn/enclave_manager_factory.h b/chrome/browser/webauthn/enclave_manager_factory.h index 2b23d7c..0fe5b9b 100644 --- a/chrome/browser/webauthn/enclave_manager_factory.h +++ b/chrome/browser/webauthn/enclave_manager_factory.h
@@ -38,6 +38,8 @@ // BrowserContextKeyedServiceFactory: std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const override; + + bool ServiceIsCreatedWithBrowserContext() const override; }; #endif // CHROME_BROWSER_WEBAUTHN_ENCLAVE_MANAGER_FACTORY_H_
diff --git a/chrome/browser/webauthn/gpm_enclave_controller.cc b/chrome/browser/webauthn/gpm_enclave_controller.cc index fbf5139..b08a262 100644 --- a/chrome/browser/webauthn/gpm_enclave_controller.cc +++ b/chrome/browser/webauthn/gpm_enclave_controller.cc
@@ -902,6 +902,14 @@ return; } + if (account_state_ != AccountState::kLoading && + account_state_ != AccountState::kChecking) { + // `kLoading` and `kChecking` will call `OnGPMSelected` again, + // therefore we don't emit in these states. + RecordGPMMakeCredentialEvent( + webauthn::metrics::GPMMakeCredentialEvents::kStarted); + } + switch (account_state_) { case AccountState::kEmpty: // Set to true to indicate that the user has entered the GPM onboarding @@ -963,6 +971,15 @@ void GPMEnclaveController::OnGPMPasskeySelected( std::vector<uint8_t> credential_id) { selected_cred_id_ = std::move(credential_id); + + if (account_state_ != AccountState::kLoading && + account_state_ != AccountState::kChecking) { + // `kLoading` and `kChecking` will call `OnGPMPasskeySelected` again, + // therefore we don't emit in these states. + RecordGPMGetAssertionEvent( + webauthn::metrics::GPMGetAssertionEvents::kStarted); + } + switch (account_state_) { case AccountState::kReady: uv_method_ = PickEnclaveUserVerificationMethod(
diff --git a/chrome/browser/webauthn/webauthn_metrics_util.cc b/chrome/browser/webauthn/webauthn_metrics_util.cc index dcbb90a99..0d220aa 100644 --- a/chrome/browser/webauthn/webauthn_metrics_util.cc +++ b/chrome/browser/webauthn/webauthn_metrics_util.cc
@@ -19,6 +19,16 @@ passkey_count, kPasskeyCountMax); } +void RecordGPMMakeCredentialEvent( + webauthn::metrics::GPMMakeCredentialEvents event) { + base::UmaHistogramEnumeration("WebAuthentication.GPM.MakeCredential", event); +} + +void RecordGPMGetAssertionEvent( + webauthn::metrics::GPMGetAssertionEvents event) { + base::UmaHistogramEnumeration("WebAuthentication.GPM.GetAssertion", event); +} + void RecordOnboardingEvent(webauthn::metrics::OnboardingEvents event) { base::UmaHistogramEnumeration("WebAuthentication.OnboardingEvents", event); }
diff --git a/chrome/browser/webauthn/webauthn_metrics_util.h b/chrome/browser/webauthn/webauthn_metrics_util.h index be99d9a6..e39ba44d 100644 --- a/chrome/browser/webauthn/webauthn_metrics_util.h +++ b/chrome/browser/webauthn/webauthn_metrics_util.h
@@ -8,6 +8,28 @@ namespace webauthn::metrics { // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. +enum class GPMMakeCredentialEvents { + // LINT.IfChange + kStarted = 0, + kSuccess = 1, + kFailure = 2, + kMaxValue = kFailure, + // LINT.ThenChange(//tools/metrics/histograms/metadata/webauthn/enums.xml) +}; + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class GPMGetAssertionEvents { + // LINT.IfChange + kStarted = 0, + kSuccess = 1, + kFailure = 2, + kMaxValue = kFailure, + // LINT.ThenChange(//tools/metrics/histograms/metadata/webauthn/enums.xml) +}; + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum class OnboardingEvents { // LINT.IfChange kStarted = 0, @@ -22,6 +44,9 @@ } // namespace webauthn::metrics void ReportConditionalUiPasskeyCount(int passkey_count); +void RecordGPMMakeCredentialEvent( + webauthn::metrics::GPMMakeCredentialEvents event); +void RecordGPMGetAssertionEvent(webauthn::metrics::GPMGetAssertionEvents event); void RecordOnboardingEvent(webauthn::metrics::OnboardingEvents event); #endif // CHROME_BROWSER_WEBAUTHN_WEBAUTHN_METRICS_UTIL_H_
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index d176da03..3fbe47c 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1734371937-f283eb344a78e960bbe1d12884eec0619e778216-5ef1114e1ac2ac62c2c14b1881eba5993e27a4b3.profdata +chrome-android32-main-1734436763-9e3e8a340774f52deff33a13402447b20bcfd2d0-350bd3a6bf626f7a1187774fd5cad80e7a73499d.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 8de95f9..cb2f3d49 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1734380526-c6699d9ec30d9dd3d49bf3caeda97f8ff7895036-72f63dc6e666795c3e09838960688ee4a9722994.profdata +chrome-android64-main-1734438468-bc76c19d196bd9dfcd0558ab69b05aa46102178a-5088537f95148d6e49f57b52c42ad9af5b086d8f.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 447138b..ba187481 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1734371937-a4631cb7c5858ddfe9c7d266350cd4da67704c99-5ef1114e1ac2ac62c2c14b1881eba5993e27a4b3.profdata +chrome-linux-main-1734414938-be471abd254f3257ee224a25e0c7a2a0f0f1c376-648c84c49041f27a9f6a1910c89a1ef550cfd0ef.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 04fa364..27e1542 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1734378930-3d3508afefb827952020baf0a68aa30bd835367f-3242557f0985555df85fba80075279bac73e9300.profdata +chrome-mac-arm-main-1734436763-3947ce6fc1cc00d0aabc4342f0f5aaaa6dfdb5af-350bd3a6bf626f7a1187774fd5cad80e7a73499d.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 6e9a59d..a690b15 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1734371937-43d425a3f9349a913834fb3d57775306e85e10fd-5ef1114e1ac2ac62c2c14b1881eba5993e27a4b3.profdata +chrome-mac-main-1734414938-6adcd2b459696221606fcd528610be9567203fed-648c84c49041f27a9f6a1910c89a1ef550cfd0ef.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index e63c43c..72df09f1 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1734371937-47ee10c431b1c653c5a55c161ecc854615d2408c-5ef1114e1ac2ac62c2c14b1881eba5993e27a4b3.profdata +chrome-win-arm64-main-1734436763-0edd328847c0406d552fc56ebe92019d1fac4230-350bd3a6bf626f7a1187774fd5cad80e7a73499d.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 09793b9..2839e28 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1734371937-a97c35dfd76e40fe468471f303b8c2be15d7cfb6-5ef1114e1ac2ac62c2c14b1881eba5993e27a4b3.profdata +chrome-win32-main-1734403932-4e67c016f81772ce2ab4fe4f226c3d972a1054fe-f3de0a77fd31b0fcf0dfa90a5e39c7ae2e827023.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index af2e8a9..fdaa9d1d 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1734360969-cb6d5ec9cd9e906febddfa4e31e6e2d1e77cd84c-2e49645b1352adcee7eca1f6e888f0895f6ce3fd.profdata +chrome-win64-main-1734414938-d74b38f64d083b4df5bd3809dbd72b91a3dd2f7d-648c84c49041f27a9f6a1910c89a1ef550cfd0ef.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 3b9300f9..09c9d4fe 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -314,6 +314,9 @@ // Controls whether the Glic feature is enabled. BASE_FEATURE(kGlic, "Glic", base::FEATURE_DISABLED_BY_DEFAULT); +const base::FeatureParam<bool> kGlicStatusIconOpenMenuWithSecondaryClick{ + &kGlic, "open-status-icon-menu-with-secondary-click", false}; + BASE_FEATURE(kGlicURLConfig, "GlicURLConfig", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index f3455f6..4f34f1be 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -206,6 +206,8 @@ COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kGeoLanguage); COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kGlic); +COMPONENT_EXPORT(CHROME_FEATURES) +extern const base::FeatureParam<bool> kGlicStatusIconOpenMenuWithSecondaryClick; COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kGlicURLConfig); COMPONENT_EXPORT(CHROME_FEATURES)
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index e7a666aa..5733b59 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -3952,14 +3952,6 @@ #endif #if BUILDFLAG(IS_CHROMEOS_ASH) -// Enum pref indicating how to launch the Lacros browser. It is managed by -// LacrosAvailability policy and can have one of the following values: -// 0: User choice (default value). -// 1: Lacros is disallowed. -// 4: Lacros is the only available browser. -// Values 2 and 3 were removed and should not be reused. -inline constexpr char kLacrosLaunchSwitch[] = "lacros_launch_switch"; - // Enum pref indicating which Lacros browser to launch: rootfs or stateful. It // is managed by LacrosSelection policy and can have one of the following // values:
diff --git a/chrome/common/profiler/core_unwinders_android.cc b/chrome/common/profiler/core_unwinders_android.cc index c9fdacf7..b26e578 100644 --- a/chrome/common/profiler/core_unwinders_android.cc +++ b/chrome/common/profiler/core_unwinders_android.cc
@@ -46,6 +46,8 @@ #include "base/android/library_loader/anchor_functions.h" #include "base/files/memory_mapped_file.h" #include "base/profiler/chrome_unwinder_android_32.h" +#include "chrome/android/modules/stack_unwinder/public/module.h" +#include "chrome/common/profiler/native_unwinder_android_map_delegate_impl.h" #endif // ARM32_UNWINDING_SUPPORTED #if ARM64_UNWINDING_SUPPORTED @@ -55,8 +57,6 @@ #if UNWINDING_SUPPORTED #include "base/profiler/libunwindstack_unwinder_android.h" #include "base/profiler/native_unwinder_android.h" -#include "chrome/android/modules/stack_unwinder/public/module.h" -#include "chrome/common/profiler/native_unwinder_android_map_delegate_impl.h" extern "C" { // The address of |__executable_start| is the base address of the executable or @@ -124,6 +124,8 @@ // For now, we only use Libunwindstack on 64 bit (no other unwinders). return CreateLibunwindstackUnwinders(); #else + // The ARM32_UNWINDING_SUPPORTED branch, since this code is within an #if + // UNWINDING_SUPPORTED. static base::NoDestructor<NativeUnwinderAndroidMapDelegateImpl> map_delegate; static base::NoDestructor<ChromeUnwinderCreator> chrome_unwinder_creator; @@ -137,7 +139,9 @@ return unwinders; #endif } +#endif // UNWINDING_SUPPORTED +#if ARM32_UNWINDING_SUPPORTED // Manages installation of the module prerequisite for unwinding. Android, in // particular, requires a dynamic feature module to provide the native unwinder. class ModuleUnwindPrerequisitesDelegate : public UnwindPrerequisitesDelegate { @@ -150,7 +154,7 @@ return stack_unwinder::Module::IsInstalled(); } }; -#endif // UNWINDING_SUPPORTED +#endif // ARM32_UNWINDING_SUPPORTED } // namespace @@ -159,15 +163,17 @@ UnwindPrerequisitesDelegate* prerequites_delegate) { CHECK_EQ(sampling_profiler::ProfilerProcessType::kBrowser, GetProfilerProcessType(*base::CommandLine::ForCurrentProcess())); +#if ARM32_UNWINDING_SUPPORTED && defined(OFFICIAL_BUILD) && \ + BUILDFLAG(GOOGLE_CHROME_BRANDING) if (AreUnwindPrerequisitesAvailable(channel, prerequites_delegate)) { return; } -#if UNWINDING_SUPPORTED && defined(OFFICIAL_BUILD) && \ - BUILDFLAG(GOOGLE_CHROME_BRANDING) + ModuleUnwindPrerequisitesDelegate default_delegate; if (prerequites_delegate == nullptr) { prerequites_delegate = &default_delegate; } + // We only want to incur the cost of universally downloading the module in // early channels, where profiling will occur over substantially all of // the population. When supporting later channels in the future we will @@ -187,7 +193,8 @@ UnwindPrerequisitesDelegate* prerequites_delegate) { // While non-Android platforms do not need any specific prerequisites beyond // what is already bundled and available with Chrome for their platform-specific -// unwinders to work, Android, in particular, requires a DFM to be installed. +// unwinders to work, Android, in particular, requires a DFM to be installed on +// arm32. // // Therefore, unwind prerequisites for non-supported Android platforms are not // considered to be available by default, but prerequisites for non-Android @@ -197,7 +204,7 @@ // non-Android platforms. Regardless of the provided delegate, unwind // prerequisites are always considered to be available for non-Android // platforms. -#if UNWINDING_SUPPORTED +#if ARM32_UNWINDING_SUPPORTED #if defined(OFFICIAL_BUILD) && BUILDFLAG(GOOGLE_CHROME_BRANDING) // Sometimes, DFMs can be installed even if not requested by Chrome // explicitly (for instance, in some app stores). Therefore, even if the @@ -214,25 +221,29 @@ prerequites_delegate = &default_delegate; } return prerequites_delegate->AreAvailable(channel); -#else // UNWINDING_SUPPORTED +#elif ARM64_UNWINDING_SUPPORTED + return true; +#else return false; -#endif // UNWINDING_SUPPORTED +#endif // ARM32_UNWINDING_SUPPORTED } -#if UNWINDING_SUPPORTED +#if ARM32_UNWINDING_SUPPORTED void LoadModule() { CHECK(AreUnwindPrerequisitesAvailable(chrome::GetChannel())); static base::NoDestructor<std::unique_ptr<stack_unwinder::Module>> stack_unwinder_module(stack_unwinder::Module::Load()); } -#endif // UNWINDING_SUPPORTED +#endif // ARM32_UNWINDING_SUPPORTED base::StackSamplingProfiler::UnwindersFactory CreateCoreUnwindersFactory() { if (!AreUnwindPrerequisitesAvailable(chrome::GetChannel())) { return base::StackSamplingProfiler::UnwindersFactory(); } #if UNWINDING_SUPPORTED +#if ARM32_UNWINDING_SUPPORTED LoadModule(); +#endif // ARM32_UNWINDING_SUPPORTED return base::BindOnce(CreateCoreUnwinders); #else // UNWINDING_SUPPORTED return base::StackSamplingProfiler::UnwindersFactory();
diff --git a/chrome/common/profiler/core_unwinders_android_unittest.cc b/chrome/common/profiler/core_unwinders_android_unittest.cc index 36e8471..f9345e9c 100644 --- a/chrome/common/profiler/core_unwinders_android_unittest.cc +++ b/chrome/common/profiler/core_unwinders_android_unittest.cc
@@ -5,6 +5,7 @@ #include "chrome/common/profiler/core_unwinders.h" #include "base/command_line.h" +#include "base/debug/debugging_buildflags.h" #include "base/feature_list.h" #include "base/memory/raw_ptr.h" #include "base/profiler/profiler_buildflags.h"
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index b367aaff..38c8151 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2079,6 +2079,7 @@ "//chrome/browser/ui/views/webid:test_support", "//chrome/browser/ui/web_applications:browser_tests", "//chrome/browser/ui/webui", + "//chrome/browser/ui/webui:internal_webui_config", "//chrome/browser/ui/webui:webui_util", "//chrome/browser/ui/webui/commerce", "//chrome/browser/ui/webui/privacy_sandbox:mojo_bindings", @@ -2823,6 +2824,7 @@ "../browser/lookalikes/lookalike_test_helper.cc", "../browser/lookalikes/lookalike_test_helper.h", "../browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc", + "../browser/media/audio_ducker_browsertest.cc", "../browser/media/autoplay_metrics_browsertest.cc", "../browser/media/cast_mirroring_service_host_browsertest.cc", "../browser/media/defer_background_media_browsertest.cc", @@ -5769,7 +5771,6 @@ "../browser/component_updater/privacy_sandbox_attestations_component_installer_unittest.cc", "../browser/component_updater/subresource_filter_component_installer_unittest.cc", "../browser/component_updater/tpcd_metadata_component_installer_unittest.cc", - "../browser/component_updater/trust_token_key_commitments_component_installer_unittest.cc", "../browser/content_index/content_index_provider_unittest.cc", "../browser/custom_handlers/chrome_protocol_handler_registry_unittest.cc", "../browser/data_sharing/data_sharing_navigation_throttle_unittest.cc", @@ -6370,6 +6371,7 @@ "//chrome/browser/ui/page_info:unit_tests", "//chrome/browser/ui/safety_hub:test_support", "//chrome/browser/ui/webui", + "//chrome/browser/ui/webui:internal_webui_config", "//chrome/browser/ui/webui:webui_util", "//chrome/browser/updates/announcement_notification:unit_tests", "//chrome/browser/web_share_target:unit_tests",
diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc index 4638590..a4d1a62 100644 --- a/chrome/test/chromedriver/capabilities.cc +++ b/chrome/test/chromedriver/capabilities.cc
@@ -846,6 +846,11 @@ parser_map["devToolsEventsToLog"] = base::BindRepeating(&ParseDevToolsEventsLoggingPrefs); parser_map["windowTypes"] = base::BindRepeating(&ParseWindowTypes); + + // Enable Chrome extension related targets + parser_map["enableExtensionTargets"] = base::BindRepeating( + &ParseBoolean, &capabilities->enable_extension_targets); + // Compliance is read when session is initialized and correct response is // sent if not parsed correctly. parser_map["w3c"] = base::BindRepeating(&IgnoreCapability); @@ -1163,10 +1168,6 @@ base::BindRepeating(&ParseChromeOptions); } - // Enable Chrome extension related targets - parser_map["enableExtensionTargets"] = - base::BindRepeating(&ParseBoolean, &enable_extension_targets); - // se:options.loggingPrefs and goog:loggingPrefs is spec-compliant name, // but loggingPrefs is still supported in legacy mode. const std::string prefixed_logging_prefs_key =
diff --git a/chrome/test/chromedriver/client/chromedriver.py b/chrome/test/chromedriver/client/chromedriver.py index 23a5341e..26f0a9fc 100644 --- a/chrome/test/chromedriver/client/chromedriver.py +++ b/chrome/test/chromedriver/client/chromedriver.py
@@ -115,8 +115,8 @@ send_w3c_capability=True, send_w3c_request=True, page_load_strategy=None, unexpected_alert_behaviour=None, devtools_events_to_log=None, accept_insecure_certs=None, - enable_extension_targets=None, timeouts=None, test_name=None, - web_socket_url=None, browser_name=None, http_timeout=None): + timeouts=None, test_name=None, web_socket_url=None, browser_name=None, + http_timeout=None): self._executor = command_executor.CommandExecutor(server_url, http_timeout=http_timeout) self._server_url = server_url @@ -228,9 +228,6 @@ if accept_insecure_certs is not None: params['acceptInsecureCerts'] = accept_insecure_certs - if enable_extension_targets is not None: - params['enableExtensionTargets'] = enable_extension_targets - if timeouts is not None: params['timeouts'] = timeouts
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index ff31fc57..272956a 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -6426,8 +6426,8 @@ # This test can be removed entirely when support for MV2 extensions is # removed. driver = self.CreateDriver( - # Chrome Extension inspection requires enable_extension_targets = True. - enable_extension_targets = True, + # Chrome Extension inspection requires enableExtensionTargets = True. + experimental_options={'enableExtensionTargets': True}, chrome_extensions=[self._PackExtension(crx)], chrome_switches=['disable-features=ExtensionManifestV2Disabled']) handles = driver.GetWindowHandles() @@ -6441,9 +6441,9 @@ def testCanInspectExtensionTargetsWithMigratedSwitch(self): crx = os.path.join(_TEST_DATA_DIR, 'ext_bg_page.crx') - # Chrome Extension inspection requires enable_extension_targets = True. + # Chrome Extension inspection requires enableExtensionTargets = True. # We migrate experimental_options={'windowTypes': ['background_page']} to - # the new switch. + # the new chrome option. # This test exercises inspection of an extension background page, which # is only valid for manifest V2 extensions. Explicitly disable the # experiment that disallows MV2 extensions.
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 61d033f..11bb945 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
@@ -140,6 +140,40 @@ await navigateToRequestedUrl(); }, + // Tests that calling configureWorld() will only change the properties present + // in the `configureWorld` parameters. + async function callingConfigureWorldOnlyChangesPresentProperties() { + await cleanUpState(); + + const customCsp = 'some csp'; + const customMessaging = true; + + // Configure a world with a custom messaging and CSP state, and verify its + // values. + await chrome.userScripts.configureWorld( + {csp: customCsp, messaging: customMessaging}); + let worldConfig = (await chrome.userScripts.getWorldConfigurations())[0]; + chrome.test.assertEq(customCsp, worldConfig.csp); + chrome.test.assertEq(customMessaging, worldConfig.messaging); + + // Update the world, but don't pass any changes. The world configuration + // should be unchanged. + await chrome.userScripts.configureWorld({}); + worldConfig = (await chrome.userScripts.getWorldConfigurations())[0]; + chrome.test.assertEq(customCsp, worldConfig.csp); + chrome.test.assertEq(customMessaging, worldConfig.messaging); + + // Update the world with only a new CSP. The CSP should be updated, but the + // messaging state should stay the same (at its custom value). + const secondCustomCsp = 'some other csp'; + await chrome.userScripts.configureWorld({csp: secondCustomCsp}); + worldConfig = (await chrome.userScripts.getWorldConfigurations())[0]; + chrome.test.assertEq(secondCustomCsp, worldConfig.csp); + chrome.test.assertEq(customMessaging, worldConfig.messaging); + + chrome.test.succeed(); + }, + // Tests that a registered user script in the MAIN world cannot send or // receive messages when messaging is enabled. async function mainWorld_messagingAlwaysDisabled() { @@ -226,9 +260,8 @@ // User script uses the customized csp. chrome.test.assertEq('eval allowed', tab.title); - // Reset the csp. Currently this is only achievable by calling - // userScripts.configureWorld with no csp value (crbug.com/1497059). - await chrome.userScripts.configureWorld({}); + // Reset the csp. + await chrome.userScripts.resetWorldConfiguration(); tab = await navigateToRequestedUrl() // User script eses the extension's csp.
diff --git a/chrome/test/data/extensions/api_test/user_scripts/persistent_configure_world/worker.js b/chrome/test/data/extensions/api_test/user_scripts/persistent_configure_world/worker.js index 0806d38..6b09d01 100644 --- a/chrome/test/data/extensions/api_test/user_scripts/persistent_configure_world/worker.js +++ b/chrome/test/data/extensions/api_test/user_scripts/persistent_configure_world/worker.js
@@ -94,8 +94,8 @@ // Verify user script still uses the customized csp. chrome.test.assertEq(['customized_csp'], await getInjectedElementIds(tab.id)); - // Disable messaging and csp (by omitting its entry). - chrome.userScripts.configureWorld({messaging: false}); + // Reset to defaults. + chrome.userScripts.resetWorldConfiguration(); chrome.test.succeed(); }
diff --git a/chrome/test/data/media/start-with-no-player.html b/chrome/test/data/media/start-with-no-player.html new file mode 100644 index 0000000..1ee9cc1 --- /dev/null +++ b/chrome/test/data/media/start-with-no-player.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> + <title>Test page that adds a player on demand</title> + <meta name=viewport content='width=device-width initial-scale=1.0'> +</head> +<body> +</body> +<script> + function addVideo() { + const video = document.createElement('video'); + video.src = 'bigbuck.webm'; + document.body.append(video); + } +</script> +</html>
diff --git a/chrome/test/data/webui/chromeos/settings/os_settings_ui/os_settings_ui_page_visibility_revamp_test.ts b/chrome/test/data/webui/chromeos/settings/os_settings_ui/os_settings_ui_page_visibility_revamp_test.ts index 258a6fa..4e10b23 100644 --- a/chrome/test/data/webui/chromeos/settings/os_settings_ui/os_settings_ui_page_visibility_revamp_test.ts +++ b/chrome/test/data/webui/chromeos/settings/os_settings_ui/os_settings_ui_page_visibility_revamp_test.ts
@@ -6,8 +6,6 @@ * @fileoverview * Suite of tests for page visibility in the CrOS Settings UI. * - * - These tests expect the OsSettingsRevampWayfinding feature flag to be - * enabled. * - This suite is separated into a dedicated file to mitigate test timeouts * since the element is very large. */ @@ -138,9 +136,6 @@ suiteSetup(async () => { browserProxy = new TestAccountManagerBrowserProxy(); AccountManagerBrowserProxyImpl.setInstanceForTesting(browserProxy); - assertTrue( - loadTimeData.getBoolean('isRevampWayfindingEnabled'), - 'This suite expects OsSettingsRevampWayfinding to be enabled.'); loadTimeData.overrideValues({ isKerberosEnabled: true, // Simulate kerberos route exists });
diff --git a/chrome/test/data/webui/settings/site_settings_page_test.ts b/chrome/test/data/webui/settings/site_settings_page_test.ts index 37e5922..285a91f2 100644 --- a/chrome/test/data/webui/settings/site_settings_page_test.ts +++ b/chrome/test/data/webui/settings/site_settings_page_test.ts
@@ -104,15 +104,6 @@ defaultSettingLabel(ContentSetting.IMPORTANT_CONTENT, 'a', 'b', 'c')); }); - test('AntiAbuseLinkRowHidden', async function() { - loadTimeData.overrideValues({ - privateStateTokensEnabled: false, - }); - setupPage(); - assertFalse(isChildVisible( - page.$.advancedContentList, `#${ContentSettingsTypes.ANTI_ABUSE}`)); - }); - test('CookiesLinkRowSublabel', async function() { // This test verifies the pre-3PCD label. loadTimeData.overrideValues({
diff --git a/chrome/test/fuzzing/atspi_in_process_fuzzer.cc b/chrome/test/fuzzing/atspi_in_process_fuzzer.cc index 47b46b7c..9477495 100644 --- a/chrome/test/fuzzing/atspi_in_process_fuzzer.cc +++ b/chrome/test/fuzzing/atspi_in_process_fuzzer.cc
@@ -40,6 +40,7 @@ #include "sql/database.h" #include "sql/statement.h" #include "sql/test/test_helpers.h" +#include "sql/transaction.h" #include "testing/libfuzzer/libfuzzer_exports.h" #include "ui/accessibility/platform/inspect/ax_inspect_scenario.h" #include "ui/accessibility/platform/inspect/ax_inspect_utils_auralinux.h" @@ -1069,6 +1070,9 @@ db_path = db_path.AppendASCII("atspi_in_process_fuzzer_controls.db"); CHECK(db_->Open(db_path)); CHECK(db_->Execute("PRAGMA foreign_keys = ON")); + // Atomically delete and create tables + sql::Transaction transaction(db_.get()); + CHECK(transaction.Begin()); // Delete some tables from older versions of this fuzzer DropTableIfExists("roles"); DropTableIfExists("names"); @@ -1097,6 +1101,7 @@ "controlsv4(id) ON DELETE CASCADE, FOREIGN KEY(action_id) REFERENCES " "actionsv2(id) ON DELETE CASCADE, unique(control_id, action_id))")); } + CHECK(transaction.Commit()); } void Database::DropTableIfExists(const std::string& table_name) {
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 2555654..0c3de52 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -16124.0.0-1065359 \ No newline at end of file +16130.0.0-1065442 \ No newline at end of file
diff --git a/chromeos/ash/components/standalone_browser/BUILD.gn b/chromeos/ash/components/standalone_browser/BUILD.gn index 103996fa..d637475f 100644 --- a/chromeos/ash/components/standalone_browser/BUILD.gn +++ b/chromeos/ash/components/standalone_browser/BUILD.gn
@@ -13,8 +13,6 @@ sources = [ "channel_util.cc", "channel_util.h", - "lacros_availability.cc", - "lacros_availability.h", "lacros_selection.cc", "lacros_selection.h", "standalone_browser_features.cc", @@ -41,7 +39,6 @@ sources = [ "channel_util_unittest.cc", - "lacros_availability_unittest.cc", "lacros_selection_unittest.cc", ]
diff --git a/chromeos/ash/components/standalone_browser/DEPS b/chromeos/ash/components/standalone_browser/DEPS index cb61470b..6be56c0 100644 --- a/chromeos/ash/components/standalone_browser/DEPS +++ b/chromeos/ash/components/standalone_browser/DEPS
@@ -1,23 +1,9 @@ specific_include_rules = { - "lacros_availability\.cc": [ - "+components/policy/core/common/policy_map.h", - "+components/policy/policy_constants.h", - "+components/user_manager/user.h", - ], "lacros_selection\.cc": [ "+components/policy/core/common/policy_map.h", "+components/policy/policy_constants.h", "+components/user_manager/user_manager.h", ], - "browser_support\.cc": [ - "+ash/constants/ash_switches.h", - "+components/user_manager/user.h", - "+components/user_manager/user_manager.h", - "+components/user_manager/user_type.h", - ], - "lacros_availability_unittest\.cc": [ - "+components/user_manager/fake_user_manager.h", - ], "lacros_selection_unittest\.cc": [ "+ash/constants/ash_switches.h", "+components/account_id/account_id.h",
diff --git a/chromeos/ash/components/standalone_browser/lacros_availability.cc b/chromeos/ash/components/standalone_browser/lacros_availability.cc deleted file mode 100644 index 17ebc71..0000000 --- a/chromeos/ash/components/standalone_browser/lacros_availability.cc +++ /dev/null
@@ -1,111 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromeos/ash/components/standalone_browser/lacros_availability.h" - -#include "ash/constants/ash_switches.h" -#include "base/command_line.h" -#include "base/containers/fixed_flat_map.h" -#include "base/logging.h" -#include "base/notreached.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/policy_constants.h" -#include "components/user_manager/user.h" -#include "google_apis/gaia/gaia_auth_util.h" - -namespace ash::standalone_browser { -namespace { - -// The conversion map for LacrosAvailability policy data. The values must match -// the ones from LacrosAvailability.yaml. -// TODO(crbug.com/40269372): Remove the side_by_side and lacros_primary values -// from the policy. -constexpr auto kLacrosAvailabilityMap = - base::MakeFixedFlatMap<std::string_view, LacrosAvailability>({ - {"user_choice", LacrosAvailability::kUserChoice}, - {"lacros_disallowed", LacrosAvailability::kLacrosDisallowed}, - {"side_by_side", LacrosAvailability::kLacrosDisallowed}, - {"lacros_primary", LacrosAvailability::kLacrosDisallowed}, - {"lacros_only", LacrosAvailability::kLacrosOnly}, - }); - -} // namespace - -BASE_FEATURE(kLacrosGooglePolicyRollout, - "LacrosGooglePolicyRollout", - base::FEATURE_ENABLED_BY_DEFAULT); - -std::optional<LacrosAvailability> ParseLacrosAvailability( - std::string_view value) { - auto it = kLacrosAvailabilityMap.find(value); - if (it != kLacrosAvailabilityMap.end()) { - return it->second; - } - - LOG(ERROR) << "Unknown LacrosAvailability policy value is passed: " << value; - return std::nullopt; -} - -std::string_view GetLacrosAvailabilityPolicyName(LacrosAvailability value) { - for (const auto& entry : kLacrosAvailabilityMap) { - if (entry.second == value) { - return entry.first; - } - } - - NOTREACHED(); -} - -bool IsGoogleInternal(const user_manager::User* user) { - if (!user) { - return false; - } - - const std::string_view email = user->GetAccountId().GetUserEmail(); - return gaia::IsGoogleInternalAccountEmail(email) || - gaia::IsGoogleRobotAccountEmail(email) || - gaia::ExtractDomainName(gaia::SanitizeEmail(email)) == - "managedchrome.com"; -} - -LacrosAvailability DetermineLacrosAvailabilityFromPolicyValue( - const user_manager::User* user, - std::string_view policy_value) { - // Users can set this switch in chrome://flags to disable the effect of the - // lacros-availability policy. This should only be allowed for Googlers. - // Note: Flag actively used by CfM to bypass LaCrOS Availability Policy. - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(ash::switches::kLacrosAvailabilityIgnore) && - IsGoogleInternal(user)) { - return LacrosAvailability::kUserChoice; - } - - if (policy_value.empty()) { - // Some tests call IsLacrosAllowedToBeEnabled but don't have the value set. - return LacrosAvailability::kUserChoice; - } - - auto result = ParseLacrosAvailability(policy_value); - if (!result.has_value()) { - return LacrosAvailability::kUserChoice; - } - - if (IsGoogleInternal(user) && - !base::FeatureList::IsEnabled(kLacrosGooglePolicyRollout) && - result != LacrosAvailability::kLacrosDisallowed) { - return LacrosAvailability::kUserChoice; - } - - return result.value(); -} - -LacrosAvailability GetLacrosAvailability(const user_manager::User* user, - const policy::PolicyMap& policy_map) { - const base::Value* value = policy_map.GetValue( - policy::key::kLacrosAvailability, base::Value::Type::STRING); - return DetermineLacrosAvailabilityFromPolicyValue( - user, value ? value->GetString() : std::string_view()); -} - -} // namespace ash::standalone_browser
diff --git a/chromeos/ash/components/standalone_browser/lacros_availability.h b/chromeos/ash/components/standalone_browser/lacros_availability.h deleted file mode 100644 index 2b015f5..0000000 --- a/chromeos/ash/components/standalone_browser/lacros_availability.h +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_LACROS_AVAILABILITY_H_ -#define CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_LACROS_AVAILABILITY_H_ - -#include <optional> -#include <string_view> - -#include "base/component_export.h" -#include "base/feature_list.h" - -namespace policy { -class PolicyMap; -} - -namespace user_manager { -class User; -} - -namespace ash::standalone_browser { -// Represents the policy indicating how to launch Lacros browser, named -// LacrosAvailability. The values shall be consistent with the controlling -// policy. -// Values 2 and 3 were removed and should not be reused. -enum class LacrosAvailability { - // Indicates that the user decides whether to enable Lacros (if allowed) and - // make it the primary/only browser. - kUserChoice = 0, - // Indicates that Lacros is not allowed to be enabled. - kLacrosDisallowed = 1, - // Indicates that Lacros (if allowed) is the only available browser. - kLacrosOnly = 4 -}; - -// The internal name in about_flags.cc for the lacros-availablility-policy -// config. -inline constexpr char kLacrosAvailabilityPolicyInternalName[] = - "lacros-availability-policy"; - -// The commandline flag name of lacros-availability-policy. -// The value should be the policy value as defined just below. -// The values need to be consistent with kLacrosAvailabilityMap above. -inline constexpr char kLacrosAvailabilityPolicySwitch[] = - "lacros-availability-policy"; -inline constexpr char kLacrosAvailabilityPolicyUserChoice[] = "user_choice"; -inline constexpr char kLacrosAvailabilityPolicyLacrosDisabled[] = - "lacros_disabled"; -inline constexpr char kLacrosAvailabilityPolicyLacrosOnly[] = "lacros_only"; - -// When this feature is enabled, Lacros is allowed to roll out by policy to -// Googlers. -COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER) -BASE_DECLARE_FEATURE(kLacrosGooglePolicyRollout); - -// Parses the string representation of LacrosAvailability policy value into -// the enum value. Returns nullopt on unknown value. -COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER) -std::optional<LacrosAvailability> ParseLacrosAvailability( - std::string_view value); - -// Returns the policy value name from the given value. -COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER) -std::string_view GetLacrosAvailabilityPolicyName(LacrosAvailability value); - -// Given a raw policy value, decides what LacrosAvailability value should be -// used as a result of policy application. -COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER) -LacrosAvailability DetermineLacrosAvailabilityFromPolicyValue( - const user_manager::User* user, - std::string_view policy_value); - -// Returns LacrosAvailability policy for the given `user` and its `policy_map`. -// This function may take a look at more surrounding context. -LacrosAvailability GetLacrosAvailability(const user_manager::User* user, - const policy::PolicyMap& policy_map); - -// Returns true if the given user's profile is associated with a google internal -// account. This includes @managedchrome.com accounts. -// TODO(andreaorru): conceptually, this is an internal utility function -// and should not be exported. Currently, `crosapi::browser_util` still -// depends on it. Remove once the IsLacrosEnabled* refactoring is complete. -COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER) -bool IsGoogleInternal(const user_manager::User* user); - -} // namespace ash::standalone_browser - -#endif // CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_LACROS_AVAILABILITY_H_
diff --git a/chromeos/ash/components/standalone_browser/lacros_availability_unittest.cc b/chromeos/ash/components/standalone_browser/lacros_availability_unittest.cc deleted file mode 100644 index 0cc4a46..0000000 --- a/chromeos/ash/components/standalone_browser/lacros_availability_unittest.cc +++ /dev/null
@@ -1,153 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromeos/ash/components/standalone_browser/lacros_availability.h" - -#include "ash/constants/ash_switches.h" -#include "base/test/scoped_command_line.h" -#include "base/test/scoped_feature_list.h" -#include "components/account_id/account_id.h" -#include "components/user_manager/fake_user_manager.h" -#include "testing/gtest/include/gtest/gtest.h" - -using user_manager::User; - -namespace ash::standalone_browser { - -class LacrosAvailabilityTest : public testing::Test { - public: - const User* AddRegularUser(const std::string& email) { - AccountId account_id = AccountId::FromUserEmail(email); - const User* user = fake_user_manager_.AddUser(account_id); - fake_user_manager_.UserLoggedIn(account_id, user->username_hash(), - /*browser_restart=*/false, - /*is_child=*/false); - return user; - } - - user_manager::FakeUserManager fake_user_manager_; -}; - -TEST_F(LacrosAvailabilityTest, - DetermineLacrosAvailabilityFromPolicyValueExternal) { - const User* const user = AddRegularUser("user@random.com"); - - // For non-Googlers, the policy can't be ignored by command line flag. - { - base::test::ScopedCommandLine command_line; - command_line.GetProcessCommandLine()->AppendSwitch( - ash::switches::kLacrosAvailabilityIgnore); - EXPECT_EQ(LacrosAvailability::kLacrosOnly, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_only")); - } - - // If there's no policy value, the choice is left to the user. - EXPECT_EQ(LacrosAvailability::kUserChoice, - DetermineLacrosAvailabilityFromPolicyValue(user, "")); - - // If the policy value is valid and there is no command line flag, the policy - // should be respected. - EXPECT_EQ(LacrosAvailability::kLacrosOnly, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_only")); - - // If the policy value is invalid, the choice is left to the user. - EXPECT_EQ( - LacrosAvailability::kUserChoice, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_tertiary")); - - // Whether LacrosGooglePolicyRollout is enabled or not makes no difference for - // normal users. - { - // Disable LacrosGooglePolicyRollout. - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures({}, {kLacrosGooglePolicyRollout}); - EXPECT_EQ( - LacrosAvailability::kLacrosDisallowed, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_disallowed")); - EXPECT_EQ(LacrosAvailability::kLacrosOnly, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_only")); - } - { - // Enable LacrosGooglePolicyRollout. - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures({kLacrosGooglePolicyRollout}, {}); - EXPECT_EQ( - LacrosAvailability::kLacrosDisallowed, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_disallowed")); - EXPECT_EQ(LacrosAvailability::kLacrosOnly, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_only")); - } -} - -struct LacrosAvailabilityInternalParams { - std::string test_name; - std::string test_account; -}; - -class LacrosAvailabilityInternalTest - : public LacrosAvailabilityTest, - public testing::WithParamInterface<LacrosAvailabilityInternalParams> {}; - -TEST_P(LacrosAvailabilityInternalTest, - DetermineLacrosAvailabilityFromPolicyValueInternal) { - const User* const user = AddRegularUser(GetParam().test_account); - - // For Googlers, the policy can be ignored by command line flag. - { - base::test::ScopedCommandLine command_line; - command_line.GetProcessCommandLine()->AppendSwitch( - ash::switches::kLacrosAvailabilityIgnore); - EXPECT_EQ(LacrosAvailability::kUserChoice, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_only")); - } - - // If there's no policy value, the choice is left to the user. - EXPECT_EQ(LacrosAvailability::kUserChoice, - DetermineLacrosAvailabilityFromPolicyValue(user, "")); - - // If the policy value is invalid, the choice is left to the user. - EXPECT_EQ( - LacrosAvailability::kUserChoice, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_tertiary")); - - { - // Disable LacrosGooglePolicyRollout. - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures({}, {kLacrosGooglePolicyRollout}); - - // For Googlers, if the GooglePolicyRollout feature is disabled, the choice - // is left to the user... - EXPECT_EQ(LacrosAvailability::kUserChoice, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_only")); - - // ...unless the policy is that Lacros is explicitly disallowed. - EXPECT_EQ( - LacrosAvailability::kLacrosDisallowed, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_disallowed")); - } - - { - // Enable LacrosGooglePolicyRollout. - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures({kLacrosGooglePolicyRollout}, {}); - - // For Googlers, if the GooglePolicyRollout feature is enabled, the policy - // should be respected. - EXPECT_EQ(LacrosAvailability::kLacrosOnly, - DetermineLacrosAvailabilityFromPolicyValue(user, "lacros_only")); - } -} - -INSTANTIATE_TEST_SUITE_P( - LacrosAvailabilityInternalTests, - LacrosAvailabilityInternalTest, - testing::ValuesIn<LacrosAvailabilityInternalParams>( - {{"Google_Internal", "user@google.com"}, - {"Enterprise", "user@managedchrome.com"}, - {"Robot_Account", "something@blah.iam.gserviceaccount.com"}, - {"Auth", "service@blah.apps.googleusercontent.com"}}), - [](const testing::TestParamInfo<LacrosAvailabilityInternalTest::ParamType>& - info) { return info.param.test_name; }); - -} // namespace ash::standalone_browser
diff --git a/chromeos/ash/components/standalone_browser/lacros_selection.cc b/chromeos/ash/components/standalone_browser/lacros_selection.cc index 46db268..d7a440a 100644 --- a/chromeos/ash/components/standalone_browser/lacros_selection.cc +++ b/chromeos/ash/components/standalone_browser/lacros_selection.cc
@@ -10,10 +10,10 @@ #include "base/containers/flat_map.h" #include "base/logging.h" #include "base/notreached.h" -#include "chromeos/ash/components/standalone_browser/lacros_availability.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/policy_constants.h" #include "components/user_manager/user_manager.h" +#include "google_apis/gaia/gaia_auth_util.h" namespace ash::standalone_browser { @@ -33,6 +33,18 @@ {"rootfs", LacrosSelectionPolicy::kRootfs}, }); +bool IsGoogleInternal(const user_manager::User* user) { + if (!user) { + return false; + } + + const std::string_view email = user->GetAccountId().GetUserEmail(); + return gaia::IsGoogleInternalAccountEmail(email) || + gaia::IsGoogleRobotAccountEmail(email) || + gaia::ExtractDomainName(gaia::SanitizeEmail(email)) == + "managedchrome.com"; +} + } // namespace void CacheLacrosSelection(const policy::PolicyMap& map) {
diff --git a/chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h b/chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h index 3bebdb4..726e2f8 100644 --- a/chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h +++ b/chromeos/ash/services/ime/public/cpp/shared_lib/interfaces.h
@@ -263,6 +263,11 @@ __attribute__((visibility("default"))) bool InitializeConnectionFactory( uint32_t receiver_connection_factory_handle); +// Bootstraps an implementation of a ConnectionFactory in the IME shared lib. +// Returns false if the connection attempt was unsuccessful. +__attribute__((visibility("default"))) bool InitializeConnectionFactoryV2( + uintptr_t receiver_connection_factory_handle); + // Returns whether there's a direct Mojo connection to an input method. __attribute__((visibility("default"))) bool IsInputMethodConnected();
diff --git a/chromeos/ash/services/orca/public/cpp/orca_entry.h b/chromeos/ash/services/orca/public/cpp/orca_entry.h index 4712bfec..51ed954 100644 --- a/chromeos/ash/services/orca/public/cpp/orca_entry.h +++ b/chromeos/ash/services/orca/public/cpp/orca_entry.h
@@ -40,6 +40,12 @@ uint32_t receiver_handle, OrcaLogger* logger); +// Returns whether the receiver was successfully bound. +OrcaBindServiceStatus __attribute__((visibility("default"))) +OrcaBindServiceV2(const MojoSystemThunks2* mojo_thunks, + uintptr_t receiver_handle, + OrcaLogger* logger); + // Resets the OrcaService. // If `OrcaBindService` was called, this function must be called to clean up // resources before calling OrcaBindService again or unloading the shared
diff --git a/chromeos/assistant/internal b/chromeos/assistant/internal index 4a629f0..366dc48 160000 --- a/chromeos/assistant/internal +++ b/chromeos/assistant/internal
@@ -1 +1 @@ -Subproject commit 4a629f07bb5192d38397131cbbec303d81ac1179 +Subproject commit 366dc486f8f18d097f22acb469b8eab41b14c9ad
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 4c09f4c..d447d4cd 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -3546,6 +3546,12 @@ <message name="IDS_SEA_PEN_FREEFORM_INTRODUCTION_DIALOG_FIRST_PARAGRAPH" desc="Option to fill in the SEA_PEN_INTRO_FIRST_PARAGRAPH of the IDS_SEA_PEN_INTRODUCTION_DIALOG_CONTENT."> When you select “Create with AI,” write a custom prompt. Or you can select “AI wallpapers,” to choose a theme and then select the underlined words to personalize your AI wallpaper. </message> + <message name="IDS_SEA_PEN_FREEFORM_ARIA_LABEL_SAMPLE_PROMPTS" desc="Aria label for a list of sample text prompts to be used to generate AI images."> + Sample prompts + </message> + <message name="IDS_SEA_PEN_FREEFORM_ARIA_LABEL_SUGGESTIONS" desc="Aria label for a list of suggestions that can be added to an AI text-to-image prompt (e.g. 'realistic photo')"> + Suggestions + </message> <!-- Sea Pen Templates (AUTOGENERATED - contact assistive-eng@google.com before editing) --> <!-- Wallpaper template glowscapes -->
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_ARIA_LABEL_SAMPLE_PROMPTS.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_ARIA_LABEL_SAMPLE_PROMPTS.png.sha1 new file mode 100644 index 0000000..132911e --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_ARIA_LABEL_SAMPLE_PROMPTS.png.sha1
@@ -0,0 +1 @@ +e1c326a1af66fa0508ab2a4bc40c33df69780216 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_ARIA_LABEL_SUGGESTIONS.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_ARIA_LABEL_SUGGESTIONS.png.sha1 new file mode 100644 index 0000000..ea3fac27 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_ARIA_LABEL_SUGGESTIONS.png.sha1
@@ -0,0 +1 @@ +0c22f392a9f4ebf89771677485ab1990810d09b4 \ No newline at end of file
diff --git a/chromeos/services/assistant/public/shared/BUILD.gn b/chromeos/services/assistant/public/shared/BUILD.gn index 825caae..b93a480 100644 --- a/chromeos/services/assistant/public/shared/BUILD.gn +++ b/chromeos/services/assistant/public/shared/BUILD.gn
@@ -24,3 +24,25 @@ deps = [ "//base:base" ] } + +source_set("new_entry_point_constants") { + if (is_chromeos && is_chrome_branded) { + deps = [ "//chromeos/assistant/internal:new_entry_point_constants" ] + } else { + deps = [ ":new_entry_point_constants_placeholder" ] + } +} + +source_set("new_entry_point_constants_placeholder") { + sources = [ "new_entry_point_constants.cc" ] + deps = [ + ":new_entry_point_constants_interface", + "//chrome/app/theme:theme_resources_grit", + ] +} + +source_set("new_entry_point_constants_interface") { + sources = [ "new_entry_point_constants.h" ] + + deps = [ "//base" ] +}
diff --git a/chromeos/services/assistant/public/shared/DEPS b/chromeos/services/assistant/public/shared/DEPS new file mode 100644 index 0000000..5805ad1 --- /dev/null +++ b/chromeos/services/assistant/public/shared/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "new_entry_point_constants.cc": [ + "+chrome/grit", + ] +}
diff --git a/chromeos/services/assistant/public/shared/new_entry_point_constants.cc b/chromeos/services/assistant/public/shared/new_entry_point_constants.cc new file mode 100644 index 0000000..f0dc01e --- /dev/null +++ b/chromeos/services/assistant/public/shared/new_entry_point_constants.cc
@@ -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. + +#include "chromeos/services/assistant/public/shared/new_entry_point_constants.h" + +#include "chrome/grit/theme_resources.h" + +namespace chromeos::assistant { + +// Use `IDR_PRODUCT_LOGO_32` as a placeholder. +const int kIconResourceId = IDR_PRODUCT_LOGO_32; + +} // namespace chromeos::assistant
diff --git a/chromeos/services/assistant/public/shared/new_entry_point_constants.h b/chromeos/services/assistant/public/shared/new_entry_point_constants.h new file mode 100644 index 0000000..38ca977 --- /dev/null +++ b/chromeos/services/assistant/public/shared/new_entry_point_constants.h
@@ -0,0 +1,16 @@ +// 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 CHROMEOS_SERVICES_ASSISTANT_PUBLIC_SHARED_NEW_ENTRY_POINT_CONSTANTS_H_ +#define CHROMEOS_SERVICES_ASSISTANT_PUBLIC_SHARED_NEW_ENTRY_POINT_CONSTANTS_H_ + +#include "base/component_export.h" + +namespace chromeos::assistant { + +COMPONENT_EXPORT(ASSISTANT_SERVICE_SHARED) extern const int kIconResourceId; + +} + +#endif // CHROMEOS_SERVICES_ASSISTANT_PUBLIC_SHARED_NEW_ENTRY_POINT_CONSTANTS_H_
diff --git a/clank b/clank index 5c28d3d..94e9a17 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 5c28d3db4b56fc58531352e6cb59a7c8db2db9e3 +Subproject commit 94e9a17ca9d53b1cd11478b59a5185931ca5d547
diff --git a/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc b/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc index 4e62fb5..b5598b3 100644 --- a/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc +++ b/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc
@@ -842,16 +842,15 @@ return result; } -std::vector<AutofillOfferData*> PaymentsDataManager::GetAutofillOffers() const { +std::vector<const AutofillOfferData*> PaymentsDataManager::GetAutofillOffers() + const { if (!IsAutofillWalletImportEnabled() || !IsAutofillPaymentMethodsEnabled()) { return {}; } - std::vector<AutofillOfferData*> result; - result.reserve(autofill_offer_data_.size()); - for (const auto& data : autofill_offer_data_) { - result.push_back(data.get()); - } - return result; + return base::ToVector( + autofill_offer_data_, + [](const std::unique_ptr<AutofillOfferData>& offer) + -> const AutofillOfferData* { return offer.get(); }); } std::vector<const AutofillOfferData*>
diff --git a/components/autofill/core/browser/data_manager/payments/payments_data_manager.h b/components/autofill/core/browser/data_manager/payments/payments_data_manager.h index 71859d57..336d8466 100644 --- a/components/autofill/core/browser/data_manager/payments/payments_data_manager.h +++ b/components/autofill/core/browser/data_manager/payments/payments_data_manager.h
@@ -226,7 +226,7 @@ const; // Returns autofill offer data, including card-linked and promo code offers. - virtual std::vector<AutofillOfferData*> GetAutofillOffers() const; + std::vector<const AutofillOfferData*> GetAutofillOffers() const; // Returns autofill offer data, but only promo code offers that are not // expired and that are for the given |origin|.
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc b/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc index 106435024..df987a3 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc +++ b/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc
@@ -87,7 +87,8 @@ .set_credit_card_save_manager( std::make_unique<TestCreditCardSaveManager>(autofill_client_.get())); autofill_client_->GetPaymentsAutofillClient()->set_autofill_offer_manager( - std::make_unique<AutofillOfferManager>(&personal_data())); + std::make_unique<AutofillOfferManager>( + &personal_data().payments_data_manager())); auto browser_autofill_manager = std::make_unique<TestBrowserAutofillManager>(autofill_driver_.get());
diff --git a/components/autofill/core/browser/payments/autofill_offer_manager.cc b/components/autofill/core/browser/payments/autofill_offer_manager.cc index 602b0d9..0d1174d 100644 --- a/components/autofill/core/browser/payments/autofill_offer_manager.cc +++ b/components/autofill/core/browser/payments/autofill_offer_manager.cc
@@ -4,6 +4,7 @@ #include "components/autofill/core/browser/payments/autofill_offer_manager.h" +#include "base/check_deref.h" #include "base/containers/contains.h" #include "base/functional/bind.h" #include "base/ranges/ranges.h" @@ -20,10 +21,10 @@ #include "ui/base/l10n/l10n_util.h" namespace autofill { -AutofillOfferManager::AutofillOfferManager(PersonalDataManager* personal_data) - : personal_data_(personal_data) { - payments_data_manager_observation.Observe( - &personal_data_->payments_data_manager()); +AutofillOfferManager::AutofillOfferManager( + PaymentsDataManager* payments_data_manager) + : payments_data_manager_(CHECK_DEREF(payments_data_manager)) { + payments_data_manager_observation.Observe(payments_data_manager); UpdateEligibleMerchantDomains(); } @@ -48,13 +49,12 @@ return {}; } - const std::vector<AutofillOfferData*> offers = - personal_data_->payments_data_manager().GetAutofillOffers(); const std::vector<const CreditCard*> cards = - personal_data_->payments_data_manager().GetCreditCards(); + payments_data_manager_->GetCreditCards(); AutofillOfferManager::CardLinkedOffersMap card_linked_offers_map; - for (AutofillOfferData* offer : offers) { + for (const AutofillOfferData* offer : + payments_data_manager_->GetAutofillOffers()) { // Ensure the offer is valid. if (!offer->IsActiveAndEligibleForOrigin( last_committed_primary_main_frame_origin)) { @@ -86,10 +86,10 @@ last_committed_primary_main_frame_url.DeprecatedGetOriginAsURL()); } -AutofillOfferData* AutofillOfferManager::GetOfferForUrl( - const GURL& last_committed_primary_main_frame_url) { - for (AutofillOfferData* offer : - personal_data_->payments_data_manager().GetAutofillOffers()) { +const AutofillOfferData* AutofillOfferManager::GetOfferForUrl( + const GURL& last_committed_primary_main_frame_url) const { + for (const AutofillOfferData* offer : + payments_data_manager_->GetAutofillOffers()) { if (offer->IsActiveAndEligibleForOrigin( last_committed_primary_main_frame_url.DeprecatedGetOriginAsURL())) { return offer; @@ -101,10 +101,8 @@ void AutofillOfferManager::UpdateEligibleMerchantDomains() { eligible_merchant_domains_.clear(); - std::vector<AutofillOfferData*> offers = - personal_data_->payments_data_manager().GetAutofillOffers(); - - for (auto* offer : offers) { + for (const AutofillOfferData* offer : + payments_data_manager_->GetAutofillOffers()) { eligible_merchant_domains_.insert(offer->GetMerchantOrigins().begin(), offer->GetMerchantOrigins().end()); }
diff --git a/components/autofill/core/browser/payments/autofill_offer_manager.h b/components/autofill/core/browser/payments/autofill_offer_manager.h index 0d877ba..b34507d 100644 --- a/components/autofill/core/browser/payments/autofill_offer_manager.h +++ b/components/autofill/core/browser/payments/autofill_offer_manager.h
@@ -25,7 +25,7 @@ class AutofillClient; class AutofillOfferData; class OfferNotificationHandler; -class PersonalDataManager; +class PaymentsDataManager; // Manages all Autofill related offers. One per browser context. Owned and // created by the AutofillOfferManagerFactory. @@ -33,9 +33,9 @@ public PaymentsDataManager::Observer { public: // Mapping from credit card guid id to offer data. - using CardLinkedOffersMap = std::map<std::string, AutofillOfferData*>; + using CardLinkedOffersMap = std::map<std::string, const AutofillOfferData*>; - AutofillOfferManager(PersonalDataManager* personal_data); + explicit AutofillOfferManager(PaymentsDataManager* payments_data_manager); ~AutofillOfferManager() override; AutofillOfferManager(const AutofillOfferManager&) = delete; AutofillOfferManager& operator=(const AutofillOfferManager&) = delete; @@ -47,18 +47,18 @@ void OnDidNavigateFrame(AutofillClient& client); // Gets a mapping between credit card's guid id and eligible card-linked - // offers on the |last_committed_primary_main_frame_url|. + // offers on the `last_committed_primary_main_frame_url`. CardLinkedOffersMap GetCardLinkedOffersMap( const GURL& last_committed_primary_main_frame_url) const; - // Returns true only if the domain of |last_committed_primary_main_frame_url| + // Returns true only if the domain of `last_committed_primary_main_frame_url` // has an offer. bool IsUrlEligible(const GURL& last_committed_primary_main_frame_url); // Returns the offer that contains the domain of - // |last_committed_primary_main_frame_url|. - AutofillOfferData* GetOfferForUrl( - const GURL& last_committed_primary_main_frame_url); + // `last_committed_primary_main_frame_url`. + const AutofillOfferData* GetOfferForUrl( + const GURL& last_committed_primary_main_frame_url) const; private: FRIEND_TEST_ALL_PREFIXES( @@ -68,11 +68,11 @@ friend class OfferNotificationBubbleViewsInteractiveUiTest; friend class OfferNotificationControllerAndroidBrowserTest; - // Queries |personal_data_| to reset the elements of - // |eligible_merchant_domains_| + // Queries `payments_data_manager_` to reset the elements of + // `eligible_merchant_domains_`. void UpdateEligibleMerchantDomains(); - raw_ptr<PersonalDataManager> personal_data_; + const raw_ref<PaymentsDataManager> payments_data_manager_; // This set includes all the eligible domains where offers are applicable. // This is used as a local cache and will be updated whenever the data in the
diff --git a/components/autofill/core/browser/payments/autofill_offer_manager_unittest.cc b/components/autofill/core/browser/payments/autofill_offer_manager_unittest.cc index 9bdca40..13c83c6 100644 --- a/components/autofill/core/browser/payments/autofill_offer_manager_unittest.cc +++ b/components/autofill/core/browser/payments/autofill_offer_manager_unittest.cc
@@ -56,8 +56,8 @@ personal_data_manager_.SetPrefService(autofill_client_.GetPrefs()); personal_data_manager_.SetSyncServiceForTest(&sync_service_); personal_data_manager_.SetPrefService(autofill_client_.GetPrefs()); - autofill_offer_manager_ = - std::make_unique<AutofillOfferManager>(&personal_data_manager_); + autofill_offer_manager_ = std::make_unique<AutofillOfferManager>( + &personal_data_manager_.payments_data_manager()); } CreditCard CreateCreditCard(std::string guid, @@ -223,7 +223,7 @@ card1, "5%", /*expired=*/false, {GURL("http://www.google.com"), GURL("http://www.youtube.com")})); - AutofillOfferData* result = + const AutofillOfferData* result = autofill_offer_manager_->GetOfferForUrl(GURL("http://www.example.com")); EXPECT_EQ(nullptr, result); } @@ -247,7 +247,7 @@ personal_data_manager_.test_payments_data_manager().AddAutofillOfferData( offer2); - AutofillOfferData* result = + const AutofillOfferData* result = autofill_offer_manager_->GetOfferForUrl(GURL("http://www.example.com")); EXPECT_EQ(offer2, *result); }
diff --git a/components/autofill/core/browser/payments/offer_notification_handler.cc b/components/autofill/core/browser/payments/offer_notification_handler.cc index d09c8b1e..f08b0a5 100644 --- a/components/autofill/core/browser/payments/offer_notification_handler.cc +++ b/components/autofill/core/browser/payments/offer_notification_handler.cc
@@ -16,7 +16,7 @@ namespace { -bool IsOfferValid(AutofillOfferData* offer) { +bool IsOfferValid(const AutofillOfferData* offer) { if (!offer) { return false; } @@ -51,7 +51,7 @@ // Currently, if a url has both types of offers and the promo code offer // is selected, no bubble will end up being shown (due to not yet being // implemented). - AutofillOfferData* offer = offer_manager_->GetOfferForUrl(url); + const AutofillOfferData* const offer = offer_manager_->GetOfferForUrl(url); CHECK(IsOfferValid(offer)); int64_t offer_id = offer->GetOfferId(); bool offer_id_has_shown_before = shown_notification_ids_.contains(offer_id);
diff --git a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc index fb9ebabe..e2a8783 100644 --- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc +++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc
@@ -97,7 +97,7 @@ // Returns the card-linked offers map with credit card guid as the key and the // pointer to the linked AutofillOfferData as the value. -std::map<std::string, AutofillOfferData*> GetCardLinkedOffers( +std::map<std::string, const AutofillOfferData*> GetCardLinkedOffers( const AutofillClient& autofill_client) { if (const AutofillOfferManager* offer_manager = autofill_client.GetPaymentsAutofillClient() @@ -739,7 +739,7 @@ .GetCreditCardsToSuggest(use_legacy_algorithm); // If a card has available card linked offers on the last committed url, rank // it to the top. - if (std::map<std::string, AutofillOfferData*> card_linked_offers_map = + if (std::map<std::string, const AutofillOfferData*> card_linked_offers_map = GetCardLinkedOffers(client); !card_linked_offers_map.empty()) { base::ranges::stable_sort( @@ -950,7 +950,7 @@ features::kAutofillEnablePaymentsFieldSwapping) && trigger_field.is_autofilled(); - std::map<std::string, AutofillOfferData*> card_linked_offers_map = + std::map<std::string, const AutofillOfferData*> card_linked_offers_map = GetCardLinkedOffers(client); summary.with_offer = !card_linked_offers_map.empty(); bool suppress_disused_cards =
diff --git a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc index 28ec77bb..8a980d1 100644 --- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc +++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc
@@ -211,7 +211,8 @@ payments_data().SetSyncServiceForTest(&sync_service_); autofill_client_.GetPaymentsAutofillClient()->set_autofill_offer_manager( std::make_unique<AutofillOfferManager>( - &autofill_client_.GetPersonalDataManager())); + &autofill_client_.GetPersonalDataManager() + .payments_data_manager())); credit_card_form_event_logger_ = std::make_unique<NiceMock<MockCreditCardFormEventLogger>>( &autofill_manager_);
diff --git a/components/bookmarks/browser/bookmark_model_unittest.cc b/components/bookmarks/browser/bookmark_model_unittest.cc index f1fa9a6..c154dee 100644 --- a/components/bookmarks/browser/bookmark_model_unittest.cc +++ b/components/bookmarks/browser/bookmark_model_unittest.cc
@@ -1483,17 +1483,16 @@ // Make sure folder is in the most recently modified. std::vector<const BookmarkNode*> most_recent_folders = - GetMostRecentlyModifiedUserFolders(model_.get(), 1); - ASSERT_EQ(1U, most_recent_folders.size()); - ASSERT_EQ(folder, most_recent_folders[0]); + GetMostRecentlyModifiedUserFolders(model_.get()); + ASSERT_FALSE(most_recent_folders.empty()); + EXPECT_EQ(folder, most_recent_folders[0]); // Nuke the folder and do another fetch, making sure folder isn't in the // returned list. model_->Remove(folder->parent()->children().front().get(), bookmarks::metrics::BookmarkEditSource::kOther, FROM_HERE); - most_recent_folders = GetMostRecentlyModifiedUserFolders(model_.get(), 1); - ASSERT_EQ(1U, most_recent_folders.size()); - ASSERT_NE(most_recent_folders[0], folder); + most_recent_folders = GetMostRecentlyModifiedUserFolders(model_.get()); + EXPECT_FALSE(base::Contains(most_recent_folders, folder)); } // Make sure MostRecentlyAddedEntries stays in sync.
diff --git a/components/bookmarks/browser/bookmark_utils.cc b/components/bookmarks/browser/bookmark_utils.cc index a2f349e..ae4baa3 100644 --- a/components/bookmarks/browser/bookmark_utils.cc +++ b/components/bookmarks/browser/bookmark_utils.cc
@@ -222,51 +222,120 @@ } std::vector<const BookmarkNode*> GetMostRecentlyModifiedUserFolders( - BookmarkModel* model, - size_t max_count) { + BookmarkModel* model) { std::vector<const BookmarkNode*> nodes; ui::TreeNodeIterator<const BookmarkNode> iterator( model->root_node(), base::BindRepeating(&PruneInvisibleFolders)); while (iterator.has_next()) { - const BookmarkNode* parent = iterator.Next(); - if (model->client()->IsNodeManaged(parent)) { + const BookmarkNode* const node = iterator.Next(); + // Filter out managed nodes and non-folders. + if (model->client()->IsNodeManaged(node) || !node->is_folder()) { continue; } - if (parent->is_folder() && parent->date_folder_modified() > Time()) { - if (max_count == 0) { - nodes.push_back(parent); - } else { - auto i = std::upper_bound(nodes.begin(), nodes.end(), parent, - &MoreRecentlyModified); - if (nodes.size() < max_count || i != nodes.end()) { - nodes.insert(i, parent); - while (nodes.size() > max_count) - nodes.pop_back(); - } - } - } // else case, the root node, which we don't care about or imported nodes - // (which have a time of 0). + nodes.push_back(node); } - if (nodes.size() < max_count) { - // Add the permanent nodes if there is space. The permanent nodes are the - // only children of the root_node. - const BookmarkNode* root_node = model->root_node(); + // TODO(crbug.com/354892429): Filter local permanent nodes if they shouldn't + // visible (user has permanent account nodes but no local bookmarks). - for (const auto& node : root_node->children()) { - if (node->IsVisible() && !model->client()->IsNodeManaged(node.get()) && - !base::Contains(nodes, node.get())) { - nodes.push_back(node.get()); + std::ranges::stable_sort(nodes, &MoreRecentlyModified); - if (nodes.size() == max_count) - break; - } - } - } return nodes; } +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) +RecentlyUsedFolders::RecentlyUsedFolders() = default; +RecentlyUsedFolders::RecentlyUsedFolders(const RecentlyUsedFolders&) = default; +RecentlyUsedFolders& RecentlyUsedFolders::operator=( + const RecentlyUsedFolders&) = default; +RecentlyUsedFolders::~RecentlyUsedFolders() = default; + +RecentlyUsedFolders GetMostRecentlyUsedFoldersForDisplay( + BookmarkModel* model, + const BookmarkNode* displayed_node) { + // `displayed_node` is meant to be a bookmark. Code below is not tested for + // folders. + CHECK(!displayed_node->is_folder()); + + // Max number of most recently used non-permanent-node folders. + static constexpr size_t kMaxMRUFolders = 5; + + std::vector<const BookmarkNode*> mru_nodes = + bookmarks::GetMostRecentlyModifiedUserFolders(model); + const BookmarkNode* const most_recent_node = + mru_nodes.empty() ? nullptr : mru_nodes[0]; + + // Special case the parent item, it'll either remain first or filtered out as + // a permanent node and added back later. + std::erase(mru_nodes, displayed_node->parent()); // No-op if not present. + mru_nodes.insert(mru_nodes.begin(), displayed_node->parent()); + + // Remove permanent nodes, they'll be re-added at the end if used later. + std::erase_if(mru_nodes, [](const BookmarkNode* mru_node) { + return mru_node->is_permanent_node(); + }); + + // Figure out which permanent nodes to add. + const bool account_nodes_exist = + model->account_bookmark_bar_node() != nullptr; + const std::vector<const BookmarkNode*> account_permanent_nodes( + {model->account_bookmark_bar_node(), model->account_other_node(), + model->account_mobile_node()}); + const std::vector<const BookmarkNode*> local_permanent_nodes( + {model->bookmark_bar_node(), model->other_node(), model->mobile_node()}); + + std::vector<const BookmarkNode*> permanent_nodes_included; + for (const BookmarkNode* permanent_node : + account_nodes_exist ? account_permanent_nodes : local_permanent_nodes) { + if (!permanent_node->IsVisible()) { + continue; + } + permanent_nodes_included.push_back(permanent_node); + } + + if (account_nodes_exist) { + // Add back the most recent node and the parent node if either of them are + // local permanent nodes. Permanent account nodes are preferred. + auto append_if_permanent_local_node = [model, &permanent_nodes_included]( + const BookmarkNode* mru_node) { + if (mru_node->is_permanent_node() && model->IsLocalOnlyNode(*mru_node)) { + permanent_nodes_included.push_back(mru_node); + } + }; + if (most_recent_node) { + append_if_permanent_local_node(most_recent_node); + } + if (displayed_node->parent() != most_recent_node) { + append_if_permanent_local_node(displayed_node->parent()); + } + } + + // Cap total number of non-permanent nodes to kMaxMRUFolders. + mru_nodes.resize(std::min(mru_nodes.size(), kMaxMRUFolders)); + + // Add permanent nodes at the end (note that these lists are both sorted and + // will remain sorted (permanent last) when split them up below. + mru_nodes.insert(mru_nodes.end(), permanent_nodes_included.begin(), + permanent_nodes_included.end()); + + // Split between account and local nodes if there are account nodes. + RecentlyUsedFolders result; + if (account_nodes_exist) { + std::vector<const BookmarkNode*> account_nodes; + std::vector<const BookmarkNode*> local_nodes; + for (const BookmarkNode* mru_node : mru_nodes) { + (model->IsLocalOnlyNode(*mru_node) ? result.local_nodes + : result.account_nodes) + .push_back(mru_node); + } + } else { + result.local_nodes = std::move(mru_nodes); + } + return result; +} +#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) + void GetMostRecentlyAddedEntries(BookmarkModel* model, size_t count, std::vector<const BookmarkNode*>* nodes) { @@ -484,8 +553,8 @@ } std::vector<const BookmarkNode*> nodes = - GetMostRecentlyModifiedUserFolders(model, 1); - DCHECK(!nodes.empty()); // This list is always padded with default folders. + GetMostRecentlyModifiedUserFolders(model); + CHECK(!nodes.empty()); return nodes[0]; }
diff --git a/components/bookmarks/browser/bookmark_utils.h b/components/bookmarks/browser/bookmark_utils.h index d65dcf4..7cabdcb 100644 --- a/components/bookmarks/browser/bookmark_utils.h +++ b/components/bookmarks/browser/bookmark_utils.h
@@ -14,6 +14,7 @@ #include "base/location.h" #include "base/memory/raw_ptr.h" #include "base/strings/utf_offset_string_conversions.h" +#include "build/build_config.h" #include "components/bookmarks/browser/bookmark_node_data.h" #include "components/bookmarks/common/bookmark_metrics.h" #include "components/prefs/pref_registry_simple.h" @@ -79,10 +80,53 @@ metrics::BookmarkEditSource source, bool is_off_the_record); -// Returns a vector containing up to `max_count` of the most recently modified -// user folders. This never returns an empty vector. +// Returns a vector containing of the most recently modified user folders. This +// never returns an empty vector. std::vector<const BookmarkNode*> GetMostRecentlyModifiedUserFolders( - BookmarkModel* model, size_t max_count); + BookmarkModel* model); + +// If this should be used on mobile we need to reevaluate if this implementation +// makes sense. See tests in bookmark_utils_unittest.cc which currently fail +// outside of desktop. Enable and update those if this is to be used on mobile. +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) +// Fields to use, split by account/local bookmarks. Used by +// RecentlyUsedFoldersComboModel. +struct RecentlyUsedFolders final { + RecentlyUsedFolders(); + RecentlyUsedFolders(const RecentlyUsedFolders&); + RecentlyUsedFolders& operator=(const RecentlyUsedFolders&); + ~RecentlyUsedFolders(); + + std::vector<const BookmarkNode*> account_nodes; + std::vector<const BookmarkNode*> local_nodes; +}; + +// Get recently-used-folders, including permanent nodes for display split up by +// "account" and "local" nodes. If there are no "account" bookmarks all entries +// are returned as local nodes even if sync'd, to be displayed as a single list +// without any headers/labels. +// +// In case of a mixed account and local bookmarks in the MRU nodes, this would +// display: +// - Account Bookmark Heading +// - Most recently used custom account bookmarks +// - Account permanent folders if visible +// - Local Bookmark Heading +// - Most recently used custom local bookmarks +// - Local permanent folder if it is the most recently used folder +// +// If MRU nodes are only local or account, this would display: +// - Most recently used custom +// - Account/Local and syncable permanent nodes +// +// Note: The parent of `display_node` is pushed on top of its corresponding list +// if it is a non-permanent folder or at the end if it is a permanent folder +// that is not already included. +RecentlyUsedFolders GetMostRecentlyUsedFoldersForDisplay( + BookmarkModel* model, + const BookmarkNode* displayed_node); + +#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) // Returns the most recently added bookmarks. This does not return folders, // only nodes of type url.
diff --git a/components/bookmarks/browser/bookmark_utils_unittest.cc b/components/bookmarks/browser/bookmark_utils_unittest.cc index 7fe121d7..d48870c 100644 --- a/components/bookmarks/browser/bookmark_utils_unittest.cc +++ b/components/bookmarks/browser/bookmark_utils_unittest.cc
@@ -13,8 +13,8 @@ #include "base/memory/raw_ptr.h" #include "base/scoped_observation.h" -#include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "build/build_config.h" #include "components/bookmarks/browser/base_bookmark_model_observer.h" @@ -24,6 +24,7 @@ #include "components/bookmarks/browser/bookmark_node_data.h" #include "components/bookmarks/common/bookmark_metrics.h" #include "components/bookmarks/test/test_bookmark_client.h" +#include "components/sync/base/features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/clipboard/clipboard.h" @@ -83,6 +84,10 @@ ++grouped_changes_ended_count_; } + // Some of these tests exercise account bookmarks. + base::test::ScopedFeatureList features_override_{ + syncer::kSyncEnableBookmarksInTransportMode}; + // Clipboard requires a full TaskEnvironment. base::test::TaskEnvironment task_environment_; @@ -336,5 +341,154 @@ /*adjustments=*/nullptr)); } +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) +// TODO(crbug.com/380820764): Break this up into smaller parts that: +// * Add more than 5 custom folders and make sure that permanent nodes still +// show. +// * Add 6 custom folders, make sure that only 5 show and that the folder past +// the cutoff starts showing if it's the parent of the currently showing +// bookmark. +// * Permanent nodes don't show up first even if they are the parents of the +// currently displaying bookmarks. +TEST_F(BookmarkUtilsTest, GetRecentlyUsedFoldersWithOnlyLocalBookmarks) { + std::unique_ptr<BookmarkModel> model(TestBookmarkClient::CreateModel()); + + const std::u16string title = u"Title"; + const GURL url("http://google.com"); + // Note that because `other_bookmark` is a child of a permanent node its use + // in GetMostRecentlyUsedFoldersForDisplay will not cause other_node() to be + // displayed before more recently modified folders. + const BookmarkNode* const other_bookmark = + model->AddURL(model->other_node(), 0, title, url); + + const bookmarks::RecentlyUsedFolders mru_bookmarks = + bookmarks::GetMostRecentlyUsedFoldersForDisplay(model.get(), + other_bookmark); + + EXPECT_TRUE(mru_bookmarks.account_nodes.empty()); + ASSERT_EQ(mru_bookmarks.local_nodes.size(), 2u); + // Permanent nodes display in a fixed order even if a bookmark in other_node() + // is currently displayed. + EXPECT_EQ(mru_bookmarks.local_nodes[0], model->bookmark_bar_node()); + EXPECT_EQ(mru_bookmarks.local_nodes[1], model->other_node()); + + const BookmarkNode* const folder1 = + model->AddFolder(model->other_node(), 0, u"Folder"); + const BookmarkNode* const folder2 = + model->AddFolder(model->other_node(), 0, u"Folder2"); + + model->SetDateFolderModified(folder1, + base::Time::FromMillisecondsSinceUnixEpoch(1)); + model->SetDateFolderModified(folder2, + base::Time::FromMillisecondsSinceUnixEpoch(2)); + + // folder2 is most recent + EXPECT_EQ(folder2, bookmarks::GetMostRecentlyUsedFoldersForDisplay( + model.get(), other_bookmark) + .local_nodes[0]); + + model->SetDateFolderModified(folder1, + base::Time::FromMillisecondsSinceUnixEpoch(3)); + // folder1 is most recent + EXPECT_EQ(folder1, bookmarks::GetMostRecentlyUsedFoldersForDisplay( + model.get(), other_bookmark) + .local_nodes[0]); + + const BookmarkNode* const bookmark = model->AddURL(folder2, 0, title, url); + + // folder2 as a parent to `bookmark` displays first even though not most + // recent. + EXPECT_EQ(folder2, bookmarks::GetMostRecentlyUsedFoldersForDisplay( + model.get(), bookmark) + .local_nodes[0]); +} + +// TODO(crbug.com/380820764): Break this up into smaller parts and make sure we +// have full coverage for: +// * Add more than 5 custom folders and make sure that account permanent nodes +// still show. +// * Add 6 custom folders, make sure that the oldest one is cut off (regardless +// of local or account). Make sure that the oldest one starts showing if it's +// the parent of a currently-showing bookmarl (and the second-oldest one is +// gone instead). +// * Make sure that local permanent nodes show up if most recently used and if +// the displayed bookmark is a child of that local node it's only added once +// (no duplicates). +// * Make sure local permanent nodes show up even if the displayed bookmark is +// another permanent node (both local permanent nodes can show). +// * Make sure that local permanent nodes show up last among local nodes even if +// they are the most recent ones or parents of the current currently-displayed +// bookmark. +// * Make sure local nodes are empty if there's >5 more recently used folders +// under account bookmarks. +TEST_F(BookmarkUtilsTest, GetRecentlyUsedFoldersWithAccountBookmarks) { + std::unique_ptr<BookmarkModel> model(TestBookmarkClient::CreateModel()); + model->CreateAccountPermanentFolders(); + + const std::u16string title = u"Title"; + const GURL url("http://google.com"); + // Note that because `bookmark_in_account_other_node` is a child of a + // permanent node its use in GetMostRecentlyUsedFoldersForDisplay will not + // cause account_other_node() to be displayed before more recently modified + // folders. + const BookmarkNode* const bookmark_in_account_other_node = + model->AddURL(model->account_other_node(), 0, title, url); + + bookmarks::RecentlyUsedFolders mru_bookmarks = + bookmarks::GetMostRecentlyUsedFoldersForDisplay( + model.get(), bookmark_in_account_other_node); + + // Permanent nodes are only added to account nodes by default. + ASSERT_EQ(mru_bookmarks.account_nodes.size(), 2u); + // No local nodes display by default. + EXPECT_TRUE(mru_bookmarks.local_nodes.empty()); + + // Permanent nodes display in a fixed order even if a bookmark in + // account_other_node() is currently displayed. + EXPECT_EQ(mru_bookmarks.account_nodes[0], model->account_bookmark_bar_node()); + EXPECT_EQ(mru_bookmarks.account_nodes[1], model->account_other_node()); + + const BookmarkNode* const local_other_bookmark = + model->AddURL(model->other_node(), 0, title, url); + + // Make sure local permanent nodes are not the most recently modified ones. + model->SetDateFolderModified(model->other_node(), + base::Time::FromMillisecondsSinceUnixEpoch(1)); + model->SetDateFolderModified(model->account_other_node(), + base::Time::FromMillisecondsSinceUnixEpoch(2)); + + mru_bookmarks = bookmarks::GetMostRecentlyUsedFoldersForDisplay( + model.get(), local_other_bookmark); + + // Local permanent node included when its children are being displayed. + ASSERT_EQ(mru_bookmarks.local_nodes.size(), 1u); + EXPECT_EQ(model->other_node(), mru_bookmarks.local_nodes[0]); + + // But not otherwise. + EXPECT_TRUE(bookmarks::GetMostRecentlyUsedFoldersForDisplay( + model.get(), bookmark_in_account_other_node) + .local_nodes.empty()); + + // The most recent folders under account and local are split up as the topmost + // entries. + const BookmarkNode* const account_folder = + model->AddFolder(model->account_other_node(), 0, u"Folder"); + const BookmarkNode* const local_folder = + model->AddFolder(model->other_node(), 0, u"Folder2"); + + model->SetDateFolderModified(account_folder, + base::Time::FromMillisecondsSinceUnixEpoch(20)); + // Older than `account_folder` but not filtered out (not permanent node). + model->SetDateFolderModified(local_folder, + base::Time::FromMillisecondsSinceUnixEpoch(10)); + + mru_bookmarks = bookmarks::GetMostRecentlyUsedFoldersForDisplay( + model.get(), bookmark_in_account_other_node); + EXPECT_EQ(account_folder, mru_bookmarks.account_nodes[0]); + EXPECT_EQ(local_folder, mru_bookmarks.local_nodes[0]); +} + +#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) + } // namespace } // namespace bookmarks
diff --git a/components/collaboration/internal/messaging/messaging_backend_service_impl.cc b/components/collaboration/internal/messaging/messaging_backend_service_impl.cc index ddded50..2fa2a4e 100644 --- a/components/collaboration/internal/messaging/messaging_backend_service_impl.cc +++ b/components/collaboration/internal/messaging/messaging_backend_service_impl.cc
@@ -205,6 +205,85 @@ return tab_metadata; } +TabMessageMetadata CreateTabMessageMetadataFromMessageOrTab( + const collaboration_pb::Message& message, + std::optional<tab_groups::SavedTabGroupTab> tab) { + if (tab) { + return CreateTabMessageMetadata(*tab); + } + + // Tab no longer available, so fill in what we can. + TabMessageMetadata tab_metadata = TabMessageMetadata(); + tab_metadata.last_known_url = message.tab_data().last_url(); + tab_metadata.sync_tab_id = + base::Uuid::ParseLowercase(message.tab_data().sync_tab_id()); + return tab_metadata; +} + +std::optional<tab_groups::SavedTabGroupTab> GetTabFromGroup( + const collaboration_pb::Message& message, + std::optional<tab_groups::SavedTabGroup> tab_group) { + if (!tab_group) { + return std::nullopt; + } + + const tab_groups::SavedTabGroupTab* tab = tab_group->GetTab( + base::Uuid::ParseCaseInsensitive(message.tab_data().sync_tab_id())); + if (tab) { + return std::make_optional(*tab); + } + return std::nullopt; +} + +DirtyType GetDirtyTypeFromPersistentNotificationTypeForQuery( + std::optional<PersistentNotificationType> type) { + if (!type) { + // Ask for all dirty messages. + return DirtyType::kAll; + } + if (*type == PersistentNotificationType::DIRTY_TAB) { + return DirtyType::kDot; + } else if (*type == PersistentNotificationType::CHIP) { + return DirtyType::kChip; + } else { + // Ask for all dirty messages. + return DirtyType::kAll; + } +} + +std::vector<PersistentMessage> RemoveDuplicateDirtyTabGroupMessages( + const std::vector<PersistentMessage>& messages) { + std::unordered_set<data_sharing::GroupId> dirty_tab_groups; + std::vector<PersistentMessage> result; + for (const auto& message : messages) { + if (message.type == PersistentNotificationType::DIRTY_TAB_GROUP) { + // We only want one DIRTY_TAB_GROUP per collaboration. + if (dirty_tab_groups.find(message.attribution.collaboration_id) == + dirty_tab_groups.end()) { + // This is the first one, so we add it. + dirty_tab_groups.emplace(message.attribution.collaboration_id); + result.emplace_back(message); + } + } else { + // If this is not a dirty tab group, add it to the result + result.emplace_back(message); + } + } + return result; +} + +std::vector<PersistentMessage> CreatePersistentMessagesForTypes( + PersistentMessage base_message, + const std::vector<PersistentNotificationType>& types) { + std::vector<PersistentMessage> messages; + for (const PersistentNotificationType& type : types) { + PersistentMessage message = base_message; + message.type = type; + messages.emplace_back(message); + } + return messages; +} + } // namespace MessagingBackendServiceImpl::MessagingBackendServiceImpl( @@ -233,8 +312,15 @@ void MessagingBackendServiceImpl::AddPersistentMessageObserver( PersistentMessageObserver* observer) { persistent_message_observers_.AddObserver(observer); - // TODO(345856704): Implement this and inform the observer if we have already - // initialized. + if (IsInitialized()) { + // We invoke the observer here in a re-entrant manner (documented in the + // public API), because at any time after adding the observer, new messages + // can come in, and they could arrive before the posted task with the + // callback executes, which means they could get calls to Display/Hide of + // PersistentMessages before they get the call to + // OnMessagingBackendServiceInitialized(). + observer->OnMessagingBackendServiceInitialized(); + } } void MessagingBackendServiceImpl::RemovePersistentMessageObserver( @@ -249,24 +335,67 @@ std::vector<PersistentMessage> MessagingBackendServiceImpl::GetMessagesForTab( tab_groups::EitherTabID tab_id, std::optional<PersistentNotificationType> type) { - // TODO(345856704): Implement this and DCHECK(IsInitialized()) and update - // interface description. - return {}; + std::optional<tab_groups::SavedTabGroupTab> tab = GetTabFromTabId(tab_id); + if (!tab) { + // Unable to find tab. + return {}; + } + + std::optional<tab_groups::SavedTabGroup> tab_group = + tab_group_sync_service_->GetGroup(tab->saved_group_guid()); + if (!tab_group) { + // Unable to find group. + return {}; + } + + std::optional<data_sharing::GroupId> collaboration_group_id = + GroupIdForTabGroup(*tab_group); + if (!collaboration_group_id) { + // Unable to find collaboration ID. + return {}; + } + + DirtyType dirty_type = + GetDirtyTypeFromPersistentNotificationTypeForQuery(type); + + std::optional<collaboration_pb::Message> message = + store_->GetDirtyMessageForTab(*collaboration_group_id, + tab->saved_tab_guid(), dirty_type); + if (!message) { + return {}; + } + return ConvertMessageToPersistentMessages( + *message, dirty_type, type, /*allow_dirty_tab_group_message=*/false); } std::vector<PersistentMessage> MessagingBackendServiceImpl::GetMessagesForGroup( tab_groups::EitherGroupID group_id, std::optional<PersistentNotificationType> type) { - // TODO(345856704): Implement this and DCHECK(IsInitialized()) and update - // interface description. - return {}; + std::optional<data_sharing::GroupId> collaboration_group_id = + GetCollaborationGroupId(group_id); + if (!collaboration_group_id) { + // Unable to find collaboration. + return {}; + } + + DirtyType dirty_type = + GetDirtyTypeFromPersistentNotificationTypeForQuery(type); + + std::vector<collaboration_pb::Message> messages = + store_->GetDirtyMessagesForGroup(*collaboration_group_id, dirty_type); + return RemoveDuplicateDirtyTabGroupMessages( + ConvertMessagesToPersistentMessages(messages, dirty_type, type)); } std::vector<PersistentMessage> MessagingBackendServiceImpl::GetMessages( std::optional<PersistentNotificationType> type) { - // TODO(345856704): Implement this and DCHECK(IsInitialized()) and update - // interface description. - return {}; + DirtyType dirty_type = + GetDirtyTypeFromPersistentNotificationTypeForQuery(type); + + std::vector<collaboration_pb::Message> messages = + store_->GetDirtyMessages(dirty_type); + return RemoveDuplicateDirtyTabGroupMessages( + ConvertMessagesToPersistentMessages(messages, dirty_type, type)); } std::vector<ActivityLogItem> MessagingBackendServiceImpl::GetActivityLog( @@ -389,6 +518,16 @@ CreateTabMessage(*collaboration_group_id, added_tab, collaboration_pb::TAB_ADDED, DirtyType::kDotAndChip); store_->AddMessage(message); + + PersistentMessage persistent_message = + CreatePersistentMessage(message, std::nullopt, added_tab, std::nullopt); + + NotifyDisplayPersistentMessagesForTypes( + persistent_message, {PersistentNotificationType::CHIP, + PersistentNotificationType::DIRTY_TAB}); + + DisplayOrHideTabGroupDirtyDotForTabGroup(*collaboration_group_id, + added_tab.saved_group_guid()); } void MessagingBackendServiceImpl::OnTabRemoved( @@ -404,6 +543,21 @@ CreateTabMessage(*collaboration_group_id, removed_tab, collaboration_pb::TAB_REMOVED, DirtyType::kNone); store_->AddMessage(message); + + // Tab no longer available, so should not contribute to any dirty tab groups. + store_->ClearDirtyMessageForTab(*collaboration_group_id, + removed_tab.saved_tab_guid(), + DirtyType::kDotAndChip); + + PersistentMessage persistent_message = + CreatePersistentMessage(message, std::nullopt, removed_tab, std::nullopt); + + NotifyHidePersistentMessagesForTypes(persistent_message, + {PersistentNotificationType::CHIP, + PersistentNotificationType::DIRTY_TAB}); + + DisplayOrHideTabGroupDirtyDotForTabGroup(*collaboration_group_id, + removed_tab.saved_group_guid()); } void MessagingBackendServiceImpl::OnTabUpdated( @@ -419,10 +573,62 @@ CreateTabMessage(*collaboration_group_id, updated_tab, collaboration_pb::TAB_UPDATED, DirtyType::kDotAndChip); store_->AddMessage(message); + + PersistentMessage persistent_message = + CreatePersistentMessage(message, std::nullopt, updated_tab, std::nullopt); + + NotifyDisplayPersistentMessagesForTypes( + persistent_message, {PersistentNotificationType::CHIP, + PersistentNotificationType::DIRTY_TAB}); + + DisplayOrHideTabGroupDirtyDotForTabGroup(*collaboration_group_id, + updated_tab.saved_group_guid()); } void MessagingBackendServiceImpl::OnTabSelected( - std::optional<tab_groups::SavedTabGroupTab> selected_tab) {} + std::optional<tab_groups::SavedTabGroupTab> selected_tab) { + last_selected_tab_ = selected_tab; + if (!selected_tab) { + // A tab outside shared tab groups was selected. + // TODO(crbug.com/378422466): Maybe clear chip on desktop here. + return; + } + + std::optional<data_sharing::GroupId> collaboration_group_id = + GetCollaborationGroupIdForTab(selected_tab.value()); + + if (!collaboration_group_id) { + // Unable to find the collaboration, so nothing to clear. + return; + } + + // TODO(crbug.com/378422466): Do not clear chip on desktop, until the user + // goes away from the tab. + store_->ClearDirtyMessageForTab(*collaboration_group_id, + selected_tab->saved_tab_guid(), + DirtyType::kDotAndChip); + + std::optional<tab_groups::SavedTabGroup> tab_group = + tab_group_sync_service_->GetGroup(selected_tab->saved_group_guid()); + + // Specialized handling of creating a PersistentMessage, since we do not have + // a stored collaboration_pb::Message available. + PersistentMessage persistent_message; + persistent_message.collaboration_event = CollaborationEvent::UNDEFINED; + persistent_message.attribution = MessageAttribution(); + persistent_message.attribution.collaboration_id = *collaboration_group_id; + persistent_message.attribution.tab_group_metadata = + CreateTabGroupMessageMetadata(*tab_group); + persistent_message.attribution.tab_metadata = + CreateTabMessageMetadata(*selected_tab); + + NotifyHidePersistentMessagesForTypes(persistent_message, + {PersistentNotificationType::CHIP, + PersistentNotificationType::DIRTY_TAB}); + + DisplayOrHideTabGroupDirtyDotForTabGroup(*collaboration_group_id, + selected_tab->saved_group_guid()); +} void MessagingBackendServiceImpl::OnGroupAdded( const data_sharing::GroupId& group_id, @@ -553,7 +759,8 @@ data_sharing::GroupId collaboration_group_id(message.collaboration_id()); std::optional<GaiaId> gaia_id = GetGaiaIdFromMessage(message); - std::optional<data_sharing::GroupMember> group_member; + std::optional<data_sharing::GroupMember> group_member = + GetGroupMemberFromGaiaId(collaboration_group_id, gaia_id); if (gaia_id) { std::optional<std::string> user_name_for_display = GetDisplayNameForUserInGroup(collaboration_group_id, *gaia_id, @@ -561,15 +768,10 @@ if (user_name_for_display) { item.user_display_name = *user_name_for_display; } - std::optional<data_sharing::GroupMemberPartialData> group_member_data = - data_sharing_service_->GetPossiblyRemovedGroupMember( - collaboration_group_id, *gaia_id); - if (group_member_data) { - group_member = group_member_data->ToGroupMember(); - } } - // TODO(nyquist): Compare GaiaId with current user in this profile. + // TODO(crbug.com/380517719): Compare GaiaId with current user in this + // profile. item.user_is_self = false; // By default, we use an empty description. This is special cased below. @@ -589,28 +791,15 @@ item.show_favicon = true; std::optional<tab_groups::SavedTabGroup> tab_group = - tab_group_sync_service_->GetGroup(base::Uuid::ParseCaseInsensitive( - message.tab_data().sync_tab_group_id())); - if (!tab_group) { - break; - } + GetTabGroupFromMessage(message); item.activity_metadata.tab_group_metadata = - CreateTabGroupMessageMetadata(*tab_group); - tab_groups::SavedTabGroupTab* tab = tab_group->GetTab( - base::Uuid::ParseCaseInsensitive(message.tab_data().sync_tab_id())); - GURL url; - if (tab) { - item.activity_metadata.tab_metadata = CreateTabMessageMetadata(*tab); - url = tab->url(); - } else { - // Tab no longer available, so fill in what we can. - item.activity_metadata.tab_metadata = TabMessageMetadata(); - item.activity_metadata.tab_metadata->last_known_url = - message.tab_data().last_url(); - item.activity_metadata.tab_metadata->sync_tab_id = - base::Uuid::ParseLowercase(message.tab_data().sync_tab_id()); - url = GURL(message.tab_data().last_url()); - } + CreateTabGroupMessageMetadataFromMessageOrTabGroup(message, + tab_group); + item.activity_metadata.tab_metadata = + CreateTabMessageMetadataFromMessageOrTab( + message, GetTabFromGroup(message, tab_group)); + // We are guaranteed to have a value for `last_known_url`. + GURL url = GURL(*item.activity_metadata.tab_metadata->last_known_url); item.activity_metadata.triggering_user = group_member; item.description = @@ -621,26 +810,9 @@ } case MessageCategory::kTabGroup: { item.activity_metadata.triggering_user = group_member; - std::optional<tab_groups::SavedTabGroup> tab_group; - if (!message.tab_group_data().sync_tab_group_id().empty()) { - tab_group = - tab_group_sync_service_->GetGroup(base::Uuid::ParseLowercase( - message.tab_group_data().sync_tab_group_id())); - } - if (tab_group) { - item.activity_metadata.tab_group_metadata = - CreateTabGroupMessageMetadata(*tab_group); - } else { - item.activity_metadata.tab_group_metadata = TabGroupMessageMetadata(); - std::optional<std::u16string> previous_title = - tab_group_sync_service_ - ->GetTitleForPreviouslyExistingSharedTabGroup( - ToCollaborationId(collaboration_group_id)); - if (previous_title) { - item.activity_metadata.tab_group_metadata->last_known_title = - base::UTF16ToUTF8(*previous_title); - } - } + item.activity_metadata.tab_group_metadata = + CreateTabGroupMessageMetadataFromMessageOrTabGroup(message, + std::nullopt); // Only tab group name changes have specialized description. if (message.event_type() == collaboration_pb::TAB_GROUP_NAME_UPDATED) { @@ -676,4 +848,277 @@ return GroupIdForTabGroup(*tab_group); } +TabGroupMessageMetadata +MessagingBackendServiceImpl::CreateTabGroupMessageMetadataFromCollaborationId( + std::optional<tab_groups::SavedTabGroup> tab_group, + std::optional<data_sharing::GroupId> collaboration_group_id) { + if (tab_group) { + return CreateTabGroupMessageMetadata(*tab_group); + } + + TabGroupMessageMetadata tab_group_metadata = TabGroupMessageMetadata(); + if (!collaboration_group_id) { + return tab_group_metadata; + } + std::optional<std::u16string> previous_title = + tab_group_sync_service_->GetTitleForPreviouslyExistingSharedTabGroup( + ToCollaborationId(data_sharing::GroupId(*collaboration_group_id))); + if (previous_title) { + tab_group_metadata.last_known_title = base::UTF16ToUTF8(*previous_title); + } + return tab_group_metadata; +} + +TabGroupMessageMetadata +MessagingBackendServiceImpl::CreateTabGroupMessageMetadataFromMessageOrTabGroup( + const collaboration_pb::Message& message, + const std::optional<tab_groups::SavedTabGroup>& tab_group) { + if (tab_group) { + return CreateTabGroupMessageMetadata(*tab_group); + } + + return CreateTabGroupMessageMetadataFromCollaborationId( + GetTabGroupFromMessage(message), + data_sharing::GroupId(message.collaboration_id())); +} + +std::optional<tab_groups::SavedTabGroup> +MessagingBackendServiceImpl::GetTabGroupFromMessage( + const collaboration_pb::Message& message) { + std::string sync_tab_group_id = message.tab_group_data().sync_tab_group_id(); + if (sync_tab_group_id.empty()) { + // Try from tab data next. + sync_tab_group_id = message.tab_data().sync_tab_group_id(); + } + + if (sync_tab_group_id.empty()) { + return std::nullopt; + } + + return tab_group_sync_service_->GetGroup( + base::Uuid::ParseLowercase(sync_tab_group_id)); +} + +std::optional<data_sharing::GroupMember> +MessagingBackendServiceImpl::GetGroupMemberFromGaiaId( + const data_sharing::GroupId& collaboration_group_id, + std::optional<GaiaId> gaia_id) { + if (!gaia_id) { + return std::nullopt; + } + + std::optional<data_sharing::GroupMemberPartialData> group_member_data = + data_sharing_service_->GetPossiblyRemovedGroupMember( + collaboration_group_id, *gaia_id); + if (group_member_data) { + return group_member_data->ToGroupMember(); + } + return std::nullopt; +} + +std::optional<data_sharing::GroupId> +MessagingBackendServiceImpl::GetCollaborationGroupId( + tab_groups::EitherGroupID group_id) { + std::optional<tab_groups::SavedTabGroup> tab_group = + tab_group_sync_service_->GetGroup(group_id); + if (!tab_group) { + return std::nullopt; + } + return GroupIdForTabGroup(*tab_group); +} + +std::optional<tab_groups::SavedTabGroupTab> +MessagingBackendServiceImpl::GetTabFromTabId(tab_groups::EitherTabID tab_id) { + if (std::holds_alternative<base::Uuid>(tab_id)) { + base::Uuid sync_tab_id = std::get<base::Uuid>(tab_id); + for (const auto& group : tab_group_sync_service_->GetAllGroups()) { + if (group.ContainsTab(sync_tab_id)) { + return std::make_optional(*group.GetTab(sync_tab_id)); + } + } + } + if (std::holds_alternative<tab_groups::LocalTabID>(tab_id)) { + tab_groups::LocalTabID local_tab_id = + std::get<tab_groups::LocalTabID>(tab_id); + for (const auto& group : tab_group_sync_service_->GetAllGroups()) { + if (group.ContainsTab(local_tab_id)) { + return std::make_optional(*group.GetTab(local_tab_id)); + } + } + } + return std::nullopt; +} + +std::vector<PersistentMessage> +MessagingBackendServiceImpl::ConvertMessagesToPersistentMessages( + const std::vector<collaboration_pb::Message>& messages, + DirtyType lookup_dirty_type, + const std::optional<PersistentNotificationType>& type) { + std::vector<PersistentMessage> result; + for (const auto& message : messages) { + // Each DB message might result in multiple individual PersistentMessages. + std::vector<PersistentMessage> converted_messages = + ConvertMessageToPersistentMessages( + message, lookup_dirty_type, type, + /*allow_dirty_tab_group_message=*/true); + result.insert(result.end(), converted_messages.begin(), + converted_messages.end()); + } + return result; +} + +std::vector<PersistentMessage> +MessagingBackendServiceImpl::ConvertMessageToPersistentMessages( + const collaboration_pb::Message& message, + DirtyType lookup_dirty_type, + const std::optional<PersistentNotificationType>& type, + bool allow_dirty_tab_group_message) { + std::vector<PersistentMessage> persistent_messages; + if (GetMessageCategory(message) != MessageCategory::kTab) { + return persistent_messages; + } + + // Helper local variables to increase readability of code below. + bool has_dirty_chip = message.dirty() & static_cast<int>(DirtyType::kChip); + bool looking_for_dirty_chip = lookup_dirty_type == DirtyType::kAll || + lookup_dirty_type == DirtyType::kChip; + bool has_dirty_dot = message.dirty() & static_cast<int>(DirtyType::kDot); + bool looking_for_dirty_dot = lookup_dirty_type == DirtyType::kAll || + lookup_dirty_type == DirtyType::kDot; + bool add_dirty_tab_messages = + !type || *type == PersistentNotificationType::DIRTY_TAB; + bool add_dirty_tab_group_messages = + allow_dirty_tab_group_message && + (!type || *type == PersistentNotificationType::DIRTY_TAB_GROUP); + bool has_dirty_tab_messages_in_group = + !store_ + ->GetDirtyMessagesForGroup( + data_sharing::GroupId(message.collaboration_id()), + DirtyType::kDot) + .empty(); + + std::optional<tab_groups::SavedTabGroup> tab_group = + GetTabGroupFromMessage(message); + + if (has_dirty_chip && looking_for_dirty_chip) { + persistent_messages.push_back(CreatePersistentMessage( + message, tab_group, std::nullopt, PersistentNotificationType::CHIP)); + } + + if (has_dirty_dot && looking_for_dirty_dot) { + if (add_dirty_tab_messages) { + persistent_messages.push_back( + CreatePersistentMessage(message, tab_group, std::nullopt, + PersistentNotificationType::DIRTY_TAB)); + } + + if (add_dirty_tab_group_messages && has_dirty_tab_messages_in_group) { + PersistentMessage persistent_message = + CreatePersistentMessage(message, tab_group, std::nullopt, + PersistentNotificationType::DIRTY_TAB_GROUP); + // Override collaboration event and tab metadata since this is about + // a group. + persistent_message.collaboration_event = CollaborationEvent::UNDEFINED; + persistent_message.attribution.tab_metadata = TabMessageMetadata(); + persistent_messages.push_back(persistent_message); + } + } + return persistent_messages; +} + +PersistentMessage MessagingBackendServiceImpl::CreatePersistentMessage( + const collaboration_pb::Message& message, + const std::optional<tab_groups::SavedTabGroup>& tab_group, + const std::optional<tab_groups::SavedTabGroupTab>& tab, + const std::optional<PersistentNotificationType>& type) { + PersistentMessage persistent_message; + persistent_message.collaboration_event = + ToCollaborationEvent(message.event_type()); + persistent_message.attribution = MessageAttribution(); + persistent_message.attribution.collaboration_id = + data_sharing::GroupId(message.collaboration_id()); + std::optional<tab_groups::SavedTabGroup> stack_tab_group = tab_group; + if (!tab_group && tab) { + stack_tab_group = + tab_group_sync_service_->GetGroup(tab->saved_group_guid()); + } + persistent_message.attribution.tab_group_metadata = + CreateTabGroupMessageMetadataFromMessageOrTabGroup(message, tab_group); + persistent_message.attribution.tab_metadata = + CreateTabMessageMetadataFromMessageOrTab( + message, tab.has_value() ? tab : GetTabFromGroup(message, tab_group)); + persistent_message.attribution.triggering_user = GetGroupMemberFromGaiaId( + data_sharing::GroupId(message.collaboration_id()), + GaiaId(message.triggering_user_gaia_id())); + if (type) { + persistent_message.type = *type; + } + return persistent_message; +} + +void MessagingBackendServiceImpl::NotifyDisplayPersistentMessagesForTypes( + const PersistentMessage& base_message, + const std::vector<PersistentNotificationType>& types) { + for (const PersistentMessage& message : + CreatePersistentMessagesForTypes(base_message, types)) { + persistent_message_observers_.Notify( + &PersistentMessageObserver::DisplayPersistentMessage, message); + } +} + +void MessagingBackendServiceImpl::NotifyHidePersistentMessagesForTypes( + const PersistentMessage& base_message, + const std::vector<PersistentNotificationType>& types) { + for (const PersistentMessage& message : + CreatePersistentMessagesForTypes(base_message, types)) { + persistent_message_observers_.Notify( + &PersistentMessageObserver::HidePersistentMessage, message); + } +} + +void MessagingBackendServiceImpl::DisplayOrHideTabGroupDirtyDotForTabGroup( + const data_sharing::GroupId& collaboration_group_id, + base::Uuid shared_tab_group_id) { + bool hasDirtyDotMessagesForGroup = + !store_->GetDirtyMessagesForGroup(collaboration_group_id, DirtyType::kDot) + .empty(); + + std::optional<tab_groups::SavedTabGroup> tab_group = + tab_group_sync_service_->GetGroup(shared_tab_group_id); + PersistentMessage persistent_message; + + persistent_message.attribution = MessageAttribution(); + persistent_message.attribution.collaboration_id = collaboration_group_id; + + if (tab_group) { + persistent_message.attribution.tab_group_metadata = + CreateTabGroupMessageMetadata(*tab_group); + } else { + // Unable to find the group, so we fill in what we known. + persistent_message.attribution.tab_group_metadata = + TabGroupMessageMetadata(); + persistent_message.attribution.tab_group_metadata->sync_tab_group_id = + shared_tab_group_id; + std::optional<std::u16string> previous_title = + tab_group_sync_service_->GetTitleForPreviouslyExistingSharedTabGroup( + ToCollaborationId(collaboration_group_id)); + if (previous_title) { + persistent_message.attribution.tab_group_metadata->last_known_title = + base::UTF16ToUTF8(*previous_title); + } + } + + persistent_message.collaboration_event = CollaborationEvent::UNDEFINED; + // We do not fill in triggering user or affeted user, because any action + // related to dirty tabs could have been relevant here. + + if (hasDirtyDotMessagesForGroup) { + NotifyDisplayPersistentMessagesForTypes( + persistent_message, {PersistentNotificationType::DIRTY_TAB_GROUP}); + } else { + NotifyHidePersistentMessagesForTypes( + persistent_message, {PersistentNotificationType::DIRTY_TAB_GROUP}); + } +} + } // namespace collaboration::messaging
diff --git a/components/collaboration/internal/messaging/messaging_backend_service_impl.h b/components/collaboration/internal/messaging/messaging_backend_service_impl.h index 33ed750..276326e 100644 --- a/components/collaboration/internal/messaging/messaging_backend_service_impl.h +++ b/components/collaboration/internal/messaging/messaging_backend_service_impl.h
@@ -12,6 +12,7 @@ #include "base/observer_list.h" #include "base/scoped_observation.h" #include "components/collaboration/internal/messaging/data_sharing_change_notifier.h" +#include "components/collaboration/internal/messaging/storage/messaging_backend_store.h" #include "components/collaboration/internal/messaging/tab_group_change_notifier.h" #include "components/collaboration/public/messaging/message.h" #include "components/collaboration/public/messaging/messaging_backend_service.h" @@ -116,6 +117,72 @@ std::optional<data_sharing::GroupId> GetCollaborationGroupIdForTab( const tab_groups::SavedTabGroupTab& tab); + // Uses the provided data to create TabGroupMessageMetadata. + TabGroupMessageMetadata CreateTabGroupMessageMetadataFromCollaborationId( + std::optional<tab_groups::SavedTabGroup> tab_group, + std::optional<data_sharing::GroupId> collaboration_group_id); + + // Creates a TabGroupMessageMetadata based on the sources given as input. + TabGroupMessageMetadata CreateTabGroupMessageMetadataFromMessageOrTabGroup( + const collaboration_pb::Message& message, + const std::optional<tab_groups::SavedTabGroup>& tab_group); + + // Tries to retrieve the correct tab group based on data in the Message. + std::optional<tab_groups::SavedTabGroup> GetTabGroupFromMessage( + const collaboration_pb::Message& message); + + // Uses the available data to look up a GroupMember. + std::optional<data_sharing::GroupMember> GetGroupMemberFromGaiaId( + const data_sharing::GroupId& collaboration_group_id, + std::optional<GaiaId> gaia_id); + + // Retrieves the relevant tab group from the TabGroupSyncService and looks up + // its collaboration group id. + std::optional<data_sharing::GroupId> GetCollaborationGroupId( + tab_groups::EitherGroupID group_id); + + // Looks up the tab from tab group sync service. + std::optional<tab_groups::SavedTabGroupTab> GetTabFromTabId( + tab_groups::EitherTabID tab_id); + + // Convert all the provided stored Messages to PersistentMessages. + std::vector<PersistentMessage> ConvertMessagesToPersistentMessages( + const std::vector<collaboration_pb::Message>& messages, + DirtyType lookup_dirty_type, + const std::optional<PersistentNotificationType>& type); + + // Convert a single stored Message to PersistentMessages. Each stored message + // may result in multiple PersistentMessages, e.g. both CHIP and DIRTY_TAB. + std::vector<PersistentMessage> ConvertMessageToPersistentMessages( + const collaboration_pb::Message& message, + DirtyType lookup_dirty_type, + const std::optional<PersistentNotificationType>& type, + bool allow_dirty_tab_group_message); + + // Creates a PersistentMessage based on the provided information. + PersistentMessage CreatePersistentMessage( + const collaboration_pb::Message& message, + const std::optional<tab_groups::SavedTabGroup>& tab_group, + const std::optional<tab_groups::SavedTabGroupTab>& tab, + const std::optional<PersistentNotificationType>& type); + + // Creates individual messages based on `base_message` per type, and notifies + // oservers to display the messages. + void NotifyDisplayPersistentMessagesForTypes( + const PersistentMessage& base_message, + const std::vector<PersistentNotificationType>& types); + + // Creates individual messages based on `base_message` per type, and notifies + // oservers to hide the messages. + void NotifyHidePersistentMessagesForTypes( + const PersistentMessage& base_message, + const std::vector<PersistentNotificationType>& types); + + // Notifies observers to display or hide the dirty dot for a tab group. + void DisplayOrHideTabGroupDirtyDotForTabGroup( + const data_sharing::GroupId& collaboration_group_id, + base::Uuid shared_tab_group_id); + // Provides functionality to go from observing the TabGroupSyncService to // a delta based observer API. std::unique_ptr<TabGroupChangeNotifier> tab_group_change_notifier_; @@ -142,6 +209,10 @@ // data sharing service. DataSharingChangeNotifier::FlushCallback data_sharing_flush_callback_; + // The last tab the user selected, or `std::nullopt` if it was outside a + // shared tab group. + std::optional<tab_groups::SavedTabGroupTab> last_selected_tab_; + // Service providing information about tabs and tab groups. raw_ptr<tab_groups::TabGroupSyncService> tab_group_sync_service_;
diff --git a/components/collaboration/internal/messaging/messaging_backend_service_impl_unittest.cc b/components/collaboration/internal/messaging/messaging_backend_service_impl_unittest.cc index dfd52e9..c701b73 100644 --- a/components/collaboration/internal/messaging/messaging_backend_service_impl_unittest.cc +++ b/components/collaboration/internal/messaging/messaging_backend_service_impl_unittest.cc
@@ -20,6 +20,7 @@ #include "components/data_sharing/test_support/mock_data_sharing_service.h" #include "components/saved_tab_groups/public/saved_tab_group_tab.h" #include "components/saved_tab_groups/public/tab_group_sync_service.h" +#include "components/saved_tab_groups/public/types.h" #include "components/saved_tab_groups/test_support/mock_tab_group_sync_service.h" #include "components/tab_groups/tab_group_color.h" #include "google_apis/gaia/gaia_id.h" @@ -861,4 +862,202 @@ activity_log[2].activity_metadata.triggering_user->email); } +TEST_F(MessagingBackendServiceImplTest, TestGetMessagesNoMessages) { + CreateAndInitializeService(); + + std::vector<collaboration_pb::Message> db_messages; + + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessages(DirtyType::kAll)) + .WillOnce(Return(db_messages)); + std::vector<PersistentMessage> messages = service_->GetMessages(std::nullopt); + EXPECT_EQ(0u, messages.size()); +} + +TEST_F(MessagingBackendServiceImplTest, TestGetMessagesOneMessage) { + CreateAndInitializeService(); + + data_sharing::GroupId collaboration_group_id = + data_sharing::GroupId("my group id"); + base::Time now = base::Time::Now(); + + std::vector<collaboration_pb::Message> db_messages; + + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessages(DirtyType::kAll)) + .WillOnce(Return(db_messages)); + std::vector<PersistentMessage> messages = service_->GetMessages(std::nullopt); + EXPECT_EQ(0u, messages.size()); + + collaboration_pb::Message message = CreateStoredMessage( + collaboration_group_id, collaboration_pb::EventType::TAB_ADDED, + DirtyType::kDotAndChip, now); + db_messages.emplace_back(message); + + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessages(DirtyType::kAll)) + .WillOnce(Return(db_messages)); + // Our service will need to also query for dirty dot messages for a group. + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessagesForGroup(collaboration_group_id, DirtyType::kDot)) + .WillOnce(Return(db_messages)); + messages = service_->GetMessages(std::nullopt); + // Should become two PersistentMessages for the tab, and one for the tab + // group. + ASSERT_EQ(3u, messages.size()); + EXPECT_EQ(CollaborationEvent::TAB_ADDED, messages.at(0).collaboration_event); + EXPECT_EQ(PersistentNotificationType::CHIP, messages.at(0).type); + EXPECT_EQ(CollaborationEvent::TAB_ADDED, messages.at(1).collaboration_event); + EXPECT_EQ(PersistentNotificationType::DIRTY_TAB, messages.at(1).type); + EXPECT_EQ(CollaborationEvent::UNDEFINED, messages.at(2).collaboration_event); + EXPECT_EQ(PersistentNotificationType::DIRTY_TAB_GROUP, messages.at(2).type); +} + +TEST_F(MessagingBackendServiceImplTest, TestGetMessagesTwoMessages) { + CreateAndInitializeService(); + + data_sharing::GroupId collaboration_group_id = + data_sharing::GroupId("my group id"); + base::Time now = base::Time::Now(); + + std::vector<collaboration_pb::Message> db_messages; + + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessages(DirtyType::kAll)) + .WillOnce(Return(db_messages)); + std::vector<PersistentMessage> messages = service_->GetMessages(std::nullopt); + EXPECT_EQ(0u, messages.size()); + + collaboration_pb::Message message1 = CreateStoredMessage( + collaboration_group_id, collaboration_pb::EventType::TAB_ADDED, + DirtyType::kDotAndChip, now); + collaboration_pb::Message message2 = CreateStoredMessage( + collaboration_group_id, collaboration_pb::EventType::TAB_UPDATED, + DirtyType::kDotAndChip, now); + db_messages.emplace_back(message1); + db_messages.emplace_back(message2); + + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessages(DirtyType::kAll)) + .WillRepeatedly(Return(db_messages)); + // Our service will need to also query for dirty dot messages for a group. + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessagesForGroup(collaboration_group_id, DirtyType::kDot)) + .WillRepeatedly(Return(db_messages)); + messages = service_->GetMessages(std::nullopt); + // Should become two PersistentMessages for each tab, and one for the tab + // group. + ASSERT_EQ(5u, messages.size()); + EXPECT_EQ(CollaborationEvent::TAB_ADDED, messages.at(0).collaboration_event); + EXPECT_EQ(PersistentNotificationType::CHIP, messages.at(0).type); + EXPECT_EQ(CollaborationEvent::TAB_ADDED, messages.at(1).collaboration_event); + EXPECT_EQ(PersistentNotificationType::DIRTY_TAB, messages.at(1).type); + EXPECT_EQ(CollaborationEvent::UNDEFINED, messages.at(2).collaboration_event); + EXPECT_EQ(PersistentNotificationType::DIRTY_TAB_GROUP, messages.at(2).type); + EXPECT_EQ(CollaborationEvent::TAB_UPDATED, + messages.at(3).collaboration_event); + EXPECT_EQ(PersistentNotificationType::CHIP, messages.at(3).type); + EXPECT_EQ(CollaborationEvent::TAB_UPDATED, + messages.at(4).collaboration_event); + EXPECT_EQ(PersistentNotificationType::DIRTY_TAB, messages.at(4).type); +} + +TEST_F(MessagingBackendServiceImplTest, TestGetMessagesForGroup) { + CreateAndInitializeService(); + + data_sharing::GroupId collaboration_group_id = + data_sharing::GroupId("my group id"); + base::Time now = base::Time::Now(); + + std::vector<collaboration_pb::Message> db_messages; + + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessages(DirtyType::kAll)) + .WillOnce(Return(db_messages)); + std::vector<PersistentMessage> messages = service_->GetMessages(std::nullopt); + EXPECT_EQ(0u, messages.size()); + + collaboration_pb::Message message = CreateStoredMessage( + collaboration_group_id, collaboration_pb::EventType::TAB_ADDED, + DirtyType::kDotAndChip, now); + db_messages.emplace_back(message); + + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessagesForGroup(collaboration_group_id, DirtyType::kAll)) + .WillOnce(Return(db_messages)); + // Our service will need to query for dirty dot messages for a group. + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessagesForGroup(collaboration_group_id, DirtyType::kDot)) + .WillOnce(Return(db_messages)); + + // The query should come for the given tab group. + tab_groups::SavedTabGroup tab_group = + CreateSharedTabGroup(collaboration_group_id); + EXPECT_CALL(*mock_tab_group_sync_service_, + GetGroup(tab_groups::EitherGroupID(tab_group.saved_guid()))) + .WillOnce(Return(tab_group)); + + messages = service_->GetMessagesForGroup( + tab_groups::EitherGroupID(tab_group.saved_guid()), std::nullopt); + // Should become two PersistentMessages for the tab, and one for the tab + // group. + ASSERT_EQ(3u, messages.size()); + EXPECT_EQ(CollaborationEvent::TAB_ADDED, messages.at(0).collaboration_event); + EXPECT_EQ(PersistentNotificationType::CHIP, messages.at(0).type); + EXPECT_EQ(CollaborationEvent::TAB_ADDED, messages.at(1).collaboration_event); + EXPECT_EQ(PersistentNotificationType::DIRTY_TAB, messages.at(1).type); + EXPECT_EQ(CollaborationEvent::UNDEFINED, messages.at(2).collaboration_event); + EXPECT_EQ(PersistentNotificationType::DIRTY_TAB_GROUP, messages.at(2).type); +} + +TEST_F(MessagingBackendServiceImplTest, TestGetMessagesForTab) { + CreateAndInitializeService(); + + data_sharing::GroupId collaboration_group_id = + data_sharing::GroupId("my group id"); + base::Time now = base::Time::Now(); + + std::vector<collaboration_pb::Message> db_messages; + + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessages(DirtyType::kAll)) + .WillOnce(Return(db_messages)); + std::vector<PersistentMessage> messages = service_->GetMessages(std::nullopt); + EXPECT_EQ(0u, messages.size()); + + collaboration_pb::Message message = CreateStoredMessage( + collaboration_group_id, collaboration_pb::EventType::TAB_ADDED, + DirtyType::kDotAndChip, now); + db_messages.emplace_back(message); + + // The query should come for the given tab's tab group. + tab_groups::SavedTabGroup tab_group = + CreateSharedTabGroup(collaboration_group_id); + std::vector<tab_groups::SavedTabGroup> all_groups = {tab_group}; + EXPECT_CALL(*mock_tab_group_sync_service_, GetAllGroups()) + .WillRepeatedly(Return(all_groups)); + EXPECT_CALL(*mock_tab_group_sync_service_, GetGroup(tab_group.saved_guid())) + .WillRepeatedly(Return(tab_group)); + base::Uuid tab1_sync_id = tab_group.saved_tabs().at(0).saved_tab_guid(); + + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessageForTab(collaboration_group_id, tab1_sync_id, + DirtyType::kAll)) + .WillRepeatedly(Return(db_messages.at(0))); + // Our service will need to query for dirty dot messages for a group. + EXPECT_CALL(*unowned_messaging_backend_store_, + GetDirtyMessagesForGroup(collaboration_group_id, DirtyType::kDot)) + .WillRepeatedly(Return(db_messages)); + + messages = service_->GetMessagesForTab(tab_groups::EitherTabID(tab1_sync_id), + std::nullopt); + // Should become two PersistentMessages for the tab, but nothing from the + // group. + ASSERT_EQ(2u, messages.size()); + EXPECT_EQ(CollaborationEvent::TAB_ADDED, messages.at(0).collaboration_event); + EXPECT_EQ(PersistentNotificationType::CHIP, messages.at(0).type); + EXPECT_EQ(CollaborationEvent::TAB_ADDED, messages.at(1).collaboration_event); + EXPECT_EQ(PersistentNotificationType::DIRTY_TAB, messages.at(1).type); +} + } // namespace collaboration::messaging
diff --git a/components/collaboration/internal/messaging/tab_group_change_notifier_impl.cc b/components/collaboration/internal/messaging/tab_group_change_notifier_impl.cc index a0a0d2f..2f94ae08 100644 --- a/components/collaboration/internal/messaging/tab_group_change_notifier_impl.cc +++ b/components/collaboration/internal/messaging/tab_group_change_notifier_impl.cc
@@ -336,6 +336,19 @@ return std::nullopt; } + // Try to look up live data first, since we are not always updated, e.g. if a + // local tab ID changes for a particular tab. + std::optional<tab_groups::SavedTabGroup> tab_group; + if (sync_tab_group_id) { + tab_group = tab_group_sync_service_->GetGroup(*sync_tab_group_id); + } + if (tab_group) { + const tab_groups::SavedTabGroupTab* tab = tab_group->GetTab(*sync_tab_id); + if (tab) { + return *tab; + } + } + // The tab is in a shared tab group. const tab_groups::SavedTabGroup& group = group_it->second; const tab_groups::SavedTabGroupTab* tab = group.GetTab(*sync_tab_id);
diff --git a/components/collaboration/internal/messaging/tab_group_change_notifier_impl_unittest.cc b/components/collaboration/internal/messaging/tab_group_change_notifier_impl_unittest.cc index 1f85e11..76b32113 100644 --- a/components/collaboration/internal/messaging/tab_group_change_notifier_impl_unittest.cc +++ b/components/collaboration/internal/messaging/tab_group_change_notifier_impl_unittest.cc
@@ -786,4 +786,36 @@ tab1.saved_tab_guid()); } +TEST_F(TabGroupChangeNotifierImplTest, TestTabSelectionReadsLiveData) { + InitializeNotifier( + /*startup_tab_groups=*/std::vector<tab_groups::SavedTabGroup>(), + /*init_tab_groups=*/std::vector<tab_groups::SavedTabGroup>()); + + tab_groups::SavedTabGroup tab_group = CreateTestSharedTabGroupWithNoTabs(); + tab_groups::SavedTabGroupTab tab = tab_groups::test::CreateSavedTabGroupTab( + "url", u"title", tab_group.saved_guid()); + // The local tab ID is not set yet. + tab_group.AddTabFromSync(tab); + + // Set up notifier with initial tab group data. + EXPECT_CALL(*notifier_observer_, OnTabGroupAdded(TabGroupGuidEq(tab_group))); + tgss_observer_->OnTabGroupAdded(tab_group, tab_groups::TriggerSource::REMOTE); + + // Now, set the local tab ID, but do not inform our observers. + tab_groups::SavedTabGroupTab* tab_for_update = + tab_group.GetTab(tab.saved_tab_guid()); + tab_for_update->SetLocalTabID(42); + + // We expect the notifier to use live data to get the updated local tab id. + EXPECT_CALL(*tab_group_sync_service_, GetGroup(tab_group.saved_guid())) + .WillOnce(Return(tab_group)); + + std::optional<tab_groups::SavedTabGroupTab> tab_selection_received; + // Select the tab: This should lead to our notifier reading the live data. + EXPECT_CALL(*notifier_observer_, OnTabSelected(TabGuidEq(tab))) + .WillOnce(SaveArg<0>(&tab_selection_received)); + tgss_observer_->OnTabSelected(tab_group.saved_guid(), tab.saved_tab_guid()); + EXPECT_EQ(42, tab_selection_received->local_tab_id()); +} + } // namespace collaboration::messaging
diff --git a/components/collaboration/public/BUILD.gn b/components/collaboration/public/BUILD.gn index 0f3fb32a8..130007b 100644 --- a/components/collaboration/public/BUILD.gn +++ b/components/collaboration/public/BUILD.gn
@@ -20,6 +20,8 @@ sources = [ "collaboration_controller_delegate.h", "collaboration_service.h", + "features.cc", + "features.h", "service_status.cc", "service_status.h", ]
diff --git a/components/collaboration/public/features.cc b/components/collaboration/public/features.cc new file mode 100644 index 0000000..63b98944 --- /dev/null +++ b/components/collaboration/public/features.cc
@@ -0,0 +1,15 @@ +// 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/collaboration/public/features.h" + +#include "base/feature_list.h" + +namespace collaboration::messaging { + +BASE_FEATURE(kCollaborationMessaging, + "CollaborationMessaging", + base::FEATURE_DISABLED_BY_DEFAULT); + +} // namespace collaboration::messaging
diff --git a/components/collaboration/public/features.h b/components/collaboration/public/features.h new file mode 100644 index 0000000..ead7a10e --- /dev/null +++ b/components/collaboration/public/features.h
@@ -0,0 +1,16 @@ +// 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_COLLABORATION_PUBLIC_FEATURES_H_ +#define COMPONENTS_COLLABORATION_PUBLIC_FEATURES_H_ + +#include "base/feature_list.h" + +namespace collaboration::messaging { + +BASE_DECLARE_FEATURE(kCollaborationMessaging); + +} // namespace collaboration::messaging + +#endif // COMPONENTS_COLLABORATION_PUBLIC_FEATURES_H_
diff --git a/components/collaboration/public/messaging/messaging_backend_service.h b/components/collaboration/public/messaging/messaging_backend_service.h index 506fcd0..1d2cebf 100644 --- a/components/collaboration/public/messaging/messaging_backend_service.h +++ b/components/collaboration/public/messaging/messaging_backend_service.h
@@ -23,9 +23,9 @@ class PersistentMessageObserver : public base::CheckedObserver { public: // Invoked once when the service is initialized. This is invoked only once - // and is immediately invoked if the service was initialized before the - // observer was added. The initialization state can also be inspected using - // IsInitialized(). + // and is immediately invoked (re-entrant) if the service was initialized + // before the observer was added. You can invoke `IsInitialized()` if you + // want to know the state and whether this is going to happen or not. virtual void OnMessagingBackendServiceInitialized() = 0; // Invoked when the frontend needs to display a specific persistent message.
diff --git a/components/commerce/core/commerce_feature_list.cc b/components/commerce/core/commerce_feature_list.cc index a0c687ed..2d19e92 100644 --- a/components/commerce/core/commerce_feature_list.cc +++ b/components/commerce/core/commerce_feature_list.cc
@@ -198,11 +198,6 @@ &commerce::kProductSpecificationsMultiSpecifics, kProductSpecsMigrateToMultiSpecificsParam, false}; -// Tonal colors for the expanded state of the price tracking chip on desktop. -BASE_FEATURE(kPriceTrackingIconColors, - "PriceTrackingIconColors", - base::FEATURE_DISABLED_BY_DEFAULT); - // Promotion in Magic Stack for Price Tracking users from other platforms. BASE_FEATURE(kPriceTrackingPromo, "PriceTrackingPromo", @@ -243,10 +238,6 @@ "CompareManagementInterface", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kShoppingIconColorVariant, - "ShoppingIconColorVariant", - base::FEATURE_DISABLED_BY_DEFAULT); - // Discount on navigation BASE_FEATURE(kEnableDiscountInfoApi, "EnableDiscountInfoApi",
diff --git a/components/commerce/core/commerce_feature_list.h b/components/commerce/core/commerce_feature_list.h index 2880ab09..ca4e256c 100644 --- a/components/commerce/core/commerce_feature_list.h +++ b/components/commerce/core/commerce_feature_list.h
@@ -46,7 +46,6 @@ extern const base::FeatureParam<bool> kPriceInsightsUseCache; extern const char kProductSpecsMigrateToMultiSpecificsParam[]; extern const base::FeatureParam<bool> kProductSpecsMigrateToMultiSpecifics; -BASE_DECLARE_FEATURE(kPriceTrackingIconColors); BASE_DECLARE_FEATURE(kPriceTrackingPromo); BASE_DECLARE_FEATURE(kProductSpecifications); @@ -57,7 +56,6 @@ BASE_DECLARE_FEATURE(kProductSpecificationsCache); BASE_DECLARE_FEATURE(kCompareManagementInterface); -BASE_DECLARE_FEATURE(kShoppingIconColorVariant); BASE_DECLARE_FEATURE(kShoppingList); BASE_DECLARE_FEATURE(kShoppingListRegionLaunched); BASE_DECLARE_FEATURE(kPriceTrackingSubscriptionServiceLocaleKey);
diff --git a/components/commerce/core/flag_descriptions.cc b/components/commerce/core/flag_descriptions.cc index 9e74913..a788514 100644 --- a/components/commerce/core/flag_descriptions.cc +++ b/components/commerce/core/flag_descriptions.cc
@@ -11,12 +11,6 @@ "Allow Chrome to attempt to detect product pages on the client, without " "server support."; -const char kPriceTrackingIconColorsName[] = - "Price Tracking Icon Tonal UI Colors"; -const char kPriceTrackingIconColorsDescription[] = - "Tonal colors for the expanded state of the price tracking chip on " - "desktop."; - const char kProductSpecificationsName[] = "Product Specifications"; const char kProductSpecificationsDescription[] = "Enable the Product Specifications feature."; @@ -37,12 +31,6 @@ "Enable showing the comparison tables list in the Compare UI and enable " "the new \"Comparison tables\" context menu under \"Bookmarks and Lists\"."; -const char kShoppingIconColorVariantName[] = - "Enable color variant for shopping icons"; -const char kShoppingIconColorVariantDescription[] = - "Enables a color variant for shopping page action icons (Price Insights & " - "Price Tracking)"; - const char kShoppingListName[] = "Shopping List"; const char kShoppingListDescription[] = "Enable shopping list in bookmarks.";
diff --git a/components/commerce/core/flag_descriptions.h b/components/commerce/core/flag_descriptions.h index 9691ab7..4d1ec9f 100644 --- a/components/commerce/core/flag_descriptions.h +++ b/components/commerce/core/flag_descriptions.h
@@ -12,9 +12,6 @@ extern const char kCommerceLocalPDPDetectionName[]; extern const char kCommerceLocalPDPDetectionDescription[]; -extern const char kPriceTrackingIconColorsName[]; -extern const char kPriceTrackingIconColorsDescription[]; - extern const char kProductSpecificationsName[]; extern const char kProductSpecificationsDescription[]; @@ -27,9 +24,6 @@ extern const char kCompareManagementInterfaceName[]; extern const char kCompareManagementInterfaceDescription[]; -extern const char kShoppingIconColorVariantName[]; -extern const char kShoppingIconColorVariantDescription[]; - extern const char kShoppingListName[]; extern const char kShoppingListDescription[];
diff --git a/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy_unittest.cc b/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy_unittest.cc index e4fc5d1..b8609ff 100644 --- a/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy_unittest.cc +++ b/components/component_updater/installer_policies/trust_token_key_commitments_component_installer_policy_unittest.cc
@@ -13,12 +13,10 @@ #include "base/sequence_checker.h" #include "base/test/bind.h" #include "base/test/scoped_command_line.h" -#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/values.h" #include "base/version.h" #include "components/component_updater/component_updater_switches.h" -#include "services/network/public/cpp/features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -42,9 +40,6 @@ TEST_F(TrustTokenKeyCommitmentsComponentInstallerTest, LoadsCommitmentsFromOverriddenPath) { - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndEnableFeature(network::features::kPrivateStateTokens); - base::SequenceCheckerImpl checker; std::string expectation = "some trust token keys"; @@ -79,9 +74,6 @@ } TEST_F(TrustTokenKeyCommitmentsComponentInstallerTest, LoadsCommitments) { - base::test::ScopedFeatureList scoped_list; - scoped_list.InitAndEnableFeature(network::features::kPrivateStateTokens); - base::SequenceCheckerImpl checker; std::string expectation = "some trust token keys";
diff --git a/components/embedder_support/user_agent_utils.cc b/components/embedder_support/user_agent_utils.cc index a8cb8f5d..279a6ae 100644 --- a/components/embedder_support/user_agent_utils.cc +++ b/components/embedder_support/user_agent_utils.cc
@@ -193,26 +193,16 @@ #if !BUILDFLAG(CHROMIUM_BRANDING) brand = version_info::GetProductName(); #endif - std::optional<std::string> maybe_brand_override = - base::GetFieldTrialParamValueByFeature(features::kGreaseUACH, - "brand_override"); - std::optional<std::string> maybe_version_override = - base::GetFieldTrialParamValueByFeature(features::kGreaseUACH, - "version_override"); - if (maybe_brand_override->empty()) - maybe_brand_override = std::nullopt; - if (maybe_version_override->empty()) - maybe_version_override = std::nullopt; std::string brand_version = output_version_type == blink::UserAgentBrandVersionType::kFullVersion ? full_version : major_version; - return GenerateBrandVersionList( - major_version_number, brand, brand_version, maybe_brand_override, - maybe_version_override, enable_updated_grease_by_policy, - output_version_type, additional_brand_version); + return GenerateBrandVersionList(major_version_number, brand, brand_version, + enable_updated_grease_by_policy, + output_version_type, + additional_brand_version); } // Return UserAgentBrandList with the major version populated in the brand @@ -383,16 +373,13 @@ int seed, std::optional<std::string> brand, const std::string& version, - std::optional<std::string> maybe_greasey_brand, - std::optional<std::string> maybe_greasey_version, bool enable_updated_grease_by_policy, blink::UserAgentBrandVersionType output_version_type, std::optional<blink::UserAgentBrandVersion> additional_brand_version) { DCHECK_GE(seed, 0); blink::UserAgentBrandVersion greasey_bv = GetGreasedUserAgentBrandVersion( - seed, maybe_greasey_brand, maybe_greasey_version, - enable_updated_grease_by_policy, output_version_type); + seed, enable_updated_grease_by_policy, output_version_type); blink::UserAgentBrandVersion chromium_bv = {"Chromium", version}; blink::UserAgentBrandList brand_version_list = {std::move(greasey_bv), @@ -443,8 +430,6 @@ blink::UserAgentBrandVersion GetGreasedUserAgentBrandVersion( int seed, - std::optional<std::string> maybe_greasey_brand, - std::optional<std::string> maybe_greasey_version, bool enable_updated_grease_by_policy, blink::UserAgentBrandVersionType output_version_type) { std::string greasey_brand; @@ -452,9 +437,7 @@ // The updated algorithm is enabled by default, but we maintain the ability // to opt out of it either via Finch (setting updated_algorithm to false) or // via an enterprise policy escape hatch. - if (enable_updated_grease_by_policy && - base::GetFieldTrialParamByFeatureAsBool(features::kGreaseUACH, - "updated_algorithm", true)) { + if (enable_updated_grease_by_policy) { const std::vector<std::string> greasey_chars = { " ", "(", ":", "-", ".", "/", ")", ";", "=", "?", "_"}; const std::vector<std::string> greased_versions = {"8", "99", "24"}; @@ -465,9 +448,8 @@ greasey_chars[(seed + 1) % greasey_chars.size()], "Brand"}); greasey_version = greased_versions[seed % greased_versions.size()]; - return GetProcessedGreasedBrandVersion( - maybe_greasey_brand.value_or(greasey_brand), - maybe_greasey_version.value_or(greasey_version), output_version_type); + return GetProcessedGreasedBrandVersion(greasey_brand, greasey_version, + output_version_type); } else { const std::vector<std::string> greasey_chars = {" ", " ", ";"}; const std::vector<size_t> permuted_order =
diff --git a/components/embedder_support/user_agent_utils.h b/components/embedder_support/user_agent_utils.h index e6a4843..3adb28fb 100644 --- a/components/embedder_support/user_agent_utils.h +++ b/components/embedder_support/user_agent_utils.h
@@ -69,8 +69,6 @@ int seed, std::optional<std::string> brand, const std::string& version, - std::optional<std::string> maybe_greasey_brand, - std::optional<std::string> maybe_greasey_version, bool enable_updated_grease_by_policy, blink::UserAgentBrandVersionType output_version_type, std::optional<blink::UserAgentBrandVersion> additional_brand_version = @@ -107,8 +105,6 @@ // https://wicg.github.io/ua-client-hints/#create-arbitrary-brands-section. blink::UserAgentBrandVersion GetGreasedUserAgentBrandVersion( int seed, - std::optional<std::string> maybe_greasey_brand, - std::optional<std::string> maybe_greasey_version, bool enable_updated_grease_by_policy, blink::UserAgentBrandVersionType output_version_type);
diff --git a/components/embedder_support/user_agent_utils_unittest.cc b/components/embedder_support/user_agent_utils_unittest.cc index 8912eb3..b9779c4 100644 --- a/components/embedder_support/user_agent_utils_unittest.cc +++ b/components/embedder_support/user_agent_utils_unittest.cc
@@ -771,12 +771,12 @@ TEST_F(UserAgentUtilsTest, GenerateBrandVersionListUnbranded) { blink::UserAgentMetadata metadata; - metadata.brand_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion); - metadata.brand_full_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84.0.0.0", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion); + metadata.brand_version_list = + GenerateBrandVersionList(84, std::nullopt, "84", true, + blink::UserAgentBrandVersionType::kMajorVersion); + metadata.brand_full_version_list = + GenerateBrandVersionList(84, std::nullopt, "84.0.0.0", true, + blink::UserAgentBrandVersionType::kFullVersion); // 1. verify major version std::string brand_list = metadata.SerializeBrandMajorVersionList(); EXPECT_EQ(R"("Not;A=Brand";v="8", "Chromium";v="84")", brand_list); @@ -789,19 +789,19 @@ TEST_F(UserAgentUtilsTest, GenerateBrandVersionListUnbrandedVerifySeedChanges) { blink::UserAgentMetadata metadata; - metadata.brand_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion); + metadata.brand_version_list = + GenerateBrandVersionList(84, std::nullopt, "84", true, + blink::UserAgentBrandVersionType::kMajorVersion); // Capture the serialized brand lists with version 84 as the seed. std::string brand_list = metadata.SerializeBrandMajorVersionList(); std::string brand_list_w_fv = metadata.SerializeBrandFullVersionList(); - metadata.brand_version_list = GenerateBrandVersionList( - 85, std::nullopt, "85", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion); - metadata.brand_full_version_list = GenerateBrandVersionList( - 85, std::nullopt, "85.0.0.0", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion); + metadata.brand_version_list = + GenerateBrandVersionList(85, std::nullopt, "85", true, + blink::UserAgentBrandVersionType::kMajorVersion); + metadata.brand_full_version_list = + GenerateBrandVersionList(85, std::nullopt, "85.0.0.0", true, + blink::UserAgentBrandVersionType::kFullVersion); // Make sure the lists are different for different seeds (84 vs 85). // 1. verify major version @@ -815,27 +815,6 @@ EXPECT_NE(brand_list_w_fv, brand_list_diff_w_fv); } -TEST_F(UserAgentUtilsTest, GenerateBrandVersionListWithGreaseBrandOverride) { - blink::UserAgentMetadata metadata; - // The GREASE generation algorithm should respond to experiment overrides. - metadata.brand_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84", "Clean GREASE", std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion); - metadata.brand_full_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84.0.0.0", "Clean GREASE", std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion); - // 1. verify major version - std::string brand_list_grease_override = - metadata.SerializeBrandMajorVersionList(); - EXPECT_EQ(R"("Clean GREASE";v="8", "Chromium";v="84")", - brand_list_grease_override); - // 2. verify full version - std::string brand_list_grease_override_fv = - metadata.SerializeBrandFullVersionList(); - EXPECT_EQ(R"("Clean GREASE";v="8.0.0.0", "Chromium";v="84.0.0.0")", - brand_list_grease_override_fv); -} - TEST_F(UserAgentUtilsTest, GenerateBrandVersionListAdditionalBrandVersions) { blink::UserAgentMetadata metadata; // The GREASE generation algorithm should respond to experiment overrides. @@ -844,15 +823,15 @@ blink::UserAgentBrandVersion additional_brand_full_versions = {"Add Brand", "1.0.0.0"}; - // 1. Without greasey brand and product brand. - metadata.brand_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion, - additional_brand_major_versions); - metadata.brand_full_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84.0.0.0", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion, - additional_brand_full_versions); + // 1. Without product brand. + metadata.brand_version_list = + GenerateBrandVersionList(84, std::nullopt, "84", true, + blink::UserAgentBrandVersionType::kMajorVersion, + additional_brand_major_versions); + metadata.brand_full_version_list = + GenerateBrandVersionList(84, std::nullopt, "84.0.0.0", true, + blink::UserAgentBrandVersionType::kFullVersion, + additional_brand_full_versions); // Verify major version and full version. EXPECT_EQ(base::StrCat({"\"Not;A=Brand\";v=\"8\", ", "\"Chromium\";v=\"84\", ", "\"Add Brand\";v=\"1\""}), @@ -862,33 +841,15 @@ "\"Add Brand\";v=\"1.0.0.0\""}), metadata.SerializeBrandFullVersionList()); - // 2. With greasey brand - metadata.brand_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84", "Clean GREASE", std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion, - additional_brand_major_versions); - metadata.brand_full_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84.0.0.0", "Clean GREASE", std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion, - additional_brand_full_versions); - // Verify major version and full version. - EXPECT_EQ(base::StrCat({"\"Clean GREASE\";v=\"8\", ", - "\"Chromium\";v=\"84\", ", "\"Add Brand\";v=\"1\""}), - metadata.SerializeBrandMajorVersionList()); - EXPECT_EQ(base::StrCat({"\"Clean GREASE\";v=\"8.0.0.0\", ", - "\"Chromium\";v=\"84.0.0.0\", ", - "\"Add Brand\";v=\"1.0.0.0\""}), - metadata.SerializeBrandFullVersionList()); - - // 3. With product brand - metadata.brand_version_list = GenerateBrandVersionList( - 84, "Product Brand", "84", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion, - additional_brand_major_versions); - metadata.brand_full_version_list = GenerateBrandVersionList( - 84, "Product Brand", "84.0.0.0", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion, - additional_brand_full_versions); + // 2. With product brand + metadata.brand_version_list = + GenerateBrandVersionList(84, "Product Brand", "84", true, + blink::UserAgentBrandVersionType::kMajorVersion, + additional_brand_major_versions); + metadata.brand_full_version_list = + GenerateBrandVersionList(84, "Product Brand", "84.0.0.0", true, + blink::UserAgentBrandVersionType::kFullVersion, + additional_brand_full_versions); // Verify major version and full version. EXPECT_EQ( base::StrCat({"\"Chromium\";v=\"84\", ", "\"Product Brand\";v=\"84\", ", @@ -900,43 +861,23 @@ "\"Add Brand\";v=\"1.0.0.0\""}), metadata.SerializeBrandFullVersionList()); - // 4. With product brand and greasey brand - metadata.brand_version_list = GenerateBrandVersionList( - 84, "Product Brand", "84", "Clean GREASE", std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion, - additional_brand_major_versions); - metadata.brand_full_version_list = GenerateBrandVersionList( - 84, "Product Brand", "84.0.0.0", "Clean GREASE", std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion, - additional_brand_full_versions); - // Verify major version and full version. - EXPECT_EQ( - base::StrCat({"\"Chromium\";v=\"84\", ", "\"Product Brand\";v=\"84\", ", - "\"Clean GREASE\";v=\"8\", ", "\"Add Brand\";v=\"1\""}), - metadata.SerializeBrandMajorVersionList()); - EXPECT_EQ(base::StrCat({"\"Chromium\";v=\"84.0.0.0\", ", - "\"Product Brand\";v=\"84.0.0.0\", ", - "\"Clean GREASE\";v=\"8.0.0.0\", ", - "\"Add Brand\";v=\"1.0.0.0\""}), - metadata.SerializeBrandFullVersionList()); - - // 5. With product brand, greasey brand and different seed. - metadata.brand_version_list = GenerateBrandVersionList( - 86, "Product Brand", "84", "Clean GREASE", std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion, - additional_brand_major_versions); - metadata.brand_full_version_list = GenerateBrandVersionList( - 86, "Product Brand", "84.0.0.0", "Clean GREASE", std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion, - additional_brand_full_versions); + // 3. With product brand and different seed. + metadata.brand_version_list = + GenerateBrandVersionList(86, "Product Brand", "84", true, + blink::UserAgentBrandVersionType::kMajorVersion, + additional_brand_major_versions); + metadata.brand_full_version_list = + GenerateBrandVersionList(86, "Product Brand", "84.0.0.0", true, + blink::UserAgentBrandVersionType::kFullVersion, + additional_brand_full_versions); // Verify major version and full version. EXPECT_EQ( base::StrCat({"\"Product Brand\";v=\"84\", ", "\"Chromium\";v=\"84\", ", - "\"Clean GREASE\";v=\"24\", ", "\"Add Brand\";v=\"1\""}), + "\"Not?A_Brand\";v=\"24\", ", "\"Add Brand\";v=\"1\""}), metadata.SerializeBrandMajorVersionList()); EXPECT_EQ(base::StrCat({"\"Product Brand\";v=\"84.0.0.0\", ", "\"Chromium\";v=\"84.0.0.0\", ", - "\"Clean GREASE\";v=\"24.0.0.0\", ", + "\"Not?A_Brand\";v=\"24.0.0.0\", ", "\"Add Brand\";v=\"1.0.0.0\""}), metadata.SerializeBrandFullVersionList()); @@ -955,53 +896,53 @@ GenerateBrandVersionListWithGreaseBrandAndVersionOverride) { blink::UserAgentMetadata metadata; - metadata.brand_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84", "Clean GREASE", "1024", true, - blink::UserAgentBrandVersionType::kMajorVersion); - metadata.brand_full_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84.0.0.0", "Clean GREASE", "1024", true, - blink::UserAgentBrandVersionType::kFullVersion); + metadata.brand_version_list = + GenerateBrandVersionList(84, std::nullopt, "84", true, + blink::UserAgentBrandVersionType::kMajorVersion); + metadata.brand_full_version_list = + GenerateBrandVersionList(84, std::nullopt, "84.0.0.0", true, + blink::UserAgentBrandVersionType::kFullVersion); // 1. verify major version std::string brand_list_and_version_grease_override = metadata.SerializeBrandMajorVersionList(); - EXPECT_EQ(R"("Clean GREASE";v="1024", "Chromium";v="84")", + EXPECT_EQ(R"("Not;A=Brand";v="8", "Chromium";v="84")", brand_list_and_version_grease_override); // 2. verify full version std::string brand_list_and_version_grease_override_fv = metadata.SerializeBrandFullVersionList(); - EXPECT_EQ(R"("Clean GREASE";v="1024.0.0.0", "Chromium";v="84.0.0.0")", + EXPECT_EQ(R"("Not;A=Brand";v="8.0.0.0", "Chromium";v="84.0.0.0")", brand_list_and_version_grease_override_fv); } TEST_F(UserAgentUtilsTest, GenerateBrandVersionListWithGreaseVersionOverride) { blink::UserAgentMetadata metadata; - metadata.brand_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84", std::nullopt, "1024", true, - blink::UserAgentBrandVersionType::kMajorVersion); - metadata.brand_full_version_list = GenerateBrandVersionList( - 84, std::nullopt, "84.0.0.0", std::nullopt, "1024", true, - blink::UserAgentBrandVersionType::kFullVersion); + metadata.brand_version_list = + GenerateBrandVersionList(84, std::nullopt, "84", true, + blink::UserAgentBrandVersionType::kMajorVersion); + metadata.brand_full_version_list = + GenerateBrandVersionList(84, std::nullopt, "84.0.0.0", true, + blink::UserAgentBrandVersionType::kFullVersion); // 1. verify major version std::string brand_version_grease_override = metadata.SerializeBrandMajorVersionList(); - EXPECT_EQ(R"("Not;A=Brand";v="1024", "Chromium";v="84")", + EXPECT_EQ(R"("Not;A=Brand";v="8", "Chromium";v="84")", brand_version_grease_override); // 2. verify full version std::string brand_version_grease_override_fv = metadata.SerializeBrandFullVersionList(); - EXPECT_EQ(R"("Not;A=Brand";v="1024.0.0.0", "Chromium";v="84.0.0.0")", + EXPECT_EQ(R"("Not;A=Brand";v="8.0.0.0", "Chromium";v="84.0.0.0")", brand_version_grease_override_fv); } TEST_F(UserAgentUtilsTest, GenerateBrandVersionListWithBrand) { blink::UserAgentMetadata metadata; - metadata.brand_version_list = GenerateBrandVersionList( - 84, "Totally A Brand", "84", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion); - metadata.brand_full_version_list = GenerateBrandVersionList( - 84, "Totally A Brand", "84.0.0.0", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion); + metadata.brand_version_list = + GenerateBrandVersionList(84, "Totally A Brand", "84", true, + blink::UserAgentBrandVersionType::kMajorVersion); + metadata.brand_full_version_list = + GenerateBrandVersionList(84, "Totally A Brand", "84.0.0.0", true, + blink::UserAgentBrandVersionType::kFullVersion); // 1. verify major version std::string brand_list_w_brand = metadata.SerializeBrandMajorVersionList(); EXPECT_EQ( @@ -1018,92 +959,21 @@ TEST_F(UserAgentUtilsTest, GenerateBrandVersionListInvalidSeed) { // Should DCHECK on negative numbers EXPECT_DCHECK_DEATH(GenerateBrandVersionList( - -1, std::nullopt, "99", std::nullopt, std::nullopt, true, + -1, std::nullopt, "99", true, blink::UserAgentBrandVersionType::kMajorVersion)); - EXPECT_DCHECK_DEATH(GenerateBrandVersionList( - -1, std::nullopt, "99.0.0.0", std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion)); + EXPECT_DCHECK_DEATH( + GenerateBrandVersionList(-1, std::nullopt, "99.0.0.0", true, + blink::UserAgentBrandVersionType::kFullVersion)); } TEST_F(UserAgentUtilsTest, GetGreasedUserAgentBrandVersionOldAlgorithm) { - base::test::ScopedFeatureList scoped_feature_list; - // Test to ensure the old algorithm is respected when opted into. - scoped_feature_list.InitAndEnableFeatureWithParameters( - features::kGreaseUACH, {{"updated_algorithm", "false"}}); - blink::UserAgentBrandVersion greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion); + 84, false, blink::UserAgentBrandVersionType::kMajorVersion); EXPECT_EQ(greased_bv.brand, " Not A;Brand"); EXPECT_EQ(greased_bv.version, "99"); greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion); - EXPECT_EQ(greased_bv.brand, " Not A;Brand"); - EXPECT_EQ(greased_bv.version, "99.0.0.0"); -} - -TEST_F(UserAgentUtilsTest, - GetGreasedUserAgentBrandVersionOldAlgorithmIgnoresBrandOverrides) { - base::test::ScopedFeatureList scoped_feature_list; - // Test to ensure the old algorithm is respected when the flag is not set. - scoped_feature_list.InitAndEnableFeatureWithParameters( - features::kGreaseUACH, {{"updated_algorithm", "false"}}); - // With the new algorithm disabled, we want to avoid experiment params - // ("WhatIsGrease", 1024) from taking an effect. - blink::UserAgentBrandVersion greased_bv = GetGreasedUserAgentBrandVersion( - 84, "WhatIsGrease", std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion); - EXPECT_EQ(greased_bv.brand, " Not A;Brand"); - EXPECT_EQ(greased_bv.version, "99"); - - greased_bv = GetGreasedUserAgentBrandVersion( - 84, "WhatIsGrease", std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion); - EXPECT_EQ(greased_bv.brand, " Not A;Brand"); - EXPECT_EQ(greased_bv.version, "99.0.0.0"); -} - -TEST_F(UserAgentUtilsTest, - GetGreasedUserAgentBrandVersionOldAlgorithmIgnoresVersionOverrides) { - base::test::ScopedFeatureList scoped_feature_list; - // Test to ensure the old algorithm is respected when the flag is not set. - scoped_feature_list.InitAndEnableFeatureWithParameters( - features::kGreaseUACH, {{"updated_algorithm", "false"}}); - // With the new algorithm disabled, we want to avoid experiment params - // ("WhatIsGrease", 1024) from taking an effect. - blink::UserAgentBrandVersion greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, "1024", true, - blink::UserAgentBrandVersionType::kMajorVersion); - EXPECT_EQ(greased_bv.brand, " Not A;Brand"); - EXPECT_EQ(greased_bv.version, "99"); - - greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, "1024", true, - blink::UserAgentBrandVersionType::kFullVersion); - EXPECT_EQ(greased_bv.brand, " Not A;Brand"); - EXPECT_EQ(greased_bv.version, "99.0.0.0"); -} - -TEST_F( - UserAgentUtilsTest, - GetGreasedUserAgentBrandVersionOldAlgorithmIgnoresBrandAndVersionOverrides) { - base::test::ScopedFeatureList scoped_feature_list; - // Test to ensure the old algorithm is respected when the flag is not set. - scoped_feature_list.InitAndEnableFeatureWithParameters( - features::kGreaseUACH, {{"updated_algorithm", "false"}}); - // With the new algorithm disabled, we want to avoid experiment params - // ("WhatIsGrease", 1024) from taking an effect. - blink::UserAgentBrandVersion greased_bv = GetGreasedUserAgentBrandVersion( - 84, "WhatIsGrease", "1024", true, - blink::UserAgentBrandVersionType::kMajorVersion); - EXPECT_EQ(greased_bv.brand, " Not A;Brand"); - EXPECT_EQ(greased_bv.version, "99"); - - greased_bv = GetGreasedUserAgentBrandVersion( - 84, "WhatIsGrease", "1024", true, - blink::UserAgentBrandVersionType::kFullVersion); + 84, false, blink::UserAgentBrandVersionType::kFullVersion); EXPECT_EQ(greased_bv.brand, " Not A;Brand"); EXPECT_EQ(greased_bv.version, "99.0.0.0"); } @@ -1112,103 +982,38 @@ TEST_F(UserAgentUtilsTest, GetGreasedUserAgentBrandVersionNewAlgorithm) { std::vector<int> permuted_order{0, 1, 2}; blink::UserAgentBrandVersion greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion); + 84, true, blink::UserAgentBrandVersionType::kMajorVersion); EXPECT_EQ(greased_bv.brand, "Not;A=Brand"); EXPECT_EQ(greased_bv.version, "8"); greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion); + 84, true, blink::UserAgentBrandVersionType::kFullVersion); EXPECT_EQ(greased_bv.brand, "Not;A=Brand"); EXPECT_EQ(greased_bv.version, "8.0.0.0"); } -TEST_F(UserAgentUtilsTest, - GetGreasedUserAgentBrandVersionNewAlgorithmBrandOverride) { - blink::UserAgentBrandVersion greased_bv = GetGreasedUserAgentBrandVersion( - 84, "WhatIsGrease", std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion); - EXPECT_EQ(greased_bv.brand, "WhatIsGrease"); - EXPECT_EQ(greased_bv.version, "8"); - - greased_bv = GetGreasedUserAgentBrandVersion( - 84, "WhatIsGrease", std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion); - EXPECT_EQ(greased_bv.brand, "WhatIsGrease"); - EXPECT_EQ(greased_bv.version, "8.0.0.0"); -} - -TEST_F(UserAgentUtilsTest, - GetGreasedUserAgentBrandVersionNewAlgorithmVersionOverride) { - std::vector<int> permuted_order{0, 1, 2}; - blink::UserAgentBrandVersion greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, "1024", true, - blink::UserAgentBrandVersionType::kMajorVersion); - EXPECT_EQ(greased_bv.brand, "Not;A=Brand"); - EXPECT_EQ(greased_bv.version, "1024"); - - greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, "1024", true, - blink::UserAgentBrandVersionType::kFullVersion); - EXPECT_EQ(greased_bv.brand, "Not;A=Brand"); - EXPECT_EQ(greased_bv.version, "1024.0.0.0"); -} - -TEST_F(UserAgentUtilsTest, - GetGreasedUserAgentBrandVersionNewAlgorithmBrandAndVersionOverride) { - blink::UserAgentBrandVersion greased_bv = GetGreasedUserAgentBrandVersion( - 84, "WhatIsGrease", "1024", true, - blink::UserAgentBrandVersionType::kMajorVersion); - EXPECT_EQ(greased_bv.brand, "WhatIsGrease"); - EXPECT_EQ(greased_bv.version, "1024"); - - greased_bv = GetGreasedUserAgentBrandVersion( - 84, "WhatIsGrease", "1024", true, - blink::UserAgentBrandVersionType::kFullVersion); - EXPECT_EQ(greased_bv.brand, "WhatIsGrease"); - EXPECT_EQ(greased_bv.version, "1024.0.0.0"); -} - TEST_F(UserAgentUtilsTest, GetGreasedUserAgentBrandVersionFullVersions) { blink::UserAgentBrandVersion greased_bv = GetGreasedUserAgentBrandVersion( - 86, std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion); + 86, true, blink::UserAgentBrandVersionType::kMajorVersion); EXPECT_EQ(greased_bv.brand, "Not?A_Brand"); EXPECT_EQ(greased_bv.version, "24"); greased_bv = GetGreasedUserAgentBrandVersion( - 86, std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion); + 86, true, blink::UserAgentBrandVersionType::kFullVersion); EXPECT_EQ(greased_bv.brand, "Not?A_Brand"); EXPECT_EQ(greased_bv.version, "24.0.0.0"); - - // Test the greasy input with full version - greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, "1024.0.0.0", true, - blink::UserAgentBrandVersionType::kMajorVersion); - EXPECT_EQ(greased_bv.brand, "Not;A=Brand"); - EXPECT_EQ(greased_bv.version, "1024"); - - greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, "1024.0.0.0", true, - blink::UserAgentBrandVersionType::kFullVersion); - EXPECT_EQ(greased_bv.brand, "Not;A=Brand"); - EXPECT_EQ(greased_bv.version, "1024.0.0.0"); } TEST_F(UserAgentUtilsTest, GetGreasedUserAgentBrandVersionEnterpriseOverride) { // Ensure the enterprise override bool can force the old GREASE algorithm to // be used. blink::UserAgentBrandVersion greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, std::nullopt, false, - blink::UserAgentBrandVersionType::kMajorVersion); + 84, false, blink::UserAgentBrandVersionType::kMajorVersion); EXPECT_EQ(greased_bv.brand, " Not A;Brand"); EXPECT_EQ(greased_bv.version, "99"); greased_bv = GetGreasedUserAgentBrandVersion( - 84, std::nullopt, std::nullopt, false, - blink::UserAgentBrandVersionType::kFullVersion); + 84, false, blink::UserAgentBrandVersionType::kFullVersion); EXPECT_EQ(greased_bv.brand, " Not A;Brand"); EXPECT_EQ(greased_bv.version, "99.0.0.0"); } @@ -1219,14 +1024,12 @@ // Ensure the enterprise override bool can force the old GREASE algorithm to // be used and supersedes passed-in brand/version overrides. blink::UserAgentBrandVersion greased_bv = GetGreasedUserAgentBrandVersion( - 84, "helloWorld", "100000", false, - blink::UserAgentBrandVersionType::kMajorVersion); + 84, false, blink::UserAgentBrandVersionType::kMajorVersion); EXPECT_EQ(greased_bv.brand, " Not A;Brand"); EXPECT_EQ(greased_bv.version, "99"); greased_bv = GetGreasedUserAgentBrandVersion( - 84, "helloWorld", "100000", false, - blink::UserAgentBrandVersionType::kFullVersion); + 84, false, blink::UserAgentBrandVersionType::kFullVersion); EXPECT_EQ(greased_bv.brand, " Not A;Brand"); EXPECT_EQ(greased_bv.version, "99.0.0.0"); } @@ -1238,13 +1041,11 @@ // Regardless of the major version seed, the spec calls for no leading // whitespace in the brand. greased_bv = GetGreasedUserAgentBrandVersion( - i, std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kMajorVersion); + i, true, blink::UserAgentBrandVersionType::kMajorVersion); EXPECT_NE(greased_bv.brand[0], ' '); greased_bv = GetGreasedUserAgentBrandVersion( - i, std::nullopt, std::nullopt, true, - blink::UserAgentBrandVersionType::kFullVersion); + i, true, blink::UserAgentBrandVersionType::kFullVersion); EXPECT_NE(greased_bv.brand[0], ' '); } }
diff --git a/components/facilitated_payments/core/browser/ewallet_manager.cc b/components/facilitated_payments/core/browser/ewallet_manager.cc index 4cfca7b7..935604be0 100644 --- a/components/facilitated_payments/core/browser/ewallet_manager.cc +++ b/components/facilitated_payments/core/browser/ewallet_manager.cc
@@ -168,11 +168,16 @@ initiate_payment_request_details_->risk_data_ = risk_data; - GetApiClient()->GetClientToken(base::BindOnce( - &EwalletManager::OnGetClientToken, weak_ptr_factory_.GetWeakPtr())); + GetApiClient()->GetClientToken( + base::BindOnce(&EwalletManager::OnGetClientToken, + weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now())); } -void EwalletManager::OnGetClientToken(std::vector<uint8_t> client_token) { +void EwalletManager::OnGetClientToken(base::TimeTicks start_time, + std::vector<uint8_t> client_token) { + LogGetClientTokenResultAndLatency(kPaymentsType, !client_token.empty(), + (base::TimeTicks::Now() - start_time), + scheme_); if (client_token.empty()) { client_->ShowErrorScreen(); return;
diff --git a/components/facilitated_payments/core/browser/ewallet_manager.h b/components/facilitated_payments/core/browser/ewallet_manager.h index 45da4f60..0a508c6 100644 --- a/components/facilitated_payments/core/browser/ewallet_manager.h +++ b/components/facilitated_payments/core/browser/ewallet_manager.h
@@ -87,7 +87,9 @@ // Called after retrieving the client token from the facilitated payment API. // If not empty, the client token can be used for initiating payment. - void OnGetClientToken(std::vector<uint8_t> client_token); + // The call was made at `start_time`. + void OnGetClientToken(base::TimeTicks start_time, + std::vector<uint8_t> client_token); // Makes a payment request to the Payments server after the user has selected // the eWallet for making the payment.
diff --git a/components/facilitated_payments/core/browser/ewallet_manager_test_api.h b/components/facilitated_payments/core/browser/ewallet_manager_test_api.h index 7127f4e..755cd1a 100644 --- a/components/facilitated_payments/core/browser/ewallet_manager_test_api.h +++ b/components/facilitated_payments/core/browser/ewallet_manager_test_api.h
@@ -54,8 +54,9 @@ ewallet_manager_->OnRiskDataLoaded(start_time, risk_data); } - void OnGetClientToken(std::vector<uint8_t> client_token) { - ewallet_manager_->OnGetClientToken(client_token); + void OnGetClientToken(base::TimeTicks start_time, + std::vector<uint8_t> client_token) { + ewallet_manager_->OnGetClientToken(start_time, client_token); } FacilitatedPaymentsInitiatePaymentRequestDetails*
diff --git a/components/facilitated_payments/core/browser/ewallet_manager_unittest.cc b/components/facilitated_payments/core/browser/ewallet_manager_unittest.cc index d53e2d99..3f1794a 100644 --- a/components/facilitated_payments/core/browser/ewallet_manager_unittest.cc +++ b/components/facilitated_payments/core/browser/ewallet_manager_unittest.cc
@@ -357,7 +357,35 @@ TEST_F(EwalletManagerTest, OnGetClientToken_ClientTokenEmpty_ErrorScreenShown) { EXPECT_CALL(client_, ShowErrorScreen); - test_api(*ewallet_manager_).OnGetClientToken(std::vector<uint8_t>{}); + test_api(*ewallet_manager_) + .OnGetClientToken(base::TimeTicks::Now() - base::Seconds(2), + std::vector<uint8_t>{}); +} + +// Test that GetClientToken related metrics are logged correctly. +TEST_F(EwalletManagerTest, LogGetClientTokenResultAndLatency) { + for (bool get_client_token_result : {true, false}) { + base::HistogramTester histogram_tester; + + test_api(*ewallet_manager_) + .OnGetClientToken(base::TimeTicks::Now() - base::Seconds(2), + get_client_token_result + ? std::vector<uint8_t>{'t', 'o', 'k', 'e', 'n'} + : std::vector<uint8_t>{}); + + std::string result = get_client_token_result ? "Success" : "Failure"; + + histogram_tester.ExpectUniqueSample( + base::StrCat({"FacilitatedPayments.Ewallet.GetClientToken.", result, + ".Latency"}), + /*sample=*/2000, + /*expected_bucket_count=*/1); + histogram_tester.ExpectUniqueSample( + base::StrCat({"FacilitatedPayments.Ewallet.GetClientToken.", result, + ".Latency.ShopeePay"}), + /*sample=*/2000, + /*expected_bucket_count=*/1); + } } // Test that SendInitiatePaymentRequest doesn't initiates payment when
diff --git a/components/facilitated_payments/core/browser/facilitated_payments_manager.cc b/components/facilitated_payments/core/browser/facilitated_payments_manager.cc index 11c97461..90c54f417 100644 --- a/components/facilitated_payments/core/browser/facilitated_payments_manager.cc +++ b/components/facilitated_payments/core/browser/facilitated_payments_manager.cc
@@ -231,7 +231,7 @@ void FacilitatedPaymentsManager::OnGetClientToken( std::vector<uint8_t> client_token) { LogGetClientTokenResultAndLatency( - !client_token.empty(), + kPaymentsType, !client_token.empty(), (base::TimeTicks::Now() - get_client_token_loading_start_time_)); if (client_token.empty()) { ShowErrorScreen();
diff --git a/components/facilitated_payments/core/metrics/facilitated_payments_metrics.cc b/components/facilitated_payments/core/metrics/facilitated_payments_metrics.cc index 926a447..a886242d 100644 --- a/components/facilitated_payments/core/metrics/facilitated_payments_metrics.cc +++ b/components/facilitated_payments/core/metrics/facilitated_payments_metrics.cc
@@ -144,11 +144,24 @@ } } -void LogGetClientTokenResultAndLatency(bool result, base::TimeDelta duration) { +void LogGetClientTokenResultAndLatency( + FacilitatedPaymentsType payment_type, + bool result, + base::TimeDelta duration, + std::optional<PaymentLinkValidator::Scheme> scheme) { base::UmaHistogramLongTimes( - base::StrCat({"FacilitatedPayments.Pix.GetClientToken.", - result ? "Success" : "Failure", ".Latency"}), + base::StrCat({"FacilitatedPayments.", PaymentTypeToString(payment_type), + ".GetClientToken.", ResultToString(result), ".Latency"}), duration); + if (payment_type == FacilitatedPaymentsType::kEwallet) { + CHECK(scheme.has_value()); + CHECK_NE(PaymentLinkValidator::Scheme::kInvalid, *scheme); + base::UmaHistogramLongTimes( + base::StrCat({"FacilitatedPayments.Ewallet.GetClientToken.", + ResultToString(result), ".Latency.", + SchemeToString(*scheme)}), + duration); + } } void LogPayflowExitedReason(PayflowExitedReason reason) {
diff --git a/components/facilitated_payments/core/metrics/facilitated_payments_metrics.h b/components/facilitated_payments/core/metrics/facilitated_payments_metrics.h index d6cf4367..c3a8377 100644 --- a/components/facilitated_payments/core/metrics/facilitated_payments_metrics.h +++ b/components/facilitated_payments/core/metrics/facilitated_payments_metrics.h
@@ -113,7 +113,14 @@ std::optional<PaymentLinkValidator::Scheme> scheme = std::nullopt); // Log the result and the latency of the GetClientToken call made to api client. -void LogGetClientTokenResultAndLatency(bool result, base::TimeDelta duration); +// `payment_type` must be either `kEwallet` or `kPix`. +// The `scheme` parameter is required for the 'kEwallet' payment type and should +// not be `kInvalid`. +void LogGetClientTokenResultAndLatency( + FacilitatedPaymentsType payment_type, + bool result, + base::TimeDelta duration, + std::optional<PaymentLinkValidator::Scheme> scheme = std::nullopt); // Log the reason for the payflow was exited early. This includes all the // reasons after receiving a signal from the renderer process that a valid code
diff --git a/components/facilitated_payments/core/metrics/facilitated_payments_metrics_unittest.cc b/components/facilitated_payments/core/metrics/facilitated_payments_metrics_unittest.cc index 1ea7c76..19ae4b8 100644 --- a/components/facilitated_payments/core/metrics/facilitated_payments_metrics_unittest.cc +++ b/components/facilitated_payments/core/metrics/facilitated_payments_metrics_unittest.cc
@@ -77,17 +77,6 @@ /*expected_bucket_count=*/1); } -TEST(FacilitatedPaymentsMetricsTest, LogGetClientTokenResultAndLatency) { - base::HistogramTester histogram_tester; - - LogGetClientTokenResultAndLatency(/*result=*/true, base::Milliseconds(10)); - - histogram_tester.ExpectUniqueSample( - "FacilitatedPayments.Pix.GetClientToken.Success.Latency", - /*sample=*/10, - /*expected_bucket_count=*/1); -} - TEST(FacilitatedPaymentsMetricsTest, LogInitiatePaymentAttempt) { base::HistogramTester histogram_tester; @@ -335,6 +324,52 @@ } TEST_P(FacilitatedPaymentsMetricsParameterizedTest, + LogGetClientTokenResultAndLatency_Success) { + base::HistogramTester histogram_tester; + + LogGetClientTokenResultAndLatency(payment_type(), /*result=*/true, + base::Milliseconds(10), scheme()); + + histogram_tester.ExpectUniqueSample( + base::StrCat({"FacilitatedPayments.", GetFacilitatedPaymentsTypeString(), + ".GetClientToken.Success.Latency"}), + /*sample=*/10, + /*expected_bucket_count=*/1); + histogram_tester.ExpectUniqueSample( + base::StrCat( + {"FacilitatedPayments.Ewallet.GetClientToken.Success.Latency.", + GetSchemeString()}), + /*sample=*/10, + /*expected_bucket_count=*/payment_type() == + FacilitatedPaymentsType::kEwallet + ? 1 + : 0); +} + +TEST_P(FacilitatedPaymentsMetricsParameterizedTest, + LogGetClientTokenResultAndLatency_Failure) { + base::HistogramTester histogram_tester; + + LogGetClientTokenResultAndLatency(payment_type(), /*result=*/false, + base::Milliseconds(10), scheme()); + + histogram_tester.ExpectUniqueSample( + base::StrCat({"FacilitatedPayments.", GetFacilitatedPaymentsTypeString(), + ".GetClientToken.Failure.Latency"}), + /*sample=*/10, + /*expected_bucket_count=*/1); + histogram_tester.ExpectUniqueSample( + base::StrCat( + {"FacilitatedPayments.Ewallet.GetClientToken.Failure.Latency.", + GetSchemeString()}), + /*sample=*/10, + /*expected_bucket_count=*/payment_type() == + FacilitatedPaymentsType::kEwallet + ? 1 + : 0); +} + +TEST_P(FacilitatedPaymentsMetricsParameterizedTest, LogLoadRiskDataResult_Success) { base::HistogramTester histogram_tester;
diff --git a/components/leveldb_proto/internal/proto_leveldb_wrapper.h b/components/leveldb_proto/internal/proto_leveldb_wrapper.h index 81345ef..8826c2f 100644 --- a/components/leveldb_proto/internal/proto_leveldb_wrapper.h +++ b/components/leveldb_proto/internal/proto_leveldb_wrapper.h
@@ -151,7 +151,7 @@ // Used to run blocking tasks in-order, must be the TaskRunner that |db_| // relies on. scoped_refptr<base::SequencedTaskRunner> task_runner_; - raw_ptr<LevelDB, AcrossTasksDanglingUntriaged> db_ = nullptr; + raw_ptr<LevelDB> db_ = nullptr; // The identifier used when recording metrics to determine the source of the // LevelDB calls, likely the database client name.
diff --git a/components/leveldb_proto/internal/unique_proto_database_unittest.cc b/components/leveldb_proto/internal/unique_proto_database_unittest.cc index 0afe16c..240bd27 100644 --- a/components/leveldb_proto/internal/unique_proto_database_unittest.cc +++ b/components/leveldb_proto/internal/unique_proto_database_unittest.cc
@@ -224,24 +224,33 @@ } } -class UniqueProtoDatabaseTest : public testing::Test { +// RAII wrapper around `ProtoDatabaseImpl<TestProto>` that waits for posted +// tasks to complete when destroyed. +class ScopedProtoDatabase { public: - UniqueProtoDatabaseTest() - : options_(MakeMatcher(new OptionsEqMatcher(CreateSimpleOptions()))) {} - void SetUp() override { - db_ = std::make_unique<ProtoDatabaseImpl<TestProto>>( - ProtoDbType::TEST_DATABASE0, base::FilePath(), - base::SingleThreadTaskRunner::GetCurrentDefault()); - } - - void TearDown() override { + ScopedProtoDatabase() + : db_(std::make_unique<ProtoDatabaseImpl<TestProto>>( + ProtoDbType::TEST_DATABASE0, + base::FilePath(), + base::SingleThreadTaskRunner::GetCurrentDefault())) {} + ~ScopedProtoDatabase() { db_.reset(); base::RunLoop().RunUntilIdle(); } + ProtoDatabaseImpl<TestProto>* operator->() { return db_.get(); } + + private: + std::unique_ptr<ProtoDatabaseImpl<TestProto>> db_; +}; + +class UniqueProtoDatabaseTest : public testing::Test { + public: + UniqueProtoDatabaseTest() + : options_(MakeMatcher(new OptionsEqMatcher(CreateSimpleOptions()))) {} + const Matcher<const Options&> options_; TaskEnvironment task_environment_; - std::unique_ptr<ProtoDatabaseImpl<TestProto>> db_; }; // Test that UniqueProtoDatabase calls Init on the underlying database and that @@ -256,9 +265,10 @@ MockDatabaseCaller caller; EXPECT_CALL(caller, InitStatusCallback(Enums::InitStatus::kOK)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); } @@ -276,9 +286,10 @@ MockDatabaseCaller caller; EXPECT_CALL(caller, InitStatusCallback(Enums::InitStatus::kError)); - db_->InitWithDatabase(mock_db.get(), path, options, - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, options, + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); } @@ -293,13 +304,14 @@ MockDatabaseCaller caller; EXPECT_CALL(caller, InitStatusCallback(Enums::InitStatus::kOK)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); EXPECT_CALL(caller, DestroyCallback(true)); - db_->Destroy(base::BindOnce(&MockDatabaseCaller::DestroyCallback, - base::Unretained(&caller))); + db->Destroy(base::BindOnce(&MockDatabaseCaller::DestroyCallback, + base::Unretained(&caller))); EXPECT_CALL(*mock_db, Destroy()).WillOnce(Return(leveldb::Status())); base::RunLoop().RunUntilIdle(); @@ -315,13 +327,14 @@ MockDatabaseCaller caller; EXPECT_CALL(caller, InitStatusCallback(Enums::InitStatus::kOK)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); EXPECT_CALL(caller, DestroyCallback(false)); - db_->Destroy(base::BindOnce(&MockDatabaseCaller::DestroyCallback, - base::Unretained(&caller))); + db->Destroy(base::BindOnce(&MockDatabaseCaller::DestroyCallback, + base::Unretained(&caller))); EXPECT_CALL(*mock_db, Destroy()) .WillOnce( Return(leveldb::Status::IOError(leveldb::Slice(), leveldb::Slice()))); @@ -371,15 +384,16 @@ EXPECT_CALL(*mock_db, Init(_, options_, _)); EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); EXPECT_CALL(*mock_db, LoadKeysAndEntriesWhile(_, _, _, _)) .WillOnce(AppendLoadKeysAndEntries(model)); EXPECT_CALL(caller, LoadKeysAndEntriesCallback1(true, _)) .WillOnce(VerifyLoadKeysAndEntries(testing::ByRef(model))); - db_->LoadKeysAndEntries( + db->LoadKeysAndEntries( base::BindOnce(&MockDatabaseCaller::LoadKeysAndEntriesCallback, base::Unretained(&caller))); @@ -394,14 +408,15 @@ EXPECT_CALL(*mock_db, Init(_, options_, _)); EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); EXPECT_CALL(*mock_db, LoadWithFilter(_, _, _, _)).WillOnce(Return(false)); EXPECT_CALL(caller, LoadCallback1(false, _)); - db_->LoadEntries(base::BindOnce(&MockDatabaseCaller::LoadCallback, - base::Unretained(&caller))); + db->LoadEntries(base::BindOnce(&MockDatabaseCaller::LoadCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); } @@ -419,9 +434,11 @@ expected["d"] = model["d"]; EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(db.get(), temp_dir.GetPath(), CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase proto_db; + proto_db->InitWithDatabase( + db.get(), temp_dir.GetPath(), CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); auto save_entries = std::make_unique<ProtoDatabase<TestProto>::KeyEntryVector>(); @@ -433,14 +450,14 @@ leveldb::Status status; EXPECT_CALL(caller, SaveCallback(true)); - db_->UpdateEntries(std::move(save_entries), std::move(remove_keys), - base::BindOnce(&MockDatabaseCaller::SaveCallback, - base::Unretained(&caller))); + proto_db->UpdateEntries(std::move(save_entries), std::move(remove_keys), + base::BindOnce(&MockDatabaseCaller::SaveCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); EXPECT_CALL(caller, LoadKeysAndEntriesCallback1(true, _)) .WillOnce(VerifyLoadKeysAndEntries(testing::ByRef(expected))); - db_->LoadKeysAndEntriesInRange( + proto_db->LoadKeysAndEntriesInRange( "b", "d", base::BindOnce(&MockDatabaseCaller::LoadKeysAndEntriesCallback, base::Unretained(&caller))); @@ -460,9 +477,11 @@ expected["d"] = model["d"]; EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(db.get(), temp_dir.GetPath(), CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase proto_db; + proto_db->InitWithDatabase( + db.get(), temp_dir.GetPath(), CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); auto save_entries = std::make_unique<ProtoDatabase<TestProto>::KeyEntryVector>(); @@ -475,14 +494,14 @@ leveldb::Status status; EXPECT_CALL(caller, SaveCallback(true)); - db_->UpdateEntries(std::move(save_entries), std::move(remove_keys), - base::BindOnce(&MockDatabaseCaller::SaveCallback, - base::Unretained(&caller))); + proto_db->UpdateEntries(std::move(save_entries), std::move(remove_keys), + base::BindOnce(&MockDatabaseCaller::SaveCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); EXPECT_CALL(caller, LoadKeysAndEntriesCallback1(true, _)) .WillOnce(VerifyLoadKeysAndEntries(testing::ByRef(expected))); - db_->LoadKeysAndEntriesInRange( + proto_db->LoadKeysAndEntriesInRange( "d", "d", base::BindOnce(&MockDatabaseCaller::LoadKeysAndEntriesCallback, base::Unretained(&caller))); @@ -518,17 +537,18 @@ EXPECT_CALL(*mock_db, Init(_, options_, _)); EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); std::string key("1"); ASSERT_TRUE(model.count(key)); EXPECT_CALL(*mock_db, Get(key, _, _, _)).WillOnce(SetGetEntry(model)); EXPECT_CALL(caller, GetCallback1(true, _)) .WillOnce(VerifyGetEntry(model[key])); - db_->GetEntry(key, base::BindOnce(&MockDatabaseCaller::GetCallback, - base::Unretained(&caller))); + db->GetEntry(key, base::BindOnce(&MockDatabaseCaller::GetCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); } @@ -544,9 +564,10 @@ EXPECT_CALL(*mock_db, UpdateWithRemoveFilter(_, _, kTestPrefix, _)) .WillOnce(Return(true)); EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); @@ -557,7 +578,7 @@ std::move(signal).Run(); }, run_update_entries.QuitClosure()); - db_->RemoveKeysForTesting( + db->RemoveKeysForTesting( base::BindRepeating([](const std::string& str) { return true; }), kTestPrefix, std::move(expect_update_success)); run_update_entries.Run(); @@ -632,16 +653,17 @@ EXPECT_CALL(*mock_db, Init(_, options_, _)); EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); std::string key("does_not_exist"); ASSERT_FALSE(model.count(key)); EXPECT_CALL(*mock_db, Get(key, _, _, _)).WillOnce(SetGetEntry(model)); EXPECT_CALL(caller, GetCallback1(true, nullptr)); - db_->GetEntry(key, base::BindOnce(&MockDatabaseCaller::GetCallback, - base::Unretained(&caller))); + db->GetEntry(key, base::BindOnce(&MockDatabaseCaller::GetCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); } @@ -655,16 +677,17 @@ EXPECT_CALL(*mock_db, Init(_, options_, _)); EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); std::string key("does_not_exist"); ASSERT_FALSE(model.count(key)); EXPECT_CALL(*mock_db, Get(key, _, _, _)).WillOnce(Return(false)); EXPECT_CALL(caller, GetCallback1(false, nullptr)); - db_->GetEntry(key, base::BindOnce(&MockDatabaseCaller::GetCallback, - base::Unretained(&caller))); + db->GetEntry(key, base::BindOnce(&MockDatabaseCaller::GetCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); } @@ -700,9 +723,10 @@ EXPECT_CALL(*mock_db, Init(_, options_, _)); EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); std::unique_ptr<ProtoDatabase<TestProto>::KeyEntryVector> entries( new ProtoDatabase<TestProto>::KeyEntryVector()); @@ -713,9 +737,9 @@ EXPECT_CALL(*mock_db, Save(_, _, _)).WillOnce(VerifyUpdateEntries(model)); EXPECT_CALL(caller, SaveCallback(true)); - db_->UpdateEntries(std::move(entries), std::move(keys_to_remove), - base::BindOnce(&MockDatabaseCaller::SaveCallback, - base::Unretained(&caller))); + db->UpdateEntries(std::move(entries), std::move(keys_to_remove), + base::BindOnce(&MockDatabaseCaller::SaveCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); } @@ -731,15 +755,16 @@ EXPECT_CALL(*mock_db, Init(_, options_, _)); EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); EXPECT_CALL(*mock_db, Save(_, _, _)).WillOnce(Return(false)); EXPECT_CALL(caller, SaveCallback(false)); - db_->UpdateEntries(std::move(entries), std::move(keys_to_remove), - base::BindOnce(&MockDatabaseCaller::SaveCallback, - base::Unretained(&caller))); + db->UpdateEntries(std::move(entries), std::move(keys_to_remove), + base::BindOnce(&MockDatabaseCaller::SaveCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); } @@ -756,9 +781,10 @@ EXPECT_CALL(*mock_db, Init(_, options_, _)); EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); std::unique_ptr<ProtoDatabase<TestProto>::KeyEntryVector> entries( new ProtoDatabase<TestProto>::KeyEntryVector()); @@ -769,9 +795,9 @@ KeyVector keys_copy(*keys_to_remove.get()); EXPECT_CALL(*mock_db, Save(_, keys_copy, _)).WillOnce(Return(true)); EXPECT_CALL(caller, SaveCallback(true)); - db_->UpdateEntries(std::move(entries), std::move(keys_to_remove), - base::BindOnce(&MockDatabaseCaller::SaveCallback, - base::Unretained(&caller))); + db->UpdateEntries(std::move(entries), std::move(keys_to_remove), + base::BindOnce(&MockDatabaseCaller::SaveCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); } @@ -787,15 +813,16 @@ EXPECT_CALL(*mock_db, Init(_, options_, _)); EXPECT_CALL(caller, InitStatusCallback(_)); - db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), - base::BindOnce(&MockDatabaseCaller::InitStatusCallback, - base::Unretained(&caller))); + ScopedProtoDatabase db; + db->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(), + base::BindOnce(&MockDatabaseCaller::InitStatusCallback, + base::Unretained(&caller))); EXPECT_CALL(*mock_db, Save(_, _, _)).WillOnce(Return(false)); EXPECT_CALL(caller, SaveCallback(false)); - db_->UpdateEntries(std::move(entries), std::move(keys_to_remove), - base::BindOnce(&MockDatabaseCaller::SaveCallback, - base::Unretained(&caller))); + db->UpdateEntries(std::move(entries), std::move(keys_to_remove), + base::BindOnce(&MockDatabaseCaller::SaveCallback, + base::Unretained(&caller))); base::RunLoop().RunUntilIdle(); }
diff --git a/components/live_caption/BUILD.gn b/components/live_caption/BUILD.gn index e43d34d..770625c 100644 --- a/components/live_caption/BUILD.gn +++ b/components/live_caption/BUILD.gn
@@ -12,6 +12,8 @@ "caption_bubble_context_remote.h", "caption_bubble_controller.h", "caption_bubble_session_observer.h", + "live_caption_controller.cc", + "live_caption_controller.h", ] deps = [ @@ -57,20 +59,6 @@ "//ui/views", ] } # toolkit_views - - if (is_chromeos_ash) { - sources += [ - "live_caption_ui_remote_driver.cc", - "live_caption_ui_remote_driver.h", - ] - } # is_chromeos_ash - - if (!is_chromeos_lacros) { - sources += [ - "live_caption_controller.cc", - "live_caption_controller.h", - ] - } } static_library("live_translate") { @@ -122,7 +110,7 @@ "//ui/gfx/geometry:geometry", ] - if (is_chromeos_ash) { + if (is_chromeos) { sources += [ "caption_bubble_context_remote_unittest.cc",
diff --git a/components/live_caption/caption_util.cc b/components/live_caption/caption_util.cc index 6c1797a..51856708 100644 --- a/components/live_caption/caption_util.cc +++ b/components/live_caption/caption_util.cc
@@ -13,7 +13,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/live_caption/pref_names.h" #include "components/prefs/pref_service.h" #include "ui/base/ui_base_switches.h"
diff --git a/components/live_caption/live_caption_controller.cc b/components/live_caption/live_caption_controller.cc index bea19ca4..b5f34a9f 100644 --- a/components/live_caption/live_caption_controller.cc +++ b/components/live_caption/live_caption_controller.cc
@@ -118,7 +118,7 @@ prefs::kLiveCaptionMediaFoundationRendererErrorSilenced, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Flags for User Microphone Captioning are only available on ash. registry->RegisterBooleanPref(prefs::kLiveCaptionUserMicrophoneEnabled, false); @@ -156,7 +156,7 @@ } bool LiveCaptionController::IsLiveCaptionEnabled() { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) return enabled_for_babel_orca_ || profile_prefs_->GetBoolean(prefs::kLiveCaptionEnabled); #else @@ -194,7 +194,7 @@ bool is_language_code_for_live_caption = prefs::IsLanguageCodeForLiveCaption(language_code, profile_prefs_); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) bool is_language_code_for_babel_orca = prefs::IsLanguageCodeForMicrophoneCaption(language_code, profile_prefs_); @@ -286,7 +286,7 @@ } const std::string LiveCaptionController::GetLanguageCode() const { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) if (enabled_for_babel_orca_) { return prefs::GetUserMicrophoneCaptionLanguage(profile_prefs_); } @@ -350,7 +350,7 @@ } #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void LiveCaptionController::ToggleLiveCaptionForBabelOrca(bool enabled) { enabled_for_babel_orca_ = enabled; OnLiveCaptionEnabledChanged();
diff --git a/components/live_caption/live_caption_controller.h b/components/live_caption/live_caption_controller.h index 70af1fb2..bb5e119 100644 --- a/components/live_caption/live_caption_controller.h +++ b/components/live_caption/live_caption_controller.h
@@ -87,9 +87,9 @@ void OnToggleFullscreen(CaptionBubbleContext* caption_bubble_context); #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void ToggleLiveCaptionForBabelOrca(bool enabled); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) CaptionBubbleController* caption_bubble_controller_for_testing() { return caption_bubble_controller_.get(); @@ -127,7 +127,7 @@ const std::string application_locale_; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Tracks whether or not Live Caption has been enabled for babel orca. bool enabled_for_babel_orca_ = false; #endif
diff --git a/components/live_caption/live_caption_controller_unittest.cc b/components/live_caption/live_caption_controller_unittest.cc index a31d1d6..42944f2 100644 --- a/components/live_caption/live_caption_controller_unittest.cc +++ b/components/live_caption/live_caption_controller_unittest.cc
@@ -110,7 +110,7 @@ speech::kUsEnglishLocale); // Babel Orca flags are only registered on ash. -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) EXPECT_FALSE(testing_pref_service_.GetBoolean( prefs::kLiveCaptionUserMicrophoneEnabled)); EXPECT_EQ(testing_pref_service_.GetString(
diff --git a/components/live_caption/live_caption_ui_remote_driver.cc b/components/live_caption/live_caption_ui_remote_driver.cc deleted file mode 100644 index f0b4df1..0000000 --- a/components/live_caption/live_caption_ui_remote_driver.cc +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/live_caption/live_caption_ui_remote_driver.h" - -#include <string> -#include <utility> - -#include "base/functional/callback_forward.h" -#include "components/live_caption/caption_bubble_context_remote.h" -#include "components/live_caption/live_caption_controller.h" -#include "mojo/public/cpp/bindings/receiver.h" - -namespace captions { - -LiveCaptionUiRemoteDriver::LiveCaptionUiRemoteDriver( - LiveCaptionController* controller, - mojo::PendingReceiver<media::mojom::SpeechRecognitionSurfaceClient> - client_receiver, - mojo::PendingRemote<media::mojom::SpeechRecognitionSurface> surface_remote, - const std::string& session_id) - : controller_(controller), - client_receiver_(this, std::move(client_receiver)), - context_(std::move(surface_remote), session_id) {} - -LiveCaptionUiRemoteDriver::~LiveCaptionUiRemoteDriver() { - controller_->OnAudioStreamEnd(&context_); -} - -void LiveCaptionUiRemoteDriver::OnSpeechRecognitionRecognitionEvent( - const media::SpeechRecognitionResult& result, - OnSpeechRecognitionRecognitionEventCallback reply) { - std::move(reply).Run(controller_->DispatchTranscription(&context_, result)); -} - -void LiveCaptionUiRemoteDriver::OnLanguageIdentificationEvent( - media::mojom::LanguageIdentificationEventPtr event) { - controller_->OnLanguageIdentificationEvent(&context_, std::move(event)); -} - -void LiveCaptionUiRemoteDriver::OnSpeechRecognitionError() { - controller_->OnError(&context_, CaptionBubbleErrorType::kGeneric, - base::RepeatingClosure(), - base::BindRepeating([](CaptionBubbleErrorType error_type, - bool checked) {})); -} - -void LiveCaptionUiRemoteDriver::OnSpeechRecognitionStopped() { - controller_->OnAudioStreamEnd(&context_); -} - -void LiveCaptionUiRemoteDriver::OnSessionEnded() { - context_.OnSessionEnded(); -} - -void LiveCaptionUiRemoteDriver::OnFullscreenToggled() { - controller_->OnToggleFullscreen(&context_); -} - -} // namespace captions
diff --git a/components/live_caption/live_caption_ui_remote_driver.h b/components/live_caption/live_caption_ui_remote_driver.h deleted file mode 100644 index fd5322f..0000000 --- a/components/live_caption/live_caption_ui_remote_driver.h +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_LIVE_CAPTION_LIVE_CAPTION_UI_REMOTE_DRIVER_H_ -#define COMPONENTS_LIVE_CAPTION_LIVE_CAPTION_UI_REMOTE_DRIVER_H_ - -#include <memory> - -#include "base/memory/raw_ptr.h" -#include "components/live_caption/caption_bubble_context_remote.h" -#include "media/mojo/mojom/speech_recognition.mojom.h" -#include "mojo/public/cpp/bindings/receiver.h" - -namespace captions { - -class CaptionBubbleContextRemote; -class LiveCaptionController; - -// Receives both speech recognition events and speech surface events (e.g. -// fullscreen-ing) from remote lacros processes, passing them to the live -// caption UI. -// -// One driver exists in the Ash browser process for each caption-producing -// stream of media in a lacros renderer. -class LiveCaptionUiRemoteDriver - : public media::mojom::SpeechRecognitionSurfaceClient, - public media::mojom::SpeechRecognitionRecognizerClient { - public: - // The speech surface client implementation is bound at construction time, but - // the speech recognition client implementation is bound in the "client - // browser interface"'s receiver set. - LiveCaptionUiRemoteDriver( - LiveCaptionController* controller, - mojo::PendingReceiver<media::mojom::SpeechRecognitionSurfaceClient> - client_receiver, - mojo::PendingRemote<media::mojom::SpeechRecognitionSurface> surface, - const std::string& session_id); - ~LiveCaptionUiRemoteDriver() override; - - // media::mojom::SpeechOriginRecognizerClient: - void OnSpeechRecognitionRecognitionEvent( - const media::SpeechRecognitionResult& result, - OnSpeechRecognitionRecognitionEventCallback reply) override; - void OnLanguageIdentificationEvent( - media::mojom::LanguageIdentificationEventPtr event) override; - void OnSpeechRecognitionError() override; - void OnSpeechRecognitionStopped() override; - - // media::mojom::SpeechRecognitionSurfaceClient: - void OnSessionEnded() override; - void OnFullscreenToggled() override; - - private: - // We are owned by the "client browser interface", which is a service that - // `DependsOn` the controller. Hence the controller is guaranteed to exist. - const raw_ptr<LiveCaptionController> controller_; - - mojo::Receiver<media::mojom::SpeechRecognitionSurfaceClient> client_receiver_; - - CaptionBubbleContextRemote context_; -}; - -} // namespace captions - -#endif // COMPONENTS_LIVE_CAPTION_LIVE_CAPTION_UI_REMOTE_DRIVER_H_
diff --git a/components/live_caption/pref_names.cc b/components/live_caption/pref_names.cc index 0721042a..8a6328a 100644 --- a/components/live_caption/pref_names.cc +++ b/components/live_caption/pref_names.cc
@@ -45,7 +45,7 @@ #endif // !defined(ANDROID) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) const std::string GetUserMicrophoneCaptionLanguage(PrefService* profile_prefs) { return GetCaptionLanguageCodeForPref( prefs::kUserMicrophoneCaptionLanguageCode, profile_prefs);
diff --git a/components/live_caption/pref_names.h b/components/live_caption/pref_names.h index dd4e6d4..0c2ad5c 100644 --- a/components/live_caption/pref_names.h +++ b/components/live_caption/pref_names.h
@@ -8,7 +8,6 @@ #include <string> #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #if !BUILDFLAG(IS_ANDROID) #include "components/soda/constants.h" @@ -44,7 +43,7 @@ "silenced"; // This may be removed in the future but for now these preferences are ash only. -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Enables Captioning from microphone input. inline constexpr char kLiveCaptionUserMicrophoneEnabled[] = @@ -59,7 +58,7 @@ bool IsLanguageCodeForMicrophoneCaption(speech::LanguageCode language_code, PrefService* profile_prefs); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) const std::string GetLiveCaptionLanguageCode(PrefService* profile_prefs); bool IsLanguageCodeForLiveCaption(speech::LanguageCode language_code,
diff --git a/components/live_caption/views/caption_bubble.cc b/components/live_caption/views/caption_bubble.cc index 6f20593..61f0cf09 100644 --- a/components/live_caption/views/caption_bubble.cc +++ b/components/live_caption/views/caption_bubble.cc
@@ -231,7 +231,7 @@ namespace captions { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIsCaptionBubbleKey, false) #endif @@ -913,7 +913,7 @@ params->z_order = ui::ZOrderLevel::kFloatingWindow; params->visible_on_all_workspaces = true; params->name = "LiveCaptionWindow"; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) params->init_properties_container.SetProperty(kIsCaptionBubbleKey, true); #endif }
diff --git a/components/live_caption/views/caption_bubble.h b/components/live_caption/views/caption_bubble.h index 08a1330..f74064b 100644 --- a/components/live_caption/views/caption_bubble.h +++ b/components/live_caption/views/caption_bubble.h
@@ -65,7 +65,7 @@ }; // LINT.ThenChange(/tools/metrics/histograms/metadata/accessibility/enums.xml:LiveCaptionSessionEvent) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Used by ash window manager to place the caption bubble in the correct // container. extern const ui::ClassProperty<bool>* const kIsCaptionBubbleKey;
diff --git a/components/live_caption/views/caption_bubble_controller_views.cc b/components/live_caption/views/caption_bubble_controller_views.cc index b887de2..979bc44 100644 --- a/components/live_caption/views/caption_bubble_controller_views.cc +++ b/components/live_caption/views/caption_bubble_controller_views.cc
@@ -43,19 +43,19 @@ views::BubbleDialogDelegateView::CreateBubble(caption_bubble_); caption_bubble_->SetCaptionBubbleStyle(); -#if !BUILDFLAG(IS_CHROMEOS_ASH) +#if !BUILDFLAG(IS_CHROMEOS) speech::SodaInstaller* soda_installer = speech::SodaInstaller::GetInstance(); if (soda_installer) { soda_installer->AddObserver(this); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } CaptionBubbleControllerViews::~CaptionBubbleControllerViews() { if (caption_widget_) caption_widget_->CloseNow(); -#if !BUILDFLAG(IS_CHROMEOS_ASH) +#if !BUILDFLAG(IS_CHROMEOS) speech::SodaInstaller* soda_installer = speech::SodaInstaller::GetInstance(); // `soda_installer` is not guaranteed to be valid, since it's possible for // this class to out-live it. This means that this class cannot use @@ -63,7 +63,7 @@ if (soda_installer) { soda_installer->RemoveObserver(this); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } void CaptionBubbleControllerViews::OnCaptionBubbleDestroyed() {
diff --git a/components/manta/walrus_provider.cc b/components/manta/walrus_provider.cc index e883c82..5b75203 100644 --- a/components/manta/walrus_provider.cc +++ b/components/manta/walrus_provider.cc
@@ -5,6 +5,7 @@ #include "components/manta/walrus_provider.h" #include <algorithm> +#include <cstdint> #include "components/manta/features.h" #include "third_party/skia/include/codec/SkJpegDecoder.h" @@ -110,9 +111,36 @@ return gfx::JPEGCodec::Encode(resized_bitmap, /*quality=*/90); } +std::string GetImageTypeTag(WalrusProvider::ImageType image_type) { + switch (image_type) { + case WalrusProvider::ImageType::kInputImage: + return "input_image"; + case WalrusProvider::ImageType::kOutputImage: + return "output_image"; + case WalrusProvider::ImageType::kGeneratedRegion: + return "generated_region"; + default: + return "input_image"; + } +} + void WalrusProvider::Filter(const std::optional<std::string>& text_prompt, const std::vector<std::vector<uint8_t>>& images, MantaGenericCallback done_callback) { + std::vector<ImageType> image_types(images.size(), ImageType::kInputImage); + Filter(text_prompt, images, image_types, std::move(done_callback)); +} + +void WalrusProvider::Filter(const std::optional<std::string>& text_prompt, + const std::vector<std::vector<uint8_t>>& images, + const std::vector<ImageType>& image_types, + MantaGenericCallback done_callback) { + if (images.size() != image_types.size()) { + std::move(done_callback) + .Run(base::Value::Dict(), {MantaStatusCode::kInvalidInput}); + return; + } + proto::Request request; request.set_feature_name(proto::FeatureName::CHROMEOS_WALRUS); @@ -122,9 +150,12 @@ input_data->set_text(text_prompt.value()); } - for (auto& image : images) { + for (size_t i = 0; i < images.size(); ++i) { + const std::vector<uint8_t>& image = images[i]; + const ImageType& image_type = image_types[i]; + auto* input_data = request.add_input_data(); - input_data->set_tag("input_image"); + input_data->set_tag(GetImageTypeTag(image_type)); auto resized_image_bytes = DownscaleImageIfNeeded(image); if (resized_image_bytes.has_value()) { input_data->mutable_image()->set_serialized_bytes(
diff --git a/components/manta/walrus_provider.h b/components/manta/walrus_provider.h index 371252af..df033598 100644 --- a/components/manta/walrus_provider.h +++ b/components/manta/walrus_provider.h
@@ -31,6 +31,13 @@ // `IdentityManager` destruction. class COMPONENT_EXPORT(MANTA) WalrusProvider : virtual public BaseProvider { public: + // Enum for different image types used in Walrus requests. + enum class ImageType { + kInputImage, + kOutputImage, + kGeneratedRegion, + }; + // Returns a `WalrusProvider` instance tied to the profile of the passed // arguments. WalrusProvider( @@ -52,6 +59,14 @@ const std::vector<std::vector<uint8_t>>& images, MantaGenericCallback done_callback); + // Filters the given `text_prompt` and `images`. The `image_types` vector + // specifies the type of each image in the `images` vector. + // The sizes of `images` and `image_types` must match. + virtual void Filter(const std::optional<std::string>& text_prompt, + const std::vector<std::vector<uint8_t>>& images, + const std::vector<ImageType>& image_types, + MantaGenericCallback done_callback); + // Filters the given `text_prompt`. virtual void Filter(const std::string text_prompt, MantaGenericCallback done_callback);
diff --git a/components/manta/walrus_provider_unittest.cc b/components/manta/walrus_provider_unittest.cc index 0ba3e7b..3aa968a 100644 --- a/components/manta/walrus_provider_unittest.cc +++ b/components/manta/walrus_provider_unittest.cc
@@ -319,4 +319,79 @@ ASSERT_EQ(resized_image.height(), 12); } +// Test the response when the generated region is provided. +TEST_F(WalrusProviderTest, GeneratedRegion) { + std::string generated_region_image_bytes = "generated_region_image_bytes"; + manta::proto::Response response; + auto* output_data = response.add_output_data(); + output_data->set_text("text prompt"); + + output_data = response.add_output_data(); + // Aratea should return the tag instead of image + output_data->set_text("generated_region"); + + std::string response_data; + response.SerializeToString(&response_data); + + SetEndpointMockResponse(GURL{kMockEndpoint}, response_data, net::HTTP_OK, + net::OK); + std::unique_ptr<FakeWalrusProvider> walrus_provider = CreateWalrusProvider(); + auto quit_closure = task_environment_.QuitClosure(); + std::optional<std::string> text_prompt = "text pompt"; + std::vector<std::vector<uint8_t>> images = { + std::vector<uint8_t>(generated_region_image_bytes.begin(), + generated_region_image_bytes.end())}; + std::vector<manta::WalrusProvider::ImageType> image_types = { + manta::WalrusProvider::ImageType::kGeneratedRegion}; + + walrus_provider->Filter( + text_prompt, images, image_types, + base::BindLambdaForTesting([&quit_closure](base::Value::Dict response, + MantaStatus manta_status) { + // Even though the response has text and image, walrus just + // returns the status code + ASSERT_EQ(MantaStatusCode::kOk, manta_status.status_code); + ASSERT_TRUE(response.empty()); + quit_closure.Run(); + })); + task_environment_.RunUntilQuit(); +} + +// Test the response when the image type argument size mismatch with number of +// images. +TEST_F(WalrusProviderTest, ImageTypeSizeMismatch) { + std::string generated_region_image_bytes = "generated_region_image_bytes"; + manta::proto::Response response; + auto* output_data = response.add_output_data(); + output_data->set_text("text prompt"); + + output_data = response.add_output_data(); + // Aratea should return the tag instead of image + output_data->set_text("output_image"); + + std::string response_data; + response.SerializeToString(&response_data); + + SetEndpointMockResponse(GURL{kMockEndpoint}, response_data, net::HTTP_OK, + net::OK); + std::unique_ptr<FakeWalrusProvider> walrus_provider = CreateWalrusProvider(); + auto quit_closure = task_environment_.QuitClosure(); + std::optional<std::string> text_prompt = "text pompt"; + std::vector<std::vector<uint8_t>> images = { + std::vector<uint8_t>(generated_region_image_bytes.begin(), + generated_region_image_bytes.end())}; + std::vector<manta::WalrusProvider::ImageType> image_types = { + manta::WalrusProvider::ImageType::kOutputImage, + manta::WalrusProvider::ImageType::kGeneratedRegion}; + + walrus_provider->Filter( + text_prompt, images, image_types, + base::BindLambdaForTesting([&quit_closure](base::Value::Dict response, + MantaStatus manta_status) { + EXPECT_EQ(manta_status.status_code, MantaStatusCode::kInvalidInput); + quit_closure.Run(); + })); + task_environment_.RunUntilQuit(); +} + } // namespace manta
diff --git a/components/media_effects/media_effects_mediapipe_unittests.cc b/components/media_effects/media_effects_mediapipe_unittests.cc index d07bd68..45bc3c0 100644 --- a/components/media_effects/media_effects_mediapipe_unittests.cc +++ b/components/media_effects/media_effects_mediapipe_unittests.cc
@@ -4,20 +4,14 @@ #include <vector> -#include "testing/gtest/include/gtest/gtest.h" - #include "build/buildflag.h" +#include "testing/gtest/include/gtest/gtest.h" #include "third_party/mediapipe/buildflags.h" #include "third_party/mediapipe/src/mediapipe/framework/calculator.pb.h" #include "third_party/mediapipe/src/mediapipe/framework/calculator_graph.h" -#include "third_party/mediapipe/src/mediapipe/framework/formats/image_frame.h" namespace { -[[maybe_unused]] uint8_t GetPixelValue(int x, int y, int iteration) { - return (1 + 3 * x + 5 * y + 2 * iteration) % 256; -} - TEST(MediaEffectsMediaPipe, OnCpu) { // Configures a simple graph, which concatenates 2 PassThroughCalculators. @@ -81,93 +75,4 @@ ASSERT_TRUE(status.ok()) << "WaitUntilDone() failed, error: " << status; } -#if BUILDFLAG(MEDIAPIPE_BUILD_WITH_GPU_SUPPORT) -TEST(MediaEffectsMediaPipe, OnGpu) { - // Configures a simple graph, which sends an on-CPU frame to GPU and then - // reads back from it. - - mediapipe::CalculatorGraphConfig config; - config.add_input_stream("in"); - config.add_output_stream("out"); - - auto* node1 = config.add_node(); - *node1->mutable_calculator() = "ImageFrameToGpuBufferCalculator"; - node1->add_input_stream("in"); - node1->add_output_stream("out1"); - - auto* node2 = config.add_node(); - *node2->mutable_calculator() = "GpuBufferToImageFrameCalculator"; - node2->add_input_stream("out1"); - node2->add_output_stream("out"); - - mediapipe::CalculatorGraph graph; - absl::Status status = graph.Initialize(config); - ASSERT_TRUE(status.ok()) << "Failed to initialize calculator graph, error: " - << status; - - absl::StatusOr<mediapipe::OutputStreamPoller> maybe_poller = - graph.AddOutputStreamPoller("out"); - ASSERT_TRUE(maybe_poller.ok()) - << "Failed to obtain poller, error: " << maybe_poller.status(); - - mediapipe::OutputStreamPoller poller = std::move(maybe_poller.value()); - - status = graph.StartRun({}); - ASSERT_TRUE(status.ok()) << "Failed to start run on the graph, error: " - << status; - - for (int i = 0; i < 10; ++i) { - mediapipe::ImageFrame input(mediapipe::ImageFormat::SRGBA, 10, 10); - - uint8_t* pixel_data = input.MutablePixelData(); - for (int col = 0; col < input.Width(); ++col) { - for (int row = 0; row < input.Height(); ++row) { - *(pixel_data + row + col * input.WidthStep()) = - GetPixelValue(col, row, i); - } - } - - status = graph.AddPacketToInputStream( - "in", mediapipe::MakePacket<mediapipe::ImageFrame>(std::move(input)) - .At(mediapipe::Timestamp(i))); - ASSERT_TRUE(status.ok()) - << "Failed to add packet to input stream, error: " << status; - } - - // Close the input stream "in". - status = graph.CloseInputStream("in"); - ASSERT_TRUE(status.ok()) << "Failed to close the input stream, error: " - << status; - - int iteration = 0; - mediapipe::Packet packet; - // Get the output packets string. - while (poller.Next(&packet)) { - const mediapipe::ImageFrame& output = packet.Get<mediapipe::ImageFrame>(); - - const uint8_t* pixel_data = output.PixelData(); - for (int col = 0; col < output.Width(); ++col) { - for (int row = 0; row < output.Height(); ++row) { - const uint8_t expected = GetPixelValue(col, row, iteration); - const uint8_t got = *(pixel_data + row + col * output.WidthStep()); - - EXPECT_EQ(got, expected) - << "data mismatch at row " << row << ", column " << col - << ", iteration " << iteration << ", expected " << expected - << ", got " << got; - } - } - - ++iteration; - } - - EXPECT_EQ(iteration, 10) - << "insufficient number of packets read from the graph!"; - - status = graph.WaitUntilDone(); - ASSERT_TRUE(status.ok()) << "WaitUntilDone() failed, error: " << status; -} - -#endif - } // namespace
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc index 4c0fd35..76dfc40e 100644 --- a/components/omnibox/browser/autocomplete_match.cc +++ b/components/omnibox/browser/autocomplete_match.cc
@@ -1120,27 +1120,26 @@ UMA_HISTOGRAM_ENUMERATION("Omnibox.SearchEngineType", search_engine_type, SEARCH_ENGINE_MAX); - if (template_url->created_by_policy() != - TemplateURLData::CreatedByPolicy::kNoPolicy) { + if (template_url->CreatedByPolicy()) { UMA_HISTOGRAM_ENUMERATION("Omnibox.SearchEngineType.SetByEnterprisePolicy", search_engine_type, SEARCH_ENGINE_MAX); - switch (template_url->created_by_policy()) { - case TemplateURLData::CreatedByPolicy::kDefaultSearchProvider: + switch (template_url->policy_origin()) { + case TemplateURLData::PolicyOrigin::kDefaultSearchProvider: UMA_HISTOGRAM_ENUMERATION( "Omnibox.SearchEngineType.SetByEnterprisePolicy." "DefaultSearchProvider", search_engine_type, SEARCH_ENGINE_MAX); break; - case TemplateURLData::CreatedByPolicy::kSiteSearch: + case TemplateURLData::PolicyOrigin::kSiteSearch: UMA_HISTOGRAM_ENUMERATION( "Omnibox.SearchEngineType.SetByEnterprisePolicy." "SiteSearchSettings", search_engine_type, SEARCH_ENGINE_MAX); break; - case TemplateURLData::CreatedByPolicy::kSearchAggregator: + case TemplateURLData::PolicyOrigin::kSearchAggregator: UMA_HISTOGRAM_ENUMERATION( "Omnibox.SearchEngineType.SetByEnterprisePolicy." "EnterpriseSearchAggregatorSettings",
diff --git a/components/omnibox/browser/featured_search_provider_unittest.cc b/components/omnibox/browser/featured_search_provider_unittest.cc index cb3be7a..259aa48 100644 --- a/components/omnibox/browser/featured_search_provider_unittest.cc +++ b/components/omnibox/browser/featured_search_provider_unittest.cc
@@ -164,8 +164,8 @@ template_url_data.SetKeyword(keyword); template_url_data.SetShortName(keyword + u" Name"); template_url_data.SetURL(url); - template_url_data.created_by_policy = - TemplateURLData::CreatedByPolicy::kSiteSearch; + template_url_data.policy_origin = + TemplateURLData::PolicyOrigin::kSiteSearch; template_url_data.enforced_by_policy = false; template_url_data.featured_by_policy = true; template_url_data.safe_for_autoreplace = false;
diff --git a/components/optimization_guide/internal b/components/optimization_guide/internal index b1fb5d5..3260a04b 160000 --- a/components/optimization_guide/internal +++ b/components/optimization_guide/internal
@@ -1 +1 @@ -Subproject commit b1fb5d58cb230fb5d7e2a75cff00ab025d18a6fd +Subproject commit 3260a04b709daada0fdf5039d580550c0ad96c9f
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/LacrosAvailability.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/LacrosAvailability.yaml index 2d329472..89fb2dc 100644 --- a/components/policy/resources/templates/policy_definitions/Miscellaneous/LacrosAvailability.yaml +++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/LacrosAvailability.yaml
@@ -48,6 +48,7 @@ - lacros_only type: string supported_on: -- chrome_os:92- +- chrome_os:92-130 tags: [] type: string-enum +deprecated: true
diff --git a/components/policy/test/data/pref_mapping/LacrosAvailability.json b/components/policy/test/data/pref_mapping/LacrosAvailability.json deleted file mode 100644 index 3fcb1f64..0000000 --- a/components/policy/test/data/pref_mapping/LacrosAvailability.json +++ /dev/null
@@ -1,52 +0,0 @@ -[ - { - "can_be_recommended": false, - "os": [ - "chromeos_ash" - ], - "policy_pref_mapping_tests": [ - { - "policies": {}, - "prefs": { - "lacros_launch_switch": { - "location": "local_state", - "value": 1 - } - } - }, - { - "policies": { - "LacrosAvailability": "user_choice" - }, - "prefs": { - "lacros_launch_switch": { - "location": "local_state", - "value": 0 - } - } - }, - { - "policies": { - "LacrosAvailability": "lacros_disallowed" - }, - "prefs": { - "lacros_launch_switch": { - "location": "local_state", - "value": 1 - } - } - }, - { - "policies": { - "LacrosAvailability": "lacros_only" - }, - "prefs": { - "lacros_launch_switch": { - "location": "local_state", - "value": 4 - } - } - } - ] - } -]
diff --git a/components/power_bookmarks/core/bookmark_client_base.cc b/components/power_bookmarks/core/bookmark_client_base.cc index 962348bf..1fbfbfc 100644 --- a/components/power_bookmarks/core/bookmark_client_base.cc +++ b/components/power_bookmarks/core/bookmark_client_base.cc
@@ -124,8 +124,7 @@ // If there's no suggested folder, ensure we're not accidentally suggesting // one via the most recently modified. for (const bookmarks::BookmarkNode* node : - bookmarks::GetMostRecentlyModifiedUserFolders( - bookmark_model_, save_location_providers_.size() + 1)) { + bookmarks::GetMostRecentlyModifiedUserFolders(bookmark_model_)) { // Suggest first non-suggested folder in the MRU. std::string was_saved_to_suggested; if (!node->GetMetaInfo(kWasSuggestedFolderKey, &was_saved_to_suggested) ||
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc index dfb65b95..9081495 100644 --- a/components/safe_browsing/core/common/features.cc +++ b/components/safe_browsing/core/common/features.cc
@@ -178,10 +178,6 @@ &kExtensionTelemetryForEnterprise, "EnterpriseReportingIntervalSeconds", /*default_value=*/300}; -BASE_FEATURE(kExtensionTelemetryReportContactedHosts, - "SafeBrowsingExtensionTelemetryReportContactedHosts", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE( kExtensionTelemetryInterceptRemoteHostsContactedInRenderer, "SafeBrowsingExtensionTelmetryInterceptRemoteHostsContactedInRenderer", @@ -363,7 +359,6 @@ &kExtensionTelemetryDeclarativeNetRequestActionSignal, &kExtensionTelemetryForEnterprise, &kExtensionTelemetryInterceptRemoteHostsContactedInRenderer, - &kExtensionTelemetryReportContactedHosts, &kExtensionTelemetryTabsExecuteScriptSignal, &kExternalAppRedirectTelemetry, &kHashPrefixRealTimeLookups,
diff --git a/components/safe_browsing/core/common/features.h b/components/safe_browsing/core/common/features.h index b1e82e5..bf08c5d 100644 --- a/components/safe_browsing/core/common/features.h +++ b/components/safe_browsing/core/common/features.h
@@ -172,9 +172,6 @@ // tabs.executeScript API call. BASE_DECLARE_FEATURE(kExtensionTelemetryTabsExecuteScriptSignal); -// Enables reporting of remote hosts contacted by extensions in telemetry. -BASE_DECLARE_FEATURE(kExtensionTelemetryReportContactedHosts); - // Enables intercepting remote hosts contacted by extensions in renderer // throttles. BASE_DECLARE_FEATURE(
diff --git a/components/search_engines/android/template_url_android.cc b/components/search_engines/android/template_url_android.cc index d1661a0..50517fd5 100644 --- a/components/search_engines/android/template_url_android.cc +++ b/components/search_engines/android/template_url_android.cc
@@ -37,8 +37,7 @@ jlong template_url_ptr) { TemplateURL* template_url = ToTemplateURL(template_url_ptr); return template_url->prepopulate_id() > 0 || - template_url->created_by_policy() != - TemplateURLData::CreatedByPolicy::kNoPolicy || + template_url->CreatedByPolicy() || template_url->created_from_play_api(); }
diff --git a/components/search_engines/default_search_manager.cc b/components/search_engines/default_search_manager.cc index cdb0330..d6b631bc 100644 --- a/components/search_engines/default_search_manager.cc +++ b/components/search_engines/default_search_manager.cc
@@ -69,7 +69,7 @@ const char DefaultSearchManager::kUsageCount[] = "usage_count"; const char DefaultSearchManager::kAlternateURLs[] = "alternate_urls"; -const char DefaultSearchManager::kCreatedByPolicy[] = "created_by_policy"; +const char DefaultSearchManager::kPolicyOrigin[] = "policy_origin"; const char DefaultSearchManager::kDisabledByPolicy[] = "disabled_by_policy"; const char DefaultSearchManager::kCreatedFromPlayAPI[] = "created_from_play_api";
diff --git a/components/search_engines/default_search_manager.h b/components/search_engines/default_search_manager.h index 4b4d7df7..37f7266 100644 --- a/components/search_engines/default_search_manager.h +++ b/components/search_engines/default_search_manager.h
@@ -78,7 +78,7 @@ static const char kUsageCount[]; static const char kAlternateURLs[]; - static const char kCreatedByPolicy[]; + static const char kPolicyOrigin[]; static const char kDisabledByPolicy[]; static const char kCreatedFromPlayAPI[]; static const char kFeaturedByPolicy[];
diff --git a/components/search_engines/enterprise/default_search_policy_handler.cc b/components/search_engines/enterprise/default_search_policy_handler.cc index e410594..3bf4e884a 100644 --- a/components/search_engines/enterprise/default_search_policy_handler.cc +++ b/components/search_engines/enterprise/default_search_policy_handler.cc
@@ -208,9 +208,9 @@ dict.Set(DefaultSearchManager::kLastModified, static_cast<double>(base::Time::Now().ToInternalValue())); dict.Set(DefaultSearchManager::kUsageCount, 0); - dict.Set(DefaultSearchManager::kCreatedByPolicy, - static_cast<int>( - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider)); + dict.Set( + DefaultSearchManager::kPolicyOrigin, + static_cast<int>(TemplateURLData::PolicyOrigin::kDefaultSearchProvider)); // For the name and keyword, default to the host if not specified. If // there is no host (as is the case with file URLs of the form:
diff --git a/components/search_engines/enterprise/default_search_policy_handler_unittest.cc b/components/search_engines/enterprise/default_search_policy_handler_unittest.cc index 35e3131..210e892 100644 --- a/components/search_engines/enterprise/default_search_policy_handler_unittest.cc +++ b/components/search_engines/enterprise/default_search_policy_handler_unittest.cc
@@ -202,9 +202,9 @@ const base::Value::Dict* dictionary = temp->GetIfDict(); ASSERT_TRUE(dictionary); - ASSERT_EQ(dictionary->FindInt(DefaultSearchManager::kCreatedByPolicy), - static_cast<int>( - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider)); + ASSERT_EQ( + dictionary->FindInt(DefaultSearchManager::kPolicyOrigin), + static_cast<int>(TemplateURLData::PolicyOrigin::kDefaultSearchProvider)); const std::string* value = nullptr; ASSERT_TRUE(value = dictionary->FindString(DefaultSearchManager::kURL)); EXPECT_EQ(kSearchURL, *value); @@ -305,9 +305,9 @@ ASSERT_TRUE(dictionary); // Name and keyword should be derived from host. - ASSERT_EQ(dictionary->FindInt(DefaultSearchManager::kCreatedByPolicy), - static_cast<int>( - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider)); + ASSERT_EQ( + dictionary->FindInt(DefaultSearchManager::kPolicyOrigin), + static_cast<int>(TemplateURLData::PolicyOrigin::kDefaultSearchProvider)); const std::string* value = nullptr; ASSERT_TRUE(value = dictionary->FindString(DefaultSearchManager::kURL)); EXPECT_EQ(kSearchURL, *value); @@ -359,9 +359,9 @@ const base::Value::Dict* dictionary = temp->GetIfDict(); ASSERT_TRUE(dictionary); - ASSERT_EQ(dictionary->FindInt(DefaultSearchManager::kCreatedByPolicy), - static_cast<int>( - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider)); + ASSERT_EQ( + dictionary->FindInt(DefaultSearchManager::kPolicyOrigin), + static_cast<int>(TemplateURLData::PolicyOrigin::kDefaultSearchProvider)); const std::string* value = nullptr; ASSERT_TRUE(value = dictionary->FindString(DefaultSearchManager::kURL)); EXPECT_EQ(kFileSearchURL, *value);
diff --git a/components/search_engines/enterprise/enterprise_search_manager_unittest.cc b/components/search_engines/enterprise/enterprise_search_manager_unittest.cc index eb01573..a3da45f 100644 --- a/components/search_engines/enterprise/enterprise_search_manager_unittest.cc +++ b/components/search_engines/enterprise/enterprise_search_manager_unittest.cc
@@ -46,17 +46,16 @@ base::Value::Dict GenerateSiteSearchPrefEntry(const std::string& keyword) { base::Value::Dict entry = GenerateSearchPrefEntry(keyword, /*featured=*/false); - entry.Set(DefaultSearchManager::kCreatedByPolicy, - static_cast<int>(TemplateURLData::CreatedByPolicy::kSiteSearch)); + entry.Set(DefaultSearchManager::kPolicyOrigin, + static_cast<int>(TemplateURLData::PolicyOrigin::kSiteSearch)); return entry; } base::Value::Dict GenerateSearchAggregatorPrefEntry(const std::string& keyword, bool featured) { base::Value::Dict entry = GenerateSearchPrefEntry(keyword, featured); - entry.Set( - DefaultSearchManager::kCreatedByPolicy, - static_cast<int>(TemplateURLData::CreatedByPolicy::kSearchAggregator)); + entry.Set(DefaultSearchManager::kPolicyOrigin, + static_cast<int>(TemplateURLData::PolicyOrigin::kSearchAggregator)); entry.Set(DefaultSearchManager::kSuggestionsURL, std::string("https://") + keyword + ".com/suggest"); return entry;
diff --git a/components/search_engines/enterprise/search_aggregator_policy_handler.cc b/components/search_engines/enterprise/search_aggregator_policy_handler.cc index 5f540be0..47b15186 100644 --- a/components/search_engines/enterprise/search_aggregator_policy_handler.cc +++ b/components/search_engines/enterprise/search_aggregator_policy_handler.cc
@@ -79,9 +79,8 @@ dict.Set(DefaultSearchManager::kFaviconURL, *icon_url); } - dict.Set( - DefaultSearchManager::kCreatedByPolicy, - static_cast<int>(TemplateURLData::CreatedByPolicy::kSearchAggregator)); + dict.Set(DefaultSearchManager::kPolicyOrigin, + static_cast<int>(TemplateURLData::PolicyOrigin::kSearchAggregator)); dict.Set(DefaultSearchManager::kEnforcedByPolicy, false); dict.Set(DefaultSearchManager::kFeaturedByPolicy, featured); dict.Set(DefaultSearchManager::kIsActive,
diff --git a/components/search_engines/enterprise/search_aggregator_policy_handler_unittest.cc b/components/search_engines/enterprise/search_aggregator_policy_handler_unittest.cc index 27fc016..8a98b73 100644 --- a/components/search_engines/enterprise/search_aggregator_policy_handler_unittest.cc +++ b/components/search_engines/enterprise/search_aggregator_policy_handler_unittest.cc
@@ -231,9 +231,9 @@ test_case.icon_url ? std::string(test_case.icon_url) : std::string()), FieldNotSet(DefaultSearchManager::kFaviconURL)), - HasIntegerField(DefaultSearchManager::kCreatedByPolicy, - static_cast<int>( - TemplateURLData::CreatedByPolicy::kSearchAggregator)), + HasIntegerField( + DefaultSearchManager::kPolicyOrigin, + static_cast<int>(TemplateURLData::PolicyOrigin::kSearchAggregator)), HasBooleanField(DefaultSearchManager::kEnforcedByPolicy, false), HasBooleanField(DefaultSearchManager::kFeaturedByPolicy, featured), HasIntegerField(DefaultSearchManager::kIsActive,
diff --git a/components/search_engines/enterprise/site_search_policy_handler.cc b/components/search_engines/enterprise/site_search_policy_handler.cc index 081073e..0e3d477 100644 --- a/components/search_engines/enterprise/site_search_policy_handler.cc +++ b/components/search_engines/enterprise/site_search_policy_handler.cc
@@ -53,8 +53,8 @@ dict.Set(DefaultSearchManager::kFeaturedByPolicy, featured); - dict.Set(DefaultSearchManager::kCreatedByPolicy, - static_cast<int>(TemplateURLData::CreatedByPolicy::kSiteSearch)); + dict.Set(DefaultSearchManager::kPolicyOrigin, + static_cast<int>(TemplateURLData::PolicyOrigin::kSiteSearch)); dict.Set(DefaultSearchManager::kEnforcedByPolicy, false); dict.Set(DefaultSearchManager::kIsActive, static_cast<int>(TemplateURLData::ActiveStatus::kTrue));
diff --git a/components/search_engines/enterprise/site_search_policy_handler_unittest.cc b/components/search_engines/enterprise/site_search_policy_handler_unittest.cc index 09410d1..11f0f94 100644 --- a/components/search_engines/enterprise/site_search_policy_handler_unittest.cc +++ b/components/search_engines/enterprise/site_search_policy_handler_unittest.cc
@@ -327,8 +327,8 @@ HasStringField(DefaultSearchManager::kURL, std::string(test_case.url)), HasBooleanField(DefaultSearchManager::kFeaturedByPolicy, featured), HasIntegerField( - DefaultSearchManager::kCreatedByPolicy, - static_cast<int>(TemplateURLData::CreatedByPolicy::kSiteSearch)), + DefaultSearchManager::kPolicyOrigin, + static_cast<int>(TemplateURLData::PolicyOrigin::kSiteSearch)), HasBooleanField(DefaultSearchManager::kEnforcedByPolicy, false), HasIntegerField(DefaultSearchManager::kIsActive, static_cast<int>(TemplateURLData::ActiveStatus::kTrue)),
diff --git a/components/search_engines/keyword_table.cc b/components/search_engines/keyword_table.cc index 66637d2..47d0d5d1 100644 --- a/components/search_engines/keyword_table.cc +++ b/components/search_engines/keyword_table.cc
@@ -576,8 +576,8 @@ data.id = s.ColumnInt64(0); data.date_created = s.ColumnTime(7); data.last_modified = s.ColumnTime(13); - data.created_by_policy = - static_cast<TemplateURLData::CreatedByPolicy>(s.ColumnInt(12)); + data.policy_origin = + static_cast<TemplateURLData::PolicyOrigin>(s.ColumnInt(12)); data.created_from_play_api = s.ColumnBool(22); data.usage_count = s.ColumnInt(8); data.prepopulate_id = s.ColumnInt(11); @@ -667,7 +667,7 @@ base::JoinString(data.input_encodings, ";")); s->BindString(starting_column + 9, data.suggestions_url); s->BindInt(starting_column + 10, data.prepopulate_id); - s->BindInt(starting_column + 11, static_cast<int>(data.created_by_policy)); + s->BindInt(starting_column + 11, static_cast<int>(data.policy_origin)); s->BindTime(starting_column + 12, data.last_modified); s->BindString(starting_column + 13, data.sync_guid); s->BindString(starting_column + 14, alternate_urls);
diff --git a/components/search_engines/keyword_table.h b/components/search_engines/keyword_table.h index 18da16b..6577f97 100644 --- a/components/search_engines/keyword_table.h +++ b/components/search_engines/keyword_table.h
@@ -54,7 +54,7 @@ // encodings, may be empty. // suggest_url // prepopulate_id See TemplateURLData::prepopulate_id. -// created_by_policy See TemplateURLData::created_by_policy. This was +// created_by_policy See TemplateURLData::policy_origin. This was // added in version 26. // last_modified See TemplateURLData::last_modified. This was added // in version 38.
diff --git a/components/search_engines/keyword_table_unittest.cc b/components/search_engines/keyword_table_unittest.cc index 24e4761..f650616 100644 --- a/components/search_engines/keyword_table_unittest.cc +++ b/components/search_engines/keyword_table_unittest.cc
@@ -82,8 +82,8 @@ keyword.date_created = base::Time::UnixEpoch(); keyword.last_modified = base::Time::UnixEpoch(); keyword.last_visited = base::Time::UnixEpoch(); - keyword.created_by_policy = - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider; + keyword.policy_origin = + TemplateURLData::PolicyOrigin::kDefaultSearchProvider; keyword.usage_count = 32; keyword.prepopulate_id = 10; keyword.sync_guid = "1234-5678-90AB-CDEF"; @@ -160,7 +160,7 @@ restored_keyword.last_modified.ToTimeT()); EXPECT_EQ(keyword.last_visited.ToTimeT(), restored_keyword.last_visited.ToTimeT()); - EXPECT_EQ(keyword.created_by_policy, restored_keyword.created_by_policy); + EXPECT_EQ(keyword.policy_origin, restored_keyword.policy_origin); EXPECT_EQ(keyword.created_from_play_api, restored_keyword.created_from_play_api); EXPECT_EQ(keyword.usage_count, restored_keyword.usage_count);
diff --git a/components/search_engines/search_engine_choice/search_engine_choice_service.cc b/components/search_engines/search_engine_choice/search_engine_choice_service.cc index bacadeb..6c238348 100644 --- a/components/search_engines/search_engine_choice/search_engine_choice_service.cc +++ b/components/search_engines/search_engine_choice/search_engine_choice_service.cc
@@ -84,8 +84,7 @@ bool IsSetOrBlockedByPolicy(const TemplateURL* default_search_engine) { return !default_search_engine || - default_search_engine->created_by_policy() == - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider; + default_search_engine->CreatedByDefaultSearchProviderPolicy(); } bool IsDefaultSearchProviderSetOrBlockedByPolicy(
diff --git a/components/search_engines/search_engine_choice/search_engine_choice_service_unittest.cc b/components/search_engines/search_engine_choice/search_engine_choice_service_unittest.cc index 5708b1e..cb2e9d3 100644 --- a/components/search_engines/search_engine_choice/search_engine_choice_service_unittest.cc +++ b/components/search_engines/search_engine_choice/search_engine_choice_service_unittest.cc
@@ -373,9 +373,9 @@ TemplateURLData data_from_policies; data_from_policies.SetURL("test"); base::Value::Dict dict = TemplateURLDataToDictionary(data_from_policies); - dict.Set(DefaultSearchManager::kCreatedByPolicy, - static_cast<int>( - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider)); + dict.Set( + DefaultSearchManager::kPolicyOrigin, + static_cast<int>(TemplateURLData::PolicyOrigin::kDefaultSearchProvider)); pref_service()->SetManagedPref( DefaultSearchManager::kDefaultSearchProviderDataPrefName, std::move(dict));
diff --git a/components/search_engines/search_host_to_urls_map_unittest.cc b/components/search_engines/search_host_to_urls_map_unittest.cc index 796d420..9821ba3b 100644 --- a/components/search_engines/search_host_to_urls_map_unittest.cc +++ b/components/search_engines/search_host_to_urls_map_unittest.cc
@@ -83,8 +83,7 @@ TemplateURLData data; data.SetURL("http://" + host_ + "/path1"); // Make the new TemplateURL "better" by having it created by policy. - data.created_by_policy = - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider; + data.policy_origin = TemplateURLData::PolicyOrigin::kDefaultSearchProvider; TemplateURL new_t_url(data); provider_map_->Add(&new_t_url, SearchTermsData());
diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc index 99077fa4..9ab21cc 100644 --- a/components/search_engines/template_url.cc +++ b/components/search_engines/template_url.cc
@@ -221,12 +221,8 @@ // the `SiteSearchSettings` or `EnterpriseSearchAggregatorSettings` policy, // `other_engine` should have been created by something else, but not via // policy. - CHECK(policy_engine->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSiteSearch || - policy_engine->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSearchAggregator); - CHECK_EQ(other_engine->created_by_policy(), - TemplateURLData::CreatedByPolicy::kNoPolicy); + CHECK(policy_engine->CreatedByNonDefaultSearchProviderPolicy()); + CHECK(!other_engine->CreatedByPolicy()); const std::u16string& keyword = policy_engine->keyword(); // Prefer `policy_engine` if the `keyword` starts with the "@" symbol. @@ -1645,26 +1641,16 @@ const TemplateURL* other) const { DCHECK(other); - auto by_policy = [](const TemplateURL* turl) { - return turl->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSiteSearch || - turl->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSearchAggregator; - }; - - auto no_policy = [](const TemplateURL* turl) { - return turl->created_by_policy() == - TemplateURLData::CreatedByPolicy::kNoPolicy; - }; - // Site search and Enterprise Search Aggregator engines set by enterprise // policy have different priority over existing search engines because we // don't want to break current workflows for power users. - if (by_policy(this) && no_policy(other)) { + if (CreatedByNonDefaultSearchProviderPolicy() && !other->CreatedByPolicy()) { return IsPolicySearchEngineBetterThanNonPolicyEngine(this, other); - } else if (no_policy(this) && by_policy(other)) { + } else if (!CreatedByPolicy() && + other->CreatedByNonDefaultSearchProviderPolicy()) { return !IsPolicySearchEngineBetterThanNonPolicyEngine(other, this); - } else if (by_policy(this) && by_policy(other)) { + } else if (CreatedByNonDefaultSearchProviderPolicy() && + other->CreatedByNonDefaultSearchProviderPolicy()) { // If both engines are created by the `SiteSearchSettings` or // `EnterpriseSearchAggregatorSettings` policy, prefer the one that is // featured. Otherwise, fallback to the comparison based on the signals @@ -1680,8 +1666,7 @@ return std::make_tuple( // Policy-created engines always win over non-policy created engines. // At this point, managed search engine should be created by DSP policy. - engine->created_by_policy() == - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider, + engine->CreatedByDefaultSearchProviderPolicy(), // Policy-enforced engines always win over policy-recommended engines. engine->enforced_by_policy(), // The integral value of the type enum is used to sort next. @@ -2007,6 +1992,18 @@ TemplateURLRef::SearchTermsArgs(), search_terms_data, nullptr)); } +bool TemplateURL::CreatedByPolicy() const { + return data().CreatedByPolicy(); +} + +bool TemplateURL::CreatedByDefaultSearchProviderPolicy() const { + return data().CreatedByDefaultSearchProviderPolicy(); +} + +bool TemplateURL::CreatedByNonDefaultSearchProviderPolicy() const { + return data().CreatedByNonDefaultSearchProviderPolicy(); +} + RegulatoryExtensionType TemplateURL::GetRegulatoryExtensionType() const { if (data().created_from_play_api) { return RegulatoryExtensionType::kAndroidEEA;
diff --git a/components/search_engines/template_url.h b/components/search_engines/template_url.h index 0ea3f24..3ef0938 100644 --- a/components/search_engines/template_url.h +++ b/components/search_engines/template_url.h
@@ -805,8 +805,8 @@ base::Time last_modified() const { return data().last_modified; } base::Time last_visited() const { return data().last_visited; } - TemplateURLData::CreatedByPolicy created_by_policy() const { - return data().created_by_policy; + TemplateURLData::PolicyOrigin policy_origin() const { + return data().policy_origin; } bool enforced_by_policy() const { return data().enforced_by_policy; } bool created_from_play_api() const { return data().created_from_play_api; } @@ -994,6 +994,15 @@ const TemplateURLData::RegulatoryExtension* GetRegulatoryExtension( RegulatoryExtensionType type) const; + // Returns whether this search engine was created by an Enterprise policy. + bool CreatedByPolicy() const; + // Returns whether this search engine was created by the Default Search + // Provider Enterprise policy. + bool CreatedByDefaultSearchProviderPolicy() const; + // Returns whether this search engine was created by an Enterprise policy that + // doesn't define the Default Search Provider. + bool CreatedByNonDefaultSearchProviderPolicy() const; + void SetURL(const std::string& url); void SetPrepopulateId(int id);
diff --git a/components/search_engines/template_url_data.cc b/components/search_engines/template_url_data.cc index dd207a0f..b762ee02 100644 --- a/components/search_engines/template_url_data.cc +++ b/components/search_engines/template_url_data.cc
@@ -52,7 +52,7 @@ id(0), date_created(base::Time::Now()), last_modified(base::Time::Now()), - created_by_policy(CreatedByPolicy::kNoPolicy), + policy_origin(PolicyOrigin::kNoPolicy), enforced_by_policy(false), created_from_play_api(false), usage_count(0), @@ -115,7 +115,7 @@ favicon_url(favicon_url), safe_for_autoreplace(true), id(0), - created_by_policy(CreatedByPolicy::kNoPolicy), + policy_origin(PolicyOrigin::kNoPolicy), enforced_by_policy(false), created_from_play_api(false), usage_count(0), @@ -216,3 +216,15 @@ return res; } + +bool TemplateURLData::CreatedByPolicy() const { + return policy_origin != PolicyOrigin::kNoPolicy; +} + +bool TemplateURLData::CreatedByDefaultSearchProviderPolicy() const { + return policy_origin == PolicyOrigin::kDefaultSearchProvider; +} + +bool TemplateURLData::CreatedByNonDefaultSearchProviderPolicy() const { + return CreatedByPolicy() && !CreatedByDefaultSearchProviderPolicy(); +}
diff --git a/components/search_engines/template_url_data.h b/components/search_engines/template_url_data.h index 1acffdfc..07a69b1 100644 --- a/components/search_engines/template_url_data.h +++ b/components/search_engines/template_url_data.h
@@ -21,7 +21,7 @@ // users to do SSA-style usage of TemplateURL: construct a TemplateURLData with // whatever fields are desired, then create an immutable TemplateURL from it. struct TemplateURLData { - enum class CreatedByPolicy { + enum class PolicyOrigin { kNoPolicy = 0, kDefaultSearchProvider = 1, kSiteSearch = 2, @@ -97,6 +97,15 @@ // See base/trace_event/memory_usage_estimator.h for more info. size_t EstimateMemoryUsage() const; + // Returns whether this search engine was created by an Enterprise policy. + bool CreatedByPolicy() const; + // Returns whether this search engine was created by the Default Search + // Provider Enterprise policy. + bool CreatedByDefaultSearchProviderPolicy() const; + // Returns whether this search engine was created by an Enterprise policy that + // doesn't define the Default Search Provider. + bool CreatedByNonDefaultSearchProviderPolicy() const; + // Optional additional raw URLs. std::string suggestions_url; std::string image_url; @@ -180,7 +189,7 @@ // True if this TemplateURL was automatically created by the administrator via // group policy. - CreatedByPolicy created_by_policy; + PolicyOrigin policy_origin; // True if this TemplateURL is forced to be the default search engine via // policy. This prevents the user from setting another search engine as
diff --git a/components/search_engines/template_url_data_util.cc b/components/search_engines/template_url_data_util.cc index 18364f4..127bfc5 100644 --- a/components/search_engines/template_url_data_util.cc +++ b/components/search_engines/template_url_data_util.cc
@@ -214,9 +214,9 @@ } } - result->created_by_policy = static_cast<TemplateURLData::CreatedByPolicy>( - dict.FindInt(DefaultSearchManager::kCreatedByPolicy) - .value_or(static_cast<int>(result->created_by_policy))); + result->policy_origin = static_cast<TemplateURLData::PolicyOrigin>( + dict.FindInt(DefaultSearchManager::kPolicyOrigin) + .value_or(static_cast<int>(result->policy_origin))); result->created_from_play_api = dict.FindBool(DefaultSearchManager::kCreatedFromPlayAPI) .value_or(result->created_from_play_api); @@ -306,8 +306,8 @@ encodings.Append(input_encoding); url_dict.Set(DefaultSearchManager::kInputEncodings, std::move(encodings)); - url_dict.Set(DefaultSearchManager::kCreatedByPolicy, - static_cast<int>(data.created_by_policy)); + url_dict.Set(DefaultSearchManager::kPolicyOrigin, + static_cast<int>(data.policy_origin)); url_dict.Set(DefaultSearchManager::kCreatedFromPlayAPI, data.created_from_play_api); url_dict.Set(DefaultSearchManager::kFeaturedByPolicy,
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc index 0051a9a46..4851820 100644 --- a/components/search_engines/template_url_service.cc +++ b/components/search_engines/template_url_service.cc
@@ -497,8 +497,7 @@ bool TemplateURLService::IsPrepopulatedOrDefaultProviderByPolicy( const TemplateURL* t_url) const { return (t_url->prepopulate_id() > 0 || - t_url->created_by_policy() == - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider || + t_url->CreatedByDefaultSearchProviderPolicy() || t_url->created_from_play_api()) && t_url->SupportsReplacement(search_terms_data()); } @@ -513,20 +512,19 @@ } bool TemplateURLService::HiddenFromLists(const TemplateURL* t_url) const { - switch (t_url->created_by_policy()) { - case TemplateURLData::CreatedByPolicy::kNoPolicy: + switch (t_url->policy_origin()) { + case TemplateURLData::PolicyOrigin::kNoPolicy: // Hide if the preferred search engine for the keyword is created by // policy. The call to `GetTemplateURLForKeyword` already ensure // prioritization of search engines, so there is no need to replicate the // logic here. - return GetTemplateURLForKeyword(t_url->keyword())->created_by_policy() != - TemplateURLData::CreatedByPolicy::kNoPolicy; + return GetTemplateURLForKeyword(t_url->keyword())->CreatedByPolicy(); - case TemplateURLData::CreatedByPolicy::kDefaultSearchProvider: + case TemplateURLData::PolicyOrigin::kDefaultSearchProvider: return false; - case TemplateURLData::CreatedByPolicy::kSiteSearch: - case TemplateURLData::CreatedByPolicy::kSearchAggregator: { + case TemplateURLData::PolicyOrigin::kSiteSearch: + case TemplateURLData::PolicyOrigin::kSearchAggregator: { // Always show featured Enterprise site search engines. if (t_url->featured_by_policy()) { return false; @@ -548,10 +546,7 @@ const TemplateURL* t_url_with_at = GetTemplateURLForKeyword(u"@" + t_url->keyword()); return t_url_with_at && - (t_url_with_at->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSiteSearch || - t_url_with_at->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSearchAggregator) && + t_url_with_at->CreatedByNonDefaultSearchProviderPolicy() && t_url_with_at->featured_by_policy(); } } @@ -563,10 +558,7 @@ // Check 'template_url` is a featured site or featured aggregator search. if (!template_url->featured_by_policy() || - (template_url->created_by_policy() != - TemplateURLData::CreatedByPolicy::kSiteSearch && - template_url->created_by_policy() != - TemplateURLData::CreatedByPolicy::kSearchAggregator)) { + !template_url->CreatedByNonDefaultSearchProviderPolicy()) { return false; } @@ -578,10 +570,7 @@ GetTemplateURLForKeyword(std::u16string(keyword, 1)); CHECK(turl_without_at); - return (turl_without_at->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSiteSearch || - turl_without_at->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSearchAggregator) && + return turl_without_at->CreatedByNonDefaultSearchProviderPolicy() && !turl_without_at->featured_by_policy(); } @@ -863,8 +852,7 @@ TemplateURLService::GetFeaturedEnterpriseSearchEngines() const { TemplateURLVector result; for (const auto& turl : template_urls_) { - if (turl->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSiteSearch && + if (turl->policy_origin() == TemplateURLData::PolicyOrigin::kSiteSearch && turl->featured_by_policy()) { result.push_back(turl.get()); } @@ -1511,8 +1499,7 @@ default_search_provider_->GetEngineType(search_terms_data()); base::UmaHistogramEnumeration("Search.DefaultSearchProviderType2", engine_type, SEARCH_ENGINE_MAX); - if (default_search_provider_->created_by_policy() == - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider) { + if (default_search_provider_->CreatedByDefaultSearchProviderPolicy()) { base::UmaHistogramEnumeration( "Search.DefaultSearchProviderType2.SetByEnterprisePolicy", engine_type, SEARCH_ENGINE_MAX); @@ -1601,8 +1588,7 @@ syncer::SyncDataList current_data; for (const auto& turl : template_urls_) { // We don't sync keywords managed by policy. - if (turl->created_by_policy() != - TemplateURLData::CreatedByPolicy::kNoPolicy) { + if (turl->CreatedByPolicy()) { continue; } // We don't sync extension-controlled search engines. @@ -1854,8 +1840,7 @@ } // Avoid syncing keywords managed by policy. - if (turl->created_by_policy() != - TemplateURLData::CreatedByPolicy::kNoPolicy) { + if (turl->CreatedByPolicy()) { return; } @@ -2181,10 +2166,7 @@ } } - if (template_url->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSiteSearch || - template_url->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSearchAggregator) { + if (template_url->CreatedByNonDefaultSearchProviderPolicy()) { enterprise_search_keyword_to_turl_.erase(keyword); } @@ -2206,10 +2188,7 @@ guid_to_turl_[template_url->sync_guid()] = template_url; } - if (template_url->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSiteSearch || - template_url->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSearchAggregator) { + if (template_url->CreatedByNonDefaultSearchProviderPolicy()) { enterprise_search_keyword_to_turl_[keyword] = template_url; } @@ -2735,8 +2714,7 @@ for (auto i = template_urls->begin(); i != template_urls->end();) { TemplateURL* template_url = i->get(); - if (template_url->created_by_policy() == - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider) { + if (template_url->CreatedByDefaultSearchProviderPolicy()) { if (default_from_prefs && TemplateURL::MatchesData(template_url, default_from_prefs, search_terms_data())) { @@ -2779,8 +2757,8 @@ if (new_data.sync_guid.empty()) { new_data.GenerateSyncGUID(); } - new_data.created_by_policy = - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider; + new_data.policy_origin = + TemplateURLData::PolicyOrigin::kDefaultSearchProvider; new_data.enforced_by_policy = is_mandatory; new_data.safe_for_autoreplace = false; new_data.is_active = TemplateURLData::ActiveStatus::kTrue; @@ -2829,8 +2807,7 @@ // Play API created engines, as those also seem local-only and should not // be merged into Synced engines. crbug.com/1414224. if (local_turl->type() == TemplateURL::NORMAL && - local_turl->created_by_policy() == - TemplateURLData::CreatedByPolicy::kNoPolicy && + !local_turl->CreatedByPolicy() && !local_turl->created_from_play_api()) { local_duplicates.push_back(local_turl); } @@ -3071,10 +3048,7 @@ // Do not replace existing search engines if `candidate` was created by the // policy. - if (candidate->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSiteSearch || - candidate->created_by_policy() == - TemplateURLData::CreatedByPolicy::kSearchAggregator) { + if (candidate->CreatedByNonDefaultSearchProviderPolicy()) { return false; } @@ -3192,8 +3166,7 @@ bool conflicts_with_active = std::any_of(match_range.first, match_range.second, [](const KeywordToTURL::value_type& entry) { - return entry.second->created_by_policy() == - TemplateURLData::CreatedByPolicy::kNoPolicy && + return !entry.second->CreatedByPolicy() && !entry.second->safe_for_autoreplace(); }); SearchPolicyConflictType type =
diff --git a/components/search_engines/template_url_service_unittest.cc b/components/search_engines/template_url_service_unittest.cc index 1e19baee..846610c 100644 --- a/components/search_engines/template_url_service_unittest.cc +++ b/components/search_engines/template_url_service_unittest.cc
@@ -349,8 +349,7 @@ const TemplateURL* policy_engine = template_url_service().GetDefaultSearchProvider(); ASSERT_EQ(policy_engine->keyword(), policy_engine_data.keyword()); - ASSERT_EQ(policy_engine->created_by_policy(), - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider); + ASSERT_TRUE(policy_engine->CreatedByDefaultSearchProviderPolicy()); const auto new_play_engine_data = CreatePlayAPITemplateURLData(kNewPlayEngineKeyword); @@ -383,8 +382,7 @@ const TemplateURL* policy_engine = template_url_service().GetDefaultSearchProvider(); ASSERT_EQ(policy_engine->keyword(), policy_engine_data.keyword()); - ASSERT_EQ(policy_engine->created_by_policy(), - TemplateURLData::CreatedByPolicy::kDefaultSearchProvider); + ASSERT_TRUE(policy_engine->CreatedByDefaultSearchProviderPolicy()); // Add the Play API engine using the same keyword as the policy engine. const auto new_play_engine_data =
diff --git a/components/search_engines/template_url_unittest.cc b/components/search_engines/template_url_unittest.cc index 54fcad05..754fa54 100644 --- a/components/search_engines/template_url_unittest.cc +++ b/components/search_engines/template_url_unittest.cc
@@ -36,7 +36,7 @@ #include "ui/base/device_form_factor.h" using base::ASCIIToUTF16; -using CreatedByPolicy = TemplateURLData::CreatedByPolicy; +using PolicyOrigin = TemplateURLData::PolicyOrigin; using RequestSource = SearchTermsData::RequestSource; namespace { @@ -3119,7 +3119,7 @@ struct IsBetterThanEngineTestEngine { std::u16string keyword; - CreatedByPolicy created_by_policy = CreatedByPolicy::kNoPolicy; + PolicyOrigin policy_origin = PolicyOrigin::kNoPolicy; bool enforced_by_policy = false; bool featured_by_policy = false; bool safe_for_autoreplace = false; @@ -3133,7 +3133,7 @@ template_url_data.SetShortName(engine.keyword + u"_name"); template_url_data.SetURL("https://" + base::UTF16ToUTF8(engine.keyword) + ".com/q={searchTerms}"); - template_url_data.created_by_policy = engine.created_by_policy; + template_url_data.policy_origin = engine.policy_origin; template_url_data.enforced_by_policy = engine.enforced_by_policy; template_url_data.featured_by_policy = engine.featured_by_policy; template_url_data.safe_for_autoreplace = engine.safe_for_autoreplace; @@ -3151,7 +3151,7 @@ .better_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kSiteSearch, + .policy_origin = PolicyOrigin::kSiteSearch, }, .worse_engine = { @@ -3169,7 +3169,7 @@ .worse_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kSiteSearch, + .policy_origin = PolicyOrigin::kSiteSearch, }, }, { @@ -3177,7 +3177,7 @@ .better_engine = { .keyword = u"@kw", - .created_by_policy = CreatedByPolicy::kSiteSearch, + .policy_origin = PolicyOrigin::kSiteSearch, .featured_by_policy = true, }, .worse_engine = @@ -3192,13 +3192,13 @@ .better_engine = { .keyword = u"@kw", - .created_by_policy = CreatedByPolicy::kSiteSearch, + .policy_origin = PolicyOrigin::kSiteSearch, .featured_by_policy = true, }, .worse_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kSiteSearch, + .policy_origin = PolicyOrigin::kSiteSearch, }, }, { @@ -3206,13 +3206,13 @@ .better_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kDefaultSearchProvider, + .policy_origin = PolicyOrigin::kDefaultSearchProvider, .enforced_by_policy = true, }, .worse_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kNoPolicy, + .policy_origin = PolicyOrigin::kNoPolicy, .safe_for_autoreplace = false, }, }, @@ -3221,13 +3221,13 @@ .better_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kDefaultSearchProvider, + .policy_origin = PolicyOrigin::kDefaultSearchProvider, .enforced_by_policy = true, }, .worse_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kDefaultSearchProvider, + .policy_origin = PolicyOrigin::kDefaultSearchProvider, }, }, { @@ -3235,13 +3235,13 @@ .better_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kSiteSearch, + .policy_origin = PolicyOrigin::kSiteSearch, .last_modified = base::Time::FromTimeT(2000), }, .worse_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kSiteSearch, + .policy_origin = PolicyOrigin::kSiteSearch, .last_modified = base::Time::FromTimeT(1000), }, }, @@ -3250,7 +3250,7 @@ .better_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kSearchAggregator, + .policy_origin = PolicyOrigin::kSearchAggregator, }, .worse_engine = { @@ -3268,7 +3268,7 @@ .worse_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kSearchAggregator, + .policy_origin = PolicyOrigin::kSearchAggregator, }, }, @@ -3277,7 +3277,7 @@ .better_engine = { .keyword = u"@kw", - .created_by_policy = CreatedByPolicy::kSearchAggregator, + .policy_origin = PolicyOrigin::kSearchAggregator, .featured_by_policy = true, }, .worse_engine = @@ -3292,13 +3292,13 @@ .better_engine = { .keyword = u"@kw", - .created_by_policy = CreatedByPolicy::kSearchAggregator, + .policy_origin = PolicyOrigin::kSearchAggregator, .featured_by_policy = true, }, .worse_engine = { .keyword = u"kw", - .created_by_policy = CreatedByPolicy::kSearchAggregator, + .policy_origin = PolicyOrigin::kSearchAggregator, }, }, };
diff --git a/components/sync/base/features.cc b/components/sync/base/features.cc index 3ae0449..187689cc 100644 --- a/components/sync/base/features.cc +++ b/components/sync/base/features.cc
@@ -169,6 +169,12 @@ "SyncPasswordCleanUpAccidentalBatchDeletions", base::FEATURE_DISABLED_BY_DEFAULT); +#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) +BASE_FEATURE(kMigrateAccountPrefs, + "MigrateAccountPrefs", + base::FEATURE_DISABLED_BY_DEFAULT); +#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) + BASE_FEATURE(kSeparateLocalAndAccountThemes, "SeparateLocalAndAccountThemes", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/components/sync/base/features.h b/components/sync/base/features.h index 5bfa181..f64152f 100644 --- a/components/sync/base/features.h +++ b/components/sync/base/features.h
@@ -161,6 +161,12 @@ // sync metadata isn't available (i.e. initial sync never completed). BASE_DECLARE_FEATURE(kSyncAlwaysForceImmediateStartIfTransportDataMissing); +#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) +// If enabled, holds the account preference values under a dictionary in the +// main preferences file. +BASE_DECLARE_FEATURE(kMigrateAccountPrefs); +#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) + // If enabled, distinguishes between local and account themes. BASE_DECLARE_FEATURE(kSeparateLocalAndAccountThemes);
diff --git a/components/tracing/BUILD.gn b/components/tracing/BUILD.gn index 1de469f..e4eb125 100644 --- a/components/tracing/BUILD.gn +++ b/components/tracing/BUILD.gn
@@ -45,6 +45,8 @@ if (is_win) { sources += [ + "common/active_processes_win.cc", + "common/active_processes_win.h", "common/etw_consumer_win.cc", "common/etw_consumer_win.h", "common/etw_export_win.cc", @@ -121,8 +123,14 @@ data = [ "$root_gen_dir/third_party/perfetto/protos/perfetto/config/chrome/scenario_config.descriptor" ] if (is_win) { - sources += [ "common/etw_consumer_win_unittest.cc" ] - deps += [ "//third_party/perfetto:libperfetto" ] + sources += [ + "common/active_processes_win_unittest.cc", + "common/etw_consumer_win_unittest.cc", + ] + deps += [ + "//base/version_info:generate_version_info", + "//third_party/perfetto:libperfetto", + ] } deps += [ ":background_tracing_utils",
diff --git a/components/tracing/common/active_processes_win.cc b/components/tracing/common/active_processes_win.cc new file mode 100644 index 0000000..4e4c255 --- /dev/null +++ b/components/tracing/common/active_processes_win.cc
@@ -0,0 +1,300 @@ +// 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/tracing/common/active_processes_win.h" + +#include "base/base_paths.h" +#include "base/command_line.h" +#include "base/path_service.h" +#include "base/ranges/algorithm.h" +#include "base/version.h" + +namespace tracing { + +namespace { + +// Returns the directory immediately above the current executable's directory if +// the directory of the current executable is of the form "W.X.Y.Z"; otherwise, +// returns the current executable's directory. +base::FilePath DetermineApplicationDirectory() { + base::FilePath dir_path = base::PathService::CheckedGet(base::DIR_EXE); + if (base::Version(dir_path.BaseName().MaybeAsASCII()).IsValid()) { + // This is likely a production install, where the elevated tracing service + // is installed in the version directory. + return dir_path.DirName(); + } + // Otherwise, this is likely a developer, where the elevated tracing service + // is in the build output directory next to the browser. + return dir_path; +} + +// Returns true if `one` and `two` are equal or if `one` is a parent of `two`. +bool IsSameOrParent(const base::FilePath& one, const base::FilePath& two) { + // Use a simple string comparison here, as the expectation is that the paths + // will be formatted the same if they truly are the same since they share a + // common origin in that case. There are cases where this will return a false + // negative, but for now this is acceptable since it will lead to under- + // rather than over-reporting. + return one == two || one.IsParent(two); +} + +} // namespace + +ActiveProcesses::Process::Process(uint32_t pid, + uint32_t parent_pid, + uint32_t session_id, + std::optional<base::win::Sid> sid, + std::string image_file_name, + std::wstring command_line) + : pid(pid), + parent_pid(parent_pid), + session_id(session_id), + sid(std::move(sid)), + image_file_name(std::move(image_file_name)), + command_line(std::move(command_line)), + category(Category::kOther) {} + +ActiveProcesses::Process::~Process() = default; + +ActiveProcesses::ActiveProcesses(base::ProcessId client_pid) + : client_pid_(client_pid), + application_dir_(DetermineApplicationDirectory()) { + DETACH_FROM_SEQUENCE(sequence_checker_); +} + +ActiveProcesses::~ActiveProcesses() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +void ActiveProcesses::AddProcess(uint32_t pid, + uint32_t parent_pid, + uint32_t session_id, + std::optional<base::win::Sid> sid, + std::string image_file_name, + std::wstring command_line) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + enum { + kNonClientAdded, + kClientAdded, + kDuplicateClientAdded, + } addition = kNonClientAdded; + if (pid != client_pid_) { + addition = kNonClientAdded; + } else if (!client_process_) { + addition = kClientAdded; + } else { + // A second process with the same pid as the client is not possible since + // the tracing service self-terminates when the client process terminates. + // Conservatively consider this to be an "other" process and forget about + // the client. + addition = kDuplicateClientAdded; + OnClientRemoved(client_process_.get()); + } + + auto [iter, inserted] = processes_.try_emplace( + pid, pid, parent_pid, session_id, std::move(sid), + std::move(image_file_name), std::move(command_line)); + auto& process = iter->second; + if (!inserted) { + // Duplicate pid. The event for the removal of this pid must have been lost. + // Forget about the old process's threads before replacing it. + base::ranges::for_each(process.threads, + [this](uint32_t tid) { threads_.erase(tid); }); + process.threads.clear(); + // Move the new process's properties into the instance. + process.parent_pid = parent_pid; + process.session_id = session_id; + process.sid = std::move(sid); + process.image_file_name = std::move(image_file_name); + process.command_line = std::move(command_line); + } + + // Finally, set the process's category. + switch (addition) { + case kNonClientAdded: + process.category = DetermineCategory(process); + break; + case kClientAdded: + process.category = Category::kClient; // This is the client's process. + OnClientAdded(&process); + break; + case kDuplicateClientAdded: + process.category = Category::kOther; + break; + } +} + +void ActiveProcesses::RemoveProcess(uint32_t pid) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (pid == client_pid_ && client_process_) { + OnClientRemoved(client_process_.get()); + } + + if (auto iter = processes_.find(pid); iter != processes_.end()) { + // Forget about this process's threads if they haven't already been removed. + base::ranges::for_each(iter->second.threads, + [this](uint32_t tid) { threads_.erase(tid); }); + processes_.erase(iter); + } // else the event for the addition of this process must have been lost. +} + +void ActiveProcesses::AddThread(uint32_t pid, + uint32_t tid, + std::wstring thread_name) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + auto process_iter = processes_.find(pid); + if (process_iter == processes_.end()) { + // The event for the addition of this thread's process must have been lost. + // The reason for tracking threads is to map a tid to its process. Since it + // will not be possible to do so for this tid, skip adding it to `threads_`. + return; + } + auto [iter, inserted] = + threads_.try_emplace(tid, std::move(thread_name), &process_iter->second); + auto& [name, process_ptr] = iter->second; + if (!inserted) { + // The event for the removal of this tid must have been lost. + // Remove the thread from the previous process's collection. + process_ptr->threads.erase(tid); + // Associate this thread with its new name and process. + name = std::move(thread_name); + process_ptr = &process_iter->second; + } + + // Add this thread to its process's collection. + process_ptr->threads.insert(tid); +} + +void ActiveProcesses::SetThreadName(uint32_t pid, + uint32_t tid, + std::wstring thread_name) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + auto process_iter = processes_.find(pid); + if (process_iter == processes_.end()) { + // The event for the addition of this thread's process must have been lost. + return; + } + auto thread_iter = threads_.find(tid); + if (thread_iter == threads_.end()) { + // The event for the addition of this thread must have been lost. + return; + } + if (thread_iter->second.second.get() != &process_iter->second) { + // The pid and tid are both known, but don't relate. Aggressive id reuse + // and lost events make this possible. + return; + } + thread_iter->second.first = std::move(thread_name); +} + +void ActiveProcesses::RemoveThread(uint32_t pid, uint32_t tid) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + auto iter = threads_.find(tid); + if (iter == threads_.end()) { + // The event for the addition of this thread must have been lost. + return; + } + auto& process_ptr = iter->second.second; + if (process_ptr->pid != pid) { + // Events for the removal of this tid and its addition to a different pid + // must have been lost. Ignore this removal to avoid corrupting tracking for + // the other process + return; + } + process_ptr->threads.erase(tid); + threads_.erase(iter); +} + +ActiveProcesses::Category ActiveProcesses::GetThreadCategory( + uint32_t tid) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (auto iter = threads_.find(tid); iter != threads_.end()) { + return iter->second.second->category; + } + return Category::kOther; +} + +std::wstring_view ActiveProcesses::GetThreadName(uint32_t tid) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (auto iter = threads_.find(tid); iter != threads_.end()) { + return iter->second.first; + } + return {}; +} + +void ActiveProcesses::OnClientAdded(Process* client) { + client_process_ = client; + client_in_application_ = + IsSameOrParent(application_dir_, GetProgram(*client).DirName()); + + // Re-categorize all existing "other" processes to detect client processes. + base::ranges::for_each( + processes_, + [this](auto& process) { + if (process.category == Category::kOther) { + process.category = DetermineCategory(process); + } + }, + &PidProcessMap::value_type::second); +} + +void ActiveProcesses::OnClientRemoved(Process* client) { + client_process_ = nullptr; + client_in_application_ = false; + + // All previously-discovered client processes are now "other" processes. + base::ranges::for_each( + processes_, + [](auto& process) { + if (process.category == Category::kClient) { + process.category = Category::kOther; + } + }, + &PidProcessMap::value_type::second); +} + +ActiveProcesses::Category ActiveProcesses::DetermineCategory( + const Process& process) { + // The session id for Idle, System, Secure System, Registry, smss.exe, and + // MemCompression. + static constexpr uint32_t kSystemSession = 0xFFFFFFFF; + + if (process.session_id == kSystemSession) { + return Category::kSystem; // Windows kernel processes. + } + + if (!client_process_) { + return Category::kOther; // Not yet possible to associate with the client. + } + + const Process& client = *client_process_; + if (process.session_id != client.session_id) { + return Category::kOther; // Not running in the same session as the client. + } + + if (!process.sid.has_value() || process.sid != client.sid) { + return Category::kOther; // Not the same user. + } + + if (client_in_application_ && + IsSameOrParent(application_dir_, GetProgram(process).DirName())) { + return Category::kClient; // A program belonging to the client. + } + + return Category::kOther; +} + +// static +base::FilePath ActiveProcesses::GetProgram(const Process& process) { + return base::CommandLine::FromString(process.command_line).GetProgram(); +} + +} // namespace tracing
diff --git a/components/tracing/common/active_processes_win.h b/components/tracing/common/active_processes_win.h new file mode 100644 index 0000000..61803bd3 --- /dev/null +++ b/components/tracing/common/active_processes_win.h
@@ -0,0 +1,152 @@ +// 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_TRACING_COMMON_ACTIVE_PROCESSES_WIN_H_ +#define COMPONENTS_TRACING_COMMON_ACTIVE_PROCESSES_WIN_H_ + +#include <stdint.h> + +#include <optional> +#include <string> +#include <string_view> +#include <unordered_map> +#include <unordered_set> +#include <utility> + +#include "base/files/file_path.h" +#include "base/memory/raw_ptr.h" +#include "base/process/process_handle.h" +#include "base/sequence_checker.h" +#include "base/win/sid.h" +#include "components/tracing/tracing_export.h" + +namespace tracing { + +// A helper that tracks active processes on the system and categorizes them, +// providing an efficient determination of a process's category given a thread +// id. An instance of this class is expected to be populated dynamically based +// on Process and Thread events sourced from the Windows system event provider +// via ETW. It provides accurate results to the extent possible, given that +// trace events may be lost. +class TRACING_EXPORT ActiveProcesses { + public: + // A process's category. Values of this type must be sequential and begin with + // zero, but are not persisted or transmitted. Values may be reordered, added, + // or removed. + enum class Category { + // A process that belongs to the tracing client. + kClient = 0, + // A process that belongs to the system. + kSystem = 1, + // Any process that doesn't meet the criteria above. + kOther = 2, + }; + + // Constructs an instance for a trace initiated on behalf of the process + // identified by `client_pid`. This and 1) any of its direct children of it + // with the same image filename and 2) any other program residing in the same + // directory tree will be categorized as belonging to the tracing client. + explicit ActiveProcesses(base::ProcessId client_pid); + ActiveProcesses(const ActiveProcesses&) = delete; + ActiveProcesses& operator=(const ActiveProcesses&) = delete; + ~ActiveProcesses(); + + // Adds a process to the collection of active processes. The process is + // categorized upon addition unless the client process has yet to be added. + // If `pid` matches `client_pid`, all previously-added processes are + // categorized. + void AddProcess(uint32_t pid, + uint32_t parent_pid, + uint32_t session_id, + std::optional<base::win::Sid> sid, + std::string image_file_name, + std::wstring command_line); + + // Removes a process and all of its threads from the collection. + void RemoveProcess(uint32_t pid); + + // Adds a process's thread to the collection. + void AddThread(uint32_t pid, uint32_t tid, std::wstring thread_name); + + // Sets the name of a thread in the collection. + void SetThreadName(uint32_t pid, uint32_t tid, std::wstring thread_name); + + // Remove's a process's thread from the collection, if it is present. + void RemoveThread(uint32_t pid, uint32_t tid); + + // Returns the category for the process to which the thread `tid` belongs. + // Returns kOther if `tid` is unknown. + Category GetThreadCategory(uint32_t tid) const; + + // Returns a thread's name, or an empty view if not found or unset. The + // returned view may become invalidated following any other operation on this + // instance. + std::wstring_view GetThreadName(uint32_t tid) const; + + private: + struct Process { + Process(uint32_t pid, + uint32_t parent_pid, + uint32_t session_id, + std::optional<base::win::Sid> sid, + std::string image_file_name, + std::wstring command_line); + ~Process(); + + uint32_t pid; + uint32_t parent_pid; + uint32_t session_id; + std::optional<base::win::Sid> sid; + std::string image_file_name; + std::wstring command_line; + Category category; + std::unordered_set<uint32_t> threads; + }; + + // Handles addition of the `Process` corresponding to the tracing client. All + // previously-added processes of type `kOther` are recategorized. + void OnClientAdded(Process* client); + + // Handles removal of the `Process` corresponding to the tracing client. All + // previously-added processes of type `kClient` are recategorized as + // `kOther`. + void OnClientRemoved(Process* client); + + // Compute and returns the category of `process`. + Category DetermineCategory(const Process& process); + + // Returns the first component of `process`'s `command_line. + static base::FilePath GetProgram(const Process& process); + + // The pid of the client process on behalf of which traces are collected. + const base::ProcessId client_pid_; + + // The path to the application directory of which the service is a part. In + // the case of Google Chrome, this is the path to the "Application" directory + // containing chrome.exe and the version directory. + const base::FilePath application_dir_; + + // True if the client appears to "belong to" the service, in the sense that it + // resides either in the same directory as the service or one directory above + // if the service is in a version directory. + bool client_in_application_ = false; + + // A mapping of a process's id (pid) to its `Process` struct. + using PidProcessMap = std::unordered_map<uint32_t, Process>; + PidProcessMap processes_; + + // A mapping of a thread's id (tid) to its name and corresponding process. + std::unordered_map<uint32_t, std::pair<std::wstring, raw_ptr<Process>>> + threads_; + + // The `Process` struct with pid `client_pid_`, or null if the process has + // not yet been added or has been removed. + raw_ptr<Process> client_process_ = nullptr; + + SEQUENCE_CHECKER(sequence_checker_); +}; + +} // namespace tracing + +#endif // COMPONENTS_TRACING_COMMON_ACTIVE_PROCESSES_WIN_H_
diff --git a/components/tracing/common/active_processes_win_unittest.cc b/components/tracing/common/active_processes_win_unittest.cc new file mode 100644 index 0000000..e675d758 --- /dev/null +++ b/components/tracing/common/active_processes_win_unittest.cc
@@ -0,0 +1,549 @@ +// 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/tracing/common/active_processes_win.h" + +#include <windows.h> + +#include <optional> + +#include "base/base_paths.h" +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/process/process.h" +#include "base/test/scoped_path_override.h" +#include "base/threading/platform_thread.h" +#include "base/version_info/version_info_values.h" +#include "base/win/access_token.h" +#include "base/win/sid.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace tracing { + +class ActiveProcessesTest : public testing::Test { + protected: + using PidAndTid = std::pair<base::ProcessId, base::PlatformThreadId>; + + // The pid and tid of the client. Named "base" because the offsets below are + // applied to compute distinct pids and tids for other processes. + static constexpr uint32_t kBasePid = 0x1000; + static constexpr uint32_t kBaseTid = 0x1000; + + // Offsets from the bases above for pids and tids for other processes. + static constexpr int kChildOffset = 100; + static constexpr int kUnrelatedOffset = 200; + static constexpr int kIndependentOffset = 300; + static constexpr int kSystemOffset = 400; + + // testing::Test: + void SetUp() override { + // Create a version directory %TMP%\random\W.X.Y.Z. + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + fake_dir_exe_ = + temp_dir_.GetPath().Append(FILE_PATH_LITERAL(PRODUCT_VERSION)); + ASSERT_TRUE(base::CreateDirectory(fake_dir_exe_)); + + // Pretend that it is the dir in which the current executable is running. + dir_exe_override_.emplace(base::DIR_EXE, fake_dir_exe_, + /*is_absolute=*/true, /*create=*/false); + + // Make a command line for a client residing in %TMP%\random. + base::CommandLine client_command_line( + temp_dir_.GetPath().AppendASCII(client_image_file_name_)); + client_command_line.AppendArgNative(L"arg1"); + client_command_line.AppendSwitchNative("switch1", L"value1"); + client_command_line.AppendSwitch("switch2"); + client_command_line.AppendArgNative(L"arg2"); + client_command_line_ = client_command_line.GetCommandLineString(); + + // Make a command line for an external client residing in %TMP%. + external_client_command_line_ = + base::CommandLine( + temp_dir_.GetPath().DirName().AppendASCII(client_image_file_name_)) + .GetCommandLineString(); + + // Now construct the instance to test. + active_processes_.emplace(kBasePid); + } + + ActiveProcesses& active_processes() { return *active_processes_; } + + // Some random sid. + const base::win::Sid& random_user_sid() const { return random_user_sid_; } + + // The file name of the current process's image. + const std::string& client_image_file_name() const { + return client_image_file_name_; + } + + // The command line string of a client that belongs to the application. + const std::wstring& client_command_line() const { + return client_command_line_; + } + + // The command line string of a client that is unrelated to the application. + const std::wstring& external_client_command_line() const { + return external_client_command_line_; + } + + // Adds the client. + PidAndTid AddClient() { + active_processes().AddProcess( + kBasePid, /*parent_pid=*/0, /*session_id=*/4, random_user_sid().Clone(), + client_image_file_name(), client_command_line()); + active_processes().AddThread(kBasePid, kBaseTid, /*thread_name=*/{}); + return {kBasePid, kBaseTid}; + } + + // Adds a child process of the client -- same image file name, parent pid + // matches the client. + PidAndTid AddChild() { + const base::ProcessId child_pid = kBasePid + kChildOffset; + const base::PlatformThreadId child_tid = kBaseTid + kChildOffset; + active_processes().AddProcess( + child_pid, kBasePid, /*session_id=*/4, random_user_sid().Clone(), + client_image_file_name(), client_command_line()); + active_processes().AddThread(child_pid, child_tid, /*thread_name=*/{}); + return {child_pid, child_tid}; + } + + // Adds a process unrelated to the client and returns its pid and a tid. + // `unrelated_pid` may be set to force a specific pid to be used. + PidAndTid AddUnrelated(base::ProcessId unrelated_pid = kBasePid + + kUnrelatedOffset) { + base::CommandLine unrelated_command_line(base::CommandLine::NO_PROGRAM); + unrelated_command_line.ParseFromString(client_command_line()); + unrelated_command_line.SetProgram( + unrelated_command_line.GetProgram().DirName().DirName().Append( + FILE_PATH_LITERAL("unrelated.exe"))); + + const base::PlatformThreadId unrelated_tid = kBaseTid + kUnrelatedOffset; + active_processes().AddProcess( + unrelated_pid, /*parent_pid=*/0, /*session_id=*/4, + random_user_sid().Clone(), "unrelated.exe", + unrelated_command_line.GetCommandLineString()); + active_processes().AddThread(unrelated_pid, unrelated_tid, + /*thread_name=*/{}); + return {unrelated_pid, unrelated_tid}; + } + + // Adds an independent process of the client -- in the same directory tree. + PidAndTid AddIndependent() { + base::CommandLine independent_command_line(base::CommandLine::NO_PROGRAM); + independent_command_line.ParseFromString(client_command_line()); + independent_command_line.SetProgram( + independent_command_line.GetProgram() + .DirName() + .Append(FILE_PATH_LITERAL("1.2.3")) + .Append(FILE_PATH_LITERAL("independent.exe"))); + + const base::ProcessId independent_pid = kBasePid + kIndependentOffset; + const base::PlatformThreadId independent_tid = + kBaseTid + kIndependentOffset; + active_processes().AddProcess( + independent_pid, /*parent_pid=*/0, /*session_id=*/4, + random_user_sid().Clone(), "independent.exe", + independent_command_line.GetCommandLineString()); + active_processes().AddThread(independent_pid, independent_tid, + /*thread_name=*/{}); + return {independent_pid, independent_tid}; + } + + private: + const std::string client_image_file_name_{"client.exe"}; + const base::win::Sid random_user_sid_{base::win::Sid::GenerateRandomSid()}; + base::ScopedTempDir temp_dir_; + base::FilePath fake_dir_exe_; + std::optional<base::ScopedPathOverride> dir_exe_override_; + std::wstring client_command_line_; + std::wstring external_client_command_line_; + + // The base pid identifies the tracing client. + std::optional<ActiveProcesses> active_processes_; +}; + +TEST_F(ActiveProcessesTest, UnknownTidIsOther) { + ASSERT_EQ(active_processes().GetThreadCategory(kBaseTid), + ActiveProcesses::Category::kOther); +} + +// Tests that a thread added for an unknown process is considered an "other" +// process. +TEST_F(ActiveProcessesTest, TidForUnknownPidIsOther) { + active_processes().AddThread(kBasePid, kBaseTid, /*thread_name=*/{}); + ASSERT_EQ(active_processes().GetThreadCategory(kBaseTid), + ActiveProcesses::Category::kOther); +} + +TEST_F(ActiveProcessesTest, ClientIsClient) { + // Add the client process and a thread, and confirm that it is categorized + // properly. + const auto [client_pid, client_tid] = AddClient(); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); +} + +// Tests that categorization of the client works as threads come and go. +TEST_F(ActiveProcessesTest, ClientThreadActivity) { + // Add the client and a couple of threads. + const auto [client_pid, client_tid] = AddClient(); + const auto client_tid2 = client_tid + 1; + active_processes().AddThread(client_pid, client_tid2, /*thread_name=*/{}); + + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid2), + ActiveProcesses::Category::kClient); + + // Now remove a thread. + active_processes().RemoveThread(client_pid, client_tid2); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid2), + ActiveProcesses::Category::kOther); + + // Now remove the process. + active_processes().RemoveProcess(client_pid); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kOther); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid2), + ActiveProcesses::Category::kOther); +} + +// Tests that a child process of the client using the same image name is +// categorized as a client proc. +TEST_F(ActiveProcessesTest, ChildOfClient) { + // Add the client. + const auto [client_pid, client_tid] = AddClient(); + + // Add a child process of the client -- same image file name, parent pid + // matches the client. + const auto [child_pid, child_tid] = AddChild(); + + // The child is categorized as a Client process. + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kClient); + + // The child going away shouldn't change the categorization of the client. + active_processes().RemoveProcess(child_pid); + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kOther); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); +} + +// Tests that a child process of the client using the same image name is +// categorized as a client proc once the client is added. +TEST_F(ActiveProcessesTest, ClientAfterChild) { + // Add a child process of the client -- same image file name, parent pid + // matches the client. + const auto [child_pid, child_tid] = AddChild(); + + // The client hasn't been added, so the child is still "other". + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kOther); + + // Add the client. + const auto [client_pid, client_tid] = AddClient(); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + + // Now the child is categorized as a Client process. + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kClient); + + // When the client goes away, the child is recategorized as "other". + active_processes().RemoveProcess(client_pid); + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kOther); +} + +// Tests that a process unrelated to the client is categorized as "other". +TEST_F(ActiveProcessesTest, UnrelatedProcess) { + // Add a process unrelated to the client -- in some other directory tree. + const auto [unrelated_pid, unrelated_tid] = AddUnrelated(); + ASSERT_EQ(active_processes().GetThreadCategory(unrelated_tid), + ActiveProcesses::Category::kOther); + + // Add the client. + const auto [client_pid, client_tid] = AddClient(); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + + // The unrelated process is still categorized as "other". + ASSERT_EQ(active_processes().GetThreadCategory(unrelated_tid), + ActiveProcesses::Category::kOther); +} + +// Tests that a process whose program resides within the directory tree of the +// client is categorized as a client proc. +TEST_F(ActiveProcessesTest, ProgramOfClient) { + // Add the client. + const auto [client_pid, client_tid] = AddClient(); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + + // Add an independent process of the client -- in the same directory tree. + const auto [independent_pid, independent_tid] = AddIndependent(); + + // The independent is categorized as a Client process. + ASSERT_EQ(active_processes().GetThreadCategory(independent_tid), + ActiveProcesses::Category::kClient); + + // The independent going away shouldn't change the categorization of the + // client. + active_processes().RemoveProcess(independent_pid); + ASSERT_EQ(active_processes().GetThreadCategory(independent_tid), + ActiveProcesses::Category::kOther); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); +} + +// Tests that a process whose program resides within the directory tree of the +// client is categorized as a client proc once the client is added. +TEST_F(ActiveProcessesTest, ClientAfterProgram) { + // Add an independent process of the client -- in the same directory tree. + const auto [independent_pid, independent_tid] = AddIndependent(); + + // The client hasn't been added, so the independent is still "other". + ASSERT_EQ(active_processes().GetThreadCategory(independent_tid), + ActiveProcesses::Category::kOther); + + // Add the client. + const auto [client_pid, client_tid] = AddClient(); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + + // Now the independent is categorized as a Client process. + ASSERT_EQ(active_processes().GetThreadCategory(independent_tid), + ActiveProcesses::Category::kClient); + + // When the client goes away, the independent is recategorized as "other". + active_processes().RemoveProcess(client_pid); + ASSERT_EQ(active_processes().GetThreadCategory(independent_tid), + ActiveProcesses::Category::kOther); +} + +// Tests that a process matching the client, but running as another user, is +// categorized as "other". +TEST_F(ActiveProcessesTest, ClientOtherUser) { + // Add the client. + const auto [client_pid, client_tid] = AddClient(); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + + // Add another instance of the client running as another user. + const base::ProcessId other_user_pid = client_pid + 1; + const base::PlatformThreadId other_user_tid = client_tid + 1; + active_processes().AddProcess( + other_user_pid, /*parent_pid=*/0, /*session_id=*/4, + base::win::Sid::GenerateRandomSid(), client_image_file_name(), + client_command_line()); + active_processes().AddThread(other_user_pid, other_user_tid, + /*thread_name=*/{}); + + // This process running as another user is categorized as "other". + ASSERT_EQ(active_processes().GetThreadCategory(other_user_tid), + ActiveProcesses::Category::kOther); +} + +// Tests that a process matching the client, but running in another window +// session, is categorized as "other". +TEST_F(ActiveProcessesTest, ClientOtherSession) { + // Add the client. + const auto [client_pid, client_tid] = AddClient(); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + + // Add another instance of the client running in a different session + const base::ProcessId other_session_pid = client_pid + 1; + const base::PlatformThreadId other_session_tid = client_tid + 1; + active_processes().AddProcess(other_session_pid, /*parent_pid=*/0, + /*session_id=*/5, random_user_sid().Clone(), + client_image_file_name(), + client_command_line()); + active_processes().AddThread(other_session_pid, other_session_tid, + /*thread_name=*/{}); + + // This process running in another session is categorized as "other". + ASSERT_EQ(active_processes().GetThreadCategory(other_session_tid), + ActiveProcesses::Category::kOther); +} + +// Tests that a client that is external to the application is considered the +// client and that other processes belonging to the application are not. +TEST_F(ActiveProcessesTest, ExternalClient) { + // Add a client that does not reside in the application's directory. + const base::ProcessId client_pid = kBasePid; + const base::PlatformThreadId client_tid = kBaseTid; + active_processes().AddProcess( + client_pid, /*parent_pid=*/0, /*session_id=*/4, random_user_sid().Clone(), + client_image_file_name(), external_client_command_line()); + active_processes().AddThread(client_pid, client_tid, /*thread_name=*/{}); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + + // If it launches a child of the application, those children are considered + // "other" with respect to the client. + const base::ProcessId child_pid = kBasePid + kChildOffset; + const base::PlatformThreadId child_tid = kBaseTid + kChildOffset; + active_processes().AddProcess( + child_pid, client_pid, /*session_id=*/4, random_user_sid().Clone(), + client_image_file_name(), client_command_line()); + active_processes().AddThread(child_pid, child_tid, /*thread_name=*/{}); + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kOther); +} + +// Tests that a system process is categorized as "other". +TEST_F(ActiveProcessesTest, SystemProcess) { + // Any process running in session 0xFFFFFFFF is a system process. + const base::ProcessId system_pid = kBasePid + kSystemOffset; + const base::PlatformThreadId system_tid = kBaseTid + kSystemOffset; + active_processes().AddProcess(system_pid, /*parent_pid=*/0, + /*session_id=*/0xFFFFFFFF, + base::win::Sid::GenerateRandomSid(), "system", + /*command_line=*/{}); + active_processes().AddThread(system_pid, system_tid, /*thread_name=*/{}); + ASSERT_EQ(active_processes().GetThreadCategory(system_tid), + ActiveProcesses::Category::kSystem); +} + +// Tests that inconsistencies from lost events are handled gracefully. +TEST_F(ActiveProcessesTest, LostEvents) { + // Add the client, a child of it, and an unrelated process. + const auto [client_pid, client_tid] = AddClient(); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + + const auto [child_pid, child_tid] = AddChild(); + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kClient); + + const auto [unrelated_pid, unrelated_tid] = AddUnrelated(); + ASSERT_EQ(active_processes().GetThreadCategory(unrelated_tid), + ActiveProcesses::Category::kOther); + + // Removing an unknown tid from an unknown pid is a noop. + active_processes().RemoveThread(client_pid + 1, client_tid + 1); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kClient); + + // Removing an unknown tid from a known pid is a noop. + active_processes().RemoveThread(client_pid, client_tid + 1); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kClient); + + // Removing a known tid from an unknown pid is a noop. + active_processes().RemoveThread(client_pid + 1, client_tid); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kClient); + + // Adding an existing tid to a different process removes the tid from the + // original. + active_processes().AddThread(client_pid, client_tid + 1, /*thread_name=*/{}); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid + 1), + ActiveProcesses::Category::kClient); + active_processes().AddThread(unrelated_pid, client_tid + 1, + /*thread_name=*/{}); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid + 1), + ActiveProcesses::Category::kOther); + + // Removing a pid also removes its tids. + active_processes().RemoveProcess(client_pid); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kOther); +} + +// Tests that a second process added with the same pid as a child of the client +// leads to the child no longer categorized as a client proc. +TEST_F(ActiveProcessesTest, DuplicatePid) { + // Add the client and a child of it. + const auto [client_pid, client_tid] = AddClient(); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + const auto [child_pid, child_tid] = AddChild(); + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kClient); + + // Imagine that events removing the child's thread and process are lost, and + // its pid is reused for a new process that is not related to the client. + const auto [unrelated_pid, unrelated_tid] = AddUnrelated(child_pid); + ASSERT_EQ(unrelated_pid, child_pid); + ASSERT_EQ(active_processes().GetThreadCategory(unrelated_tid), + ActiveProcesses::Category::kOther); + ASSERT_NE(unrelated_tid, child_tid); + + // The tid of the replaced child is no longer considered related to the + // client. + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kOther); +} + +// Tests that a second process added with the same pid as the client leads to +// the client being forgotten. +TEST_F(ActiveProcessesTest, DuplicateClient) { + // Add the client. + const auto [client_pid, client_tid] = AddClient(); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + + // Imagine a new process with the same pid as the client is added. This should + // not be possible in practice since the tracing service observes termination + // of the client and exits, but a shutdown race plus lost events could make an + // unlikely event possible. The new process should be considered as "other". + const auto [unrelated_pid, unrelated_tid] = AddUnrelated(client_pid); + ASSERT_EQ(unrelated_pid, client_pid); + ASSERT_EQ(active_processes().GetThreadCategory(unrelated_tid), + ActiveProcesses::Category::kOther); + + // The tid of the replaced process is no longer considered the client. + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kOther); +} + +// Tests that SetThreadName works in the general case, and in the face of lost +// events. +TEST_F(ActiveProcessesTest, SetThreadName) { + // Getters return empty view for unknown inputs, while setter does nothing. + ASSERT_EQ(active_processes().GetThreadName(3), L""); + active_processes().SetThreadName(/*pid=*/2, /*tid=*/3, L"Hi"); + ASSERT_EQ(active_processes().GetThreadName(3), L""); + + // Add the client and a child. + const auto [client_pid, client_tid] = AddClient(); + ASSERT_EQ(active_processes().GetThreadCategory(client_tid), + ActiveProcesses::Category::kClient); + const auto [child_pid, child_tid] = AddChild(); + ASSERT_EQ(active_processes().GetThreadCategory(child_tid), + ActiveProcesses::Category::kClient); + + // Set works on valid inputs. + ASSERT_EQ(active_processes().GetThreadName(client_tid), std::wstring_view()); + active_processes().SetThreadName(client_pid, client_tid, L"Hi"); + ASSERT_EQ(active_processes().GetThreadName(client_tid), L"Hi"); + + // Set is ignored for pid/tid mismatch. + active_processes().SetThreadName(child_pid, client_tid, L"Bye"); + ASSERT_EQ(active_processes().GetThreadName(client_tid), L"Hi"); + + // Set is ignore for invalid tid. + active_processes().SetThreadName(client_pid, client_tid + 1, L"Bye"); + ASSERT_EQ(active_processes().GetThreadName(client_tid), L"Hi"); + ASSERT_EQ(active_processes().GetThreadName(client_tid + 1), L""); + + // Set is ignore for invalid pid. + active_processes().SetThreadName(client_pid + 1, client_tid, L"Bye"); + ASSERT_EQ(active_processes().GetThreadName(client_tid), L"Hi"); +} + +} // namespace tracing
diff --git a/components/unified_consent/pref_names.cc b/components/unified_consent/pref_names.cc index 51be18a..b71abb0 100644 --- a/components/unified_consent/pref_names.cc +++ b/components/unified_consent/pref_names.cc
@@ -13,7 +13,5 @@ const char kUrlKeyedAnonymizedDataCollectionEnabled[] = "url_keyed_anonymized_data_collection.enabled"; -const char kPageContentCollectionEnabled[] = "page_content_collection.enabled"; - } // namespace prefs } // namespace unified_consent
diff --git a/components/unified_consent/pref_names.h b/components/unified_consent/pref_names.h index 40110a26..b59514d 100644 --- a/components/unified_consent/pref_names.h +++ b/components/unified_consent/pref_names.h
@@ -28,9 +28,6 @@ // NewAnonymizedDataCollectionConsentHelper. extern const char kUrlKeyedAnonymizedDataCollectionEnabled[]; -// Whether the user has enabled sharing page content. -extern const char kPageContentCollectionEnabled[]; - } // namespace unified_consent::prefs #endif // COMPONENTS_UNIFIED_CONSENT_PREF_NAMES_H_
diff --git a/components/unified_consent/unified_consent_service.cc b/components/unified_consent/unified_consent_service.cc index 8e58c72..d90746c 100644 --- a/components/unified_consent/unified_consent_service.cc +++ b/components/unified_consent/unified_consent_service.cc
@@ -191,7 +191,6 @@ prefs::kUnifiedConsentMigrationState, static_cast<int>(MigrationState::kNotInitialized)); #endif - registry->RegisterBooleanPref(prefs::kPageContentCollectionEnabled, false); } void UnifiedConsentService::SetUrlKeyedAnonymizedDataCollectionEnabled(
diff --git a/components/user_education/common/feature_promo/impl/common_preconditions.cc b/components/user_education/common/feature_promo/impl/common_preconditions.cc index 66144bc..3cbc113 100644 --- a/components/user_education/common/feature_promo/impl/common_preconditions.cc +++ b/components/user_education/common/feature_promo/impl/common_preconditions.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/functional/bind.h" +#include "base/strings/stringprintf.h" #include "components/feature_engagement/public/tracker.h" #include "components/user_education/common/feature_promo/feature_promo_lifecycle.h" #include "components/user_education/common/feature_promo/feature_promo_precondition.h"
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 0598eca..184507a 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -4,8 +4,6 @@ import("//base/allocator/partition_allocator/partition_alloc.gni") import("//build/buildflag_header.gni") -import("//build/config/chromeos/ui_mode.gni") -import("//build/config/chromeos/ui_mode.gni") import("//build/config/compiler/pgo/pgo.gni") import("//build/config/features.gni") import("//build/config/linux/pangocairo/pangocairo.gni") @@ -88,7 +86,6 @@ "//build:android_buildflags", "//build:branding_buildflags", "//build:chromecast_buildflags", - "//build:chromeos_buildflags", "//build/config/compiler:compiler_buildflags", "//cc", "//cc/animation", @@ -2551,7 +2548,7 @@ } # ChromeOS also defines linux but their memory-monitors conflict. - if (is_chromeos_ash) { + if (is_chromeos) { sources += [ "gpu/chromeos/delegate_to_browser_gpu_service_accelerator_factory.cc", "gpu/chromeos/video_capture_dependencies.cc", @@ -2856,7 +2853,7 @@ frameworks += [ "CoreMedia.framework" ] weak_frameworks = [ "ScreenCaptureKit.framework" ] # macOS 12.3 } - if (is_chromeos_ash) { + if (is_chromeos) { sources += [ "media/capture/desktop_capturer_ash.cc", "media/capture/desktop_capturer_ash.h", @@ -3216,7 +3213,6 @@ "date_time_chooser/android/date_time_chooser_android.h", "device_posture/device_posture_platform_provider_android.cc", "device_posture/device_posture_platform_provider_android.h", - "file_system_access/file_path_watcher/file_path_watcher_stub.cc", "font_unique_name_lookup/font_unique_name_lookup_android.cc", "font_unique_name_lookup/font_unique_name_lookup_android.h", "font_unique_name_lookup/font_unique_name_lookup_service.cc",
diff --git a/content/browser/accessibility/accessibility_action_browsertest.cc b/content/browser/accessibility/accessibility_action_browsertest.cc index 89e7dbe..5758e08 100644 --- a/content/browser/accessibility/accessibility_action_browsertest.cc +++ b/content/browser/accessibility/accessibility_action_browsertest.cc
@@ -17,7 +17,6 @@ #include "base/test/test_timeouts.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/test/accessibility_notification_waiter.h" #include "content/public/test/browser_test.h"
diff --git a/content/browser/accessibility/browser_accessibility_state_impl.cc b/content/browser/accessibility/browser_accessibility_state_impl.cc index e17a5c4..7f8a93d 100644 --- a/content/browser/accessibility/browser_accessibility_state_impl.cc +++ b/content/browser/accessibility/browser_accessibility_state_impl.cc
@@ -21,7 +21,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/task/thread_pool.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h"
diff --git a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc index d12a0f7..ec5015a 100644 --- a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc +++ b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
@@ -19,7 +19,6 @@ #include "base/timer/elapsed_timer.h" #include "build/build_config.h" #include "build/chromecast_buildflags.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h"
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc index b542739..86087035 100644 --- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -18,7 +18,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/browser/accessibility/dump_accessibility_browsertest_base.h" #include "content/browser/web_contents/web_contents_impl.h"
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index ce3657f..81679e05 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -15,7 +15,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/accessibility/accessibility_tree_formatter_blink.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/browser/accessibility/dump_accessibility_browsertest_base.h"
diff --git a/content/browser/accessibility/hit_testing_browsertest.cc b/content/browser/accessibility/hit_testing_browsertest.cc index b2c3e8c0..e4c8cd26 100644 --- a/content/browser/accessibility/hit_testing_browsertest.cc +++ b/content/browser/accessibility/hit_testing_browsertest.cc
@@ -10,7 +10,6 @@ #include "base/test/bind.h" #include "build/build_config.h" #include "build/chromecast_buildflags.h" -#include "build/chromeos_buildflags.h" #include "content/browser/accessibility/accessibility_tree_formatter_blink.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/ax_inspect_factory.h"
diff --git a/content/browser/android/synchronous_compositor_host.cc b/content/browser/android/synchronous_compositor_host.cc index bd0c95b0..fdc8483 100644 --- a/content/browser/android/synchronous_compositor_host.cc +++ b/content/browser/android/synchronous_compositor_host.cc
@@ -716,8 +716,7 @@ if (on_compute_scroll_called_ || !rwhva_->GetViewRenderInputRouter()->is_currently_scrolling_viewport()) { rwhva_->host()->ProgressFlingIfNeeded(args.frame_time); - } else if (base::FeatureList::IsEnabled( - features::kWebViewSuppressTapDuringFling)) { + } else { // Normally, `OnComputeScroll` is called after `OnBeginFrame`, but before // `DemandDrawHwAsync`. So `OnBeginFrame` calls before the first draw will // end up here regardless of whether `OnComputeScroll` will be called. If
diff --git a/content/browser/audio/audio_service.cc b/content/browser/audio/audio_service.cc index 63c4d957b..d461065 100644 --- a/content/browser/audio/audio_service.cc +++ b/content/browser/audio/audio_service.cc
@@ -87,12 +87,12 @@ if (!BrowserMainLoop::GetInstance()) return; -#if BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(USE_CRAS) +#if BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_CRAS) if (GetContentClient()->browser()->EnforceSystemAudioEchoCancellation()) { base::CommandLine::ForCurrentProcess()->AppendSwitch( switches::kSystemAecEnabled); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(USE_CRAS) +#endif // BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_CRAS) // TODO(crbug.com/40580951): Remove // BrowserMainLoop::GetAudioManager(). @@ -127,7 +127,7 @@ switches.push_back(base::StrCat({switches::kAudioCodecsFromEDID, "=", base::NumberToString(codec_bitmask)})); #endif // BUILDFLAG(ENABLE_PASSTHROUGH_AUDIO_CODECS) -#if BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(USE_CRAS) +#if BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_CRAS) if (GetContentClient()->browser()->EnforceSystemAudioEchoCancellation()) { switches.push_back(switches::kSystemAecEnabled); }
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index 3237face..dacaf31 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -27,7 +27,6 @@ #include "base/trace_event/trace_log.h" #include "build/build_config.h" #include "build/chromecast_buildflags.h" -#include "build/chromeos_buildflags.h" #include "components/ukm/test_ukm_recorder.h" #include "content/browser/bad_message.h" #include "content/browser/renderer_host/back_forward_cache_can_store_document_result.h"
diff --git a/content/browser/back_forward_cache_features_browsertest.cc b/content/browser/back_forward_cache_features_browsertest.cc index 58084e2..068f5668 100644 --- a/content/browser/back_forward_cache_features_browsertest.cc +++ b/content/browser/back_forward_cache_features_browsertest.cc
@@ -6,7 +6,6 @@ #include "base/threading/platform_thread.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/back_forward_cache_browsertest.h" #include "content/browser/generic_sensor/frame_sensor_provider_proxy.h" #include "content/browser/generic_sensor/web_contents_sensor_provider_proxy.h" @@ -3920,7 +3919,7 @@ adapter_ = base::MakeRefCounted<testing::NiceMock<device::MockBluetoothAdapter>>(); device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // In CHROMEOS build, even when |adapter_| object is released at TearDown() // it causes the test to fail on exit with an error indicating |adapter_| is // leaked.
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc index cea4b4a1..3c86b406 100644 --- a/content/browser/browser_child_process_host_impl.cc +++ b/content/browser/browser_child_process_host_impl.cc
@@ -29,7 +29,6 @@ #include "base/token.h" #include "base/trace_event/memory_dump_manager.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/metrics/histogram_controller.h" #include "components/tracing/common/tracing_switches.h" #include "content/browser/browser_main_loop.h" @@ -678,7 +677,7 @@ NotifyProcessLaunchedAndConnected(data_); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // In ChromeOS, there are still child processes of NaCl modules, and they // don't contribute to tracing actually. So do not register those clients // to the tracing service. See https://crbug.com/1101468.
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index 25777a0..72b73a2 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc
@@ -27,7 +27,6 @@ #include "base/notreached.h" #include "base/unguessable_token.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/download/public/common/in_progress_download_manager.h" #include "components/services/storage/privileged/mojom/indexed_db_control.mojom.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h"
diff --git a/content/browser/browser_context_impl.cc b/content/browser/browser_context_impl.cc index 6e2831f..2e25e3c 100644 --- a/content/browser/browser_context_impl.cc +++ b/content/browser/browser_context_impl.cc
@@ -33,7 +33,7 @@ #include "media/mojo/services/video_decode_perf_history.h" #include "media/mojo/services/webrtc_video_perf_history.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "storage/browser/file_system/external_mount_points.h" #endif @@ -296,7 +296,7 @@ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || !BrowserThread::IsThreadInitialized(BrowserThread::UI)); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) if (!external_mount_points_) external_mount_points_ = storage::ExternalMountPoints::CreateRefCounted(); return external_mount_points_.get();
diff --git a/content/browser/browser_context_impl.h b/content/browser/browser_context_impl.h index 29a99a9..f5a3c17b 100644 --- a/content/browser/browser_context_impl.h +++ b/content/browser/browser_context_impl.h
@@ -11,7 +11,6 @@ #include "base/memory/raw_ptr.h" #include "base/memory/scoped_refptr.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/resource_context.h" #include "content/public/browser/shared_cors_origin_access_list.h" @@ -156,7 +155,7 @@ std::unique_ptr<ResourceContext> resource_context_ = std::make_unique<ResourceContext>(); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) scoped_refptr<storage::ExternalMountPoints> external_mount_points_; #endif };
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 2f5efe0..ab40e72 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -53,7 +53,6 @@ #include "build/branding_buildflags.h" #include "build/build_config.h" #include "build/chromecast_buildflags.h" -#include "build/chromeos_buildflags.h" #include "cc/base/histograms.h" #include "components/discardable_memory/service/discardable_shared_memory_manager.h" #include "components/memory_pressure/multi_source_memory_pressure_monitor.h" @@ -203,7 +202,7 @@ #include "net/base/winsock_init.h" #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "device/bluetooth/bluetooth_adapter_factory.h" #include "services/data_decoder/public/cpp/data_decoder.h" #endif @@ -383,7 +382,7 @@ return monitor; } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) mojo::PendingRemote<data_decoder::mojom::BleScanParser> GetBleScanParser() { static base::NoDestructor<data_decoder::DataDecoder> decoder; mojo::PendingRemote<data_decoder::mojom::BleScanParser> ble_scan_parser; @@ -391,7 +390,7 @@ ble_scan_parser.InitWithNewPipeAndPassReceiver()); return ble_scan_parser; } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) class OopDataDecoder : public data_decoder::ServiceProvider { public: @@ -756,7 +755,7 @@ base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( sql::SqlMemoryDumpProvider::GetInstance(), "Sql", nullptr); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) device::BluetoothAdapterFactory::SetBleScanParserCallback( base::BindRepeating(&GetBleScanParser)); #else
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index 27b1a74..d761e64 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h
@@ -16,7 +16,6 @@ #include "base/task/thread_pool/thread_pool_instance.h" #include "base/types/strong_alias.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/browser_process_io_thread.h" #include "content/common/content_export.h" #include "content/public/browser/browser_main_runner.h"
diff --git a/content/browser/browser_process_io_thread.cc b/content/browser/browser_process_io_thread.cc index 2c3d067..3ccebd1 100644 --- a/content/browser/browser_process_io_thread.cc +++ b/content/browser/browser_process_io_thread.cc
@@ -13,7 +13,6 @@ #include "base/threading/thread_restrictions.h" #include "base/trace_event/memory_dump_manager.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/browser_child_process_host_impl.h" #include "content/browser/browser_thread_impl.h" #include "content/browser/child_process_host_impl.h" @@ -113,7 +112,7 @@ #if BUILDFLAG(CLANG_PROFILING) // On profiling build, browser_tests runs 10x slower. const int kMaxSecondsToWaitForNetworkProcess = 100; -#elif BUILDFLAG(IS_CHROMEOS_ASH) +#elif BUILDFLAG(IS_CHROMEOS) // ChromeOS will kill the browser process if it doesn't shut down within // 3 seconds, so make sure we wait for less than that. const int kMaxSecondsToWaitForNetworkProcess = 1;
diff --git a/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc b/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc index 14629fc..d0447c9 100644 --- a/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc +++ b/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc
@@ -697,19 +697,6 @@ } namespace { -// Provide BrowsingDataRemoverImplTrustTokenTest the Trust Tokens -// feature as a mixin so that it gets set before the superclass initializes -// the test's NetworkContext, as the NetworkContext's initialization must -// occur with the feature enabled. -class WithTrustTokensEnabled { - public: - WithTrustTokensEnabled() { - feature_list_.InitAndEnableFeature(network::features::kPrivateStateTokens); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; // Tests Trust Tokens clearing by calling // TrustTokenQueryAnswerer::HasTrustTokens with a TrustTokenQueryAnswerer @@ -813,9 +800,8 @@ } // namespace -class BrowsingDataRemoverImplTrustTokenTest - : public WithTrustTokensEnabled, - public BrowsingDataRemoverImplBrowserTest {}; +using BrowsingDataRemoverImplTrustTokenTest = + BrowsingDataRemoverImplBrowserTest; IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverImplTrustTokenTest, Remove) { TrustTokensTester tester(network_context());
diff --git a/content/browser/child_process_host_impl.cc b/content/browser/child_process_host_impl.cc index 7cc8188..583a386 100644 --- a/content/browser/child_process_host_impl.cc +++ b/content/browser/child_process_host_impl.cc
@@ -173,7 +173,7 @@ child_process_->BindReceiver(std::move(receiver)); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void ChildProcessHostImpl::ReinitializeLogging( uint32_t logging_dest, base::ScopedFD log_file_descriptor) { @@ -183,7 +183,7 @@ mojo::PlatformHandle(std::move(log_file_descriptor)); child_process()->ReinitializeLogging(std::move(logging_settings)); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) base::Process& ChildProcessHostImpl::GetPeerProcess() { if (!peer_process_.IsValid()) {
diff --git a/content/browser/child_process_host_impl.h b/content/browser/child_process_host_impl.h index 77bbaff..ad21f9f1 100644 --- a/content/browser/child_process_host_impl.h +++ b/content/browser/child_process_host_impl.h
@@ -81,7 +81,7 @@ void BindReceiver(mojo::GenericPendingReceiver receiver) override; void SetBatterySaverMode(bool battery_saver_mode_enabled) override; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void ReinitializeLogging(uint32_t logging_dest, base::ScopedFD log_file_descriptor) override; #endif
diff --git a/content/browser/compositor/image_transport_factory_browsertest.cc b/content/browser/compositor/image_transport_factory_browsertest.cc index 2b75d61..1adea48 100644 --- a/content/browser/compositor/image_transport_factory_browsertest.cc +++ b/content/browser/compositor/image_transport_factory_browsertest.cc
@@ -6,7 +6,6 @@ #include "base/run_loop.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/viz/common/gpu/context_lost_observer.h" #include "components/viz/common/gpu/raster_context_provider.h" #include "content/browser/gpu/browser_gpu_channel_host_factory.h" @@ -30,7 +29,7 @@ // TODO(crbug.com/394083, crbug.com/1305007, crbug.com/1302879): Flaky on // ChromeOS, Linux, and Windows. -#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) +#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) #define MAYBE_TestLostContext DISABLED_TestLostContext #else #define MAYBE_TestLostContext TestLostContext
diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc index d36b140..c8986a39 100644 --- a/content/browser/compositor/viz_process_transport_factory.cc +++ b/content/browser/compositor/viz_process_transport_factory.cc
@@ -21,7 +21,6 @@ #include "base/task/single_thread_task_runner.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/mojo_embedder/async_layer_tree_frame_sink.h" #include "cc/raster/single_thread_task_graph_runner.h" #include "cc/tiles/image_decode_cache_utils.h" @@ -127,11 +126,11 @@ } #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void SetPreferredRefreshRate(float refresh_rate) override { compositor_->OnSetPreferredRefreshRate(refresh_rate); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) private: [[maybe_unused]] const raw_ptr<ui::Compositor> compositor_; @@ -275,7 +274,7 @@ void VizProcessTransportFactory::DisableGpuCompositing( ui::Compositor* guilty_compositor) { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // A fatal error has occurred and we can't fall back to software compositing // on CrOS. These can be unrecoverable hardware errors, or bugs that should // not happen. Crash the browser process to reset everything.
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc index 7325d90..05240699 100644 --- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -27,7 +27,6 @@ #include "base/test/values_test_util.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/download/public/common/download_file_factory.h" #include "components/download/public/common/download_file_impl.h" #include "components/download/public/common/download_task_runner.h" @@ -855,7 +854,7 @@ // TODO(crbug.com/40156819) Android Lollipop has a problem with capturing // screenshot. // TODO(crbug.com/40815512): Failing on MacOS. -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) #define MAYBE_CaptureScreenshotBeyondViewport_InnerScrollbarsAreShown \ DISABLED_CaptureScreenshotBeyondViewport_InnerScrollbarsAreShown #else @@ -898,7 +897,7 @@ } // ChromeOS and Android don't support software compositing. -#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID) +#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID) class NoGPUCaptureScreenshotTest : public CaptureScreenshotTest { void SetUpCommandLine(base::CommandLine* command_line) override { @@ -957,7 +956,7 @@ EXPECT_GT(static_cast<int>(SkColorGetB(bottom_left)), 128); } -#endif // !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID) +#endif // !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID) // Setting frame size (through RWHV) is not supported on Android. // This test seems to be very flaky on all platforms: https://crbug.com/801173
diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc index 6a3a2c2..a23f0fa 100644 --- a/content/browser/devtools/protocol/target_handler.cc +++ b/content/browser/devtools/protocol/target_handler.cc
@@ -21,7 +21,6 @@ #include "base/unguessable_token.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/devtools/browser_devtools_agent_host.h" #include "content/browser/devtools/devtools_agent_host_impl.h" #include "content/browser/devtools/devtools_manager.h"
diff --git a/content/browser/file_system/browser_file_system_helper.cc b/content/browser/file_system/browser_file_system_helper.cc index e8a13f7..b3f2597 100644 --- a/content/browser/file_system/browser_file_system_helper.cc +++ b/content/browser/file_system/browser_file_system_helper.cc
@@ -17,7 +17,6 @@ #include "base/task/lazy_thread_pool_task_runner.h" #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool.h" -#include "build/chromeos_buildflags.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" @@ -187,7 +186,7 @@ ChildProcessSecurityPolicyImpl* security_policy, int child_id, const storage::FileSystemContext* file_system_context) { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // The externalfile:// scheme is used in Chrome OS to open external files in a // browser tab. // TODO(https://crbug.com/858972): This seems like it could be forged by the
diff --git a/content/browser/file_system_access/features.cc b/content/browser/file_system_access/features.cc index 97e27f1e..dcdcd88 100644 --- a/content/browser/file_system_access/features.cc +++ b/content/browser/file_system_access/features.cc
@@ -6,8 +6,6 @@ #include "base/feature_list.h" #include "build/build_config.h" -#include "third_party/blink/public/common/features.h" -#include "third_party/blink/public/common/features_generated.h" namespace content::features { @@ -29,54 +27,4 @@ BASE_FEATURE(kFileSystemAccessDirectoryIterationBlocklistCheck, "FileSystemAccessDirectoryIterationBlocklistCheck", base::FEATURE_ENABLED_BY_DEFAULT); - -// When enabled, sites are limited in how much underlying operating resources -// they can access through the `FileSystemObserver` API. This limit is called -// the quota limit. Without this enabled, sites will be limited by the system -// limit. -BASE_FEATURE(kFileSystemAccessObserverQuotaLimit, - "FileSystemAccessObserverQuotaLimit", - base::FEATURE_ENABLED_BY_DEFAULT); - -// On Linux, the quota limit is found by: -// 1. Rounding down the system limit (read from -// /proc/sys/fs/inotify/max_user_watches) to the nearest -// `kFileSystemObserverQuotaLimitLinuxBucketSize`. -// 2. Taking that max of that result and -// `kFileSystemObserverQuotaLimitLinuxMin`. -// 3. And setting quota limit to `kFileSystemObserverQuotaLimitLinuxPercent`% of -// that result. -BASE_FEATURE_PARAM(size_t, - kFileSystemObserverQuotaLimitLinuxBucketSize, - &kFileSystemAccessObserverQuotaLimit, - "file_system_observer_quota_limit_linux_bucket_size", - 100000); -BASE_FEATURE_PARAM(size_t, - kFileSystemObserverQuotaLimitLinuxMin, - &kFileSystemAccessObserverQuotaLimit, - "file_system_observer_quota_limit_linux_min", - 8192); -BASE_FEATURE_PARAM(double, - kFileSystemObserverQuotaLimitLinuxPercent, - &kFileSystemAccessObserverQuotaLimit, - "file_system_observer_quota_limit_linux_percent", - 0.8); - -// On Mac, the quota limit is `kFileSystemObserverQuotaLimitMacPercent`% of the -// system limit (512) which is constant across all devices. -BASE_FEATURE_PARAM(double, - kFileSystemObserverQuotaLimitMacPercent, - &kFileSystemAccessObserverQuotaLimit, - "file_system_observer_quota_limit_mac_percent", - 0.2 // About 100 FSEventStreamCreate calls. -); - -// On Windows, the quota limit is a constant memory size. -BASE_FEATURE_PARAM(size_t, - kFileSystemObserverQuotaLimitWindows, - &kFileSystemAccessObserverQuotaLimit, - "file_system_observer_quota_limit_windows", - 2 << 28 // 1/2GiB -); - } // namespace content::features
diff --git a/content/browser/file_system_access/features.h b/content/browser/file_system_access/features.h index 1dd96ff..17e560ae 100644 --- a/content/browser/file_system_access/features.h +++ b/content/browser/file_system_access/features.h
@@ -6,7 +6,6 @@ #define CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FEATURES_H_ #include "base/feature_list.h" -#include "base/metrics/field_trial_params.h" #include "build/build_config.h" #include "content/common/content_export.h" @@ -19,21 +18,6 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kFileSystemAccessDragAndDropCheckBlocklist); CONTENT_EXPORT BASE_DECLARE_FEATURE( kFileSystemAccessDirectoryIterationBlocklistCheck); -CONTENT_EXPORT BASE_DECLARE_FEATURE(kFileSystemAccessObserverQuotaLimit); -CONTENT_EXPORT BASE_DECLARE_FEATURE_PARAM( - size_t, - kFileSystemObserverQuotaLimitLinuxBucketSize); -CONTENT_EXPORT BASE_DECLARE_FEATURE_PARAM( - size_t, - kFileSystemObserverQuotaLimitLinuxMin); -CONTENT_EXPORT BASE_DECLARE_FEATURE_PARAM( - double, - kFileSystemObserverQuotaLimitLinuxPercent); -CONTENT_EXPORT BASE_DECLARE_FEATURE_PARAM( - double, - kFileSystemObserverQuotaLimitMacPercent); -CONTENT_EXPORT BASE_DECLARE_FEATURE_PARAM(size_t, - kFileSystemObserverQuotaLimitWindows); } // namespace content::features
diff --git a/content/browser/file_system_access/file_path_watcher/file_path_watcher.cc b/content/browser/file_system_access/file_path_watcher/file_path_watcher.cc index 3013fa8..e8770d6e 100644 --- a/content/browser/file_system_access/file_path_watcher/file_path_watcher.cc +++ b/content/browser/file_system_access/file_path_watcher/file_path_watcher.cc
@@ -13,7 +13,6 @@ #include "base/check.h" #include "base/files/file_path.h" #include "build/build_config.h" -#include "content/browser/file_system_access/features.h" namespace content { @@ -135,12 +134,8 @@ // static size_t FilePathWatcher::quota_limit() { - if (base::FeatureList::IsEnabled( - features::kFileSystemAccessObserverQuotaLimit)) { - return GetQuotaLimitImpl(); - } - - return std::numeric_limits<size_t>::max(); + // TODO(crbug.com/338457523): Decide per platform limits. + return SIZE_MAX; } } // namespace content
diff --git a/content/browser/file_system_access/file_path_watcher/file_path_watcher.h b/content/browser/file_system_access/file_path_watcher/file_path_watcher.h index d121d05..9ee6886 100644 --- a/content/browser/file_system_access/file_path_watcher/file_path_watcher.h +++ b/content/browser/file_system_access/file_path_watcher/file_path_watcher.h
@@ -265,8 +265,6 @@ private: explicit FilePathWatcher(std::unique_ptr<PlatformDelegate> delegate); - static size_t GetQuotaLimitImpl(); - std::unique_ptr<PlatformDelegate> impl_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/content/browser/file_system_access/file_path_watcher/file_path_watcher_fsevents.cc b/content/browser/file_system_access/file_path_watcher/file_path_watcher_fsevents.cc index 9b7be93..b7fa0ab0 100644 --- a/content/browser/file_system_access/file_path_watcher/file_path_watcher_fsevents.cc +++ b/content/browser/file_system_access/file_path_watcher/file_path_watcher_fsevents.cc
@@ -93,7 +93,7 @@ } size_t FilePathWatcherFSEvents::current_usage() const { - return kNumberOfFSEventStreamCreateCalls; + return kNumberOfWatches; } bool FilePathWatcherFSEvents::Watch(const base::FilePath& path, @@ -248,6 +248,10 @@ base::apple::FilePathToCFString(resolved_target_); CFStringRef paths_array[] = {cf_path.get()}; + static_assert(std::size(paths_array) == kNumberOfWatches, + "Update kNumberOfWatches to equal the number of paths we're " + "watching so that usage is reported accurately."); + base::apple::ScopedCFTypeRef<CFArrayRef> watched_paths( CFArrayCreate(NULL, reinterpret_cast<const void**>(paths_array), std::size(paths_array), &kCFTypeArrayCallBacks)); @@ -259,9 +263,6 @@ context.release = NULL; context.copyDescription = NULL; - // Ensure that if more `FSEventStreamCreate` calls are added that - // `kNumberOfFSEventStreamCreateCalls` is updated to match. - // The parameters of `FSEventStreamCreate` are defined by the FSEvents API: // (https://developer.apple.com/documentation/coreservices/1443980-fseventstreamcreate). fsevent_stream_ = FSEventStreamCreate(
diff --git a/content/browser/file_system_access/file_path_watcher/file_path_watcher_fsevents.h b/content/browser/file_system_access/file_path_watcher/file_path_watcher_fsevents.h index dfe4d30f..a8d748b 100644 --- a/content/browser/file_system_access/file_path_watcher/file_path_watcher_fsevents.h +++ b/content/browser/file_system_access/file_path_watcher/file_path_watcher_fsevents.h
@@ -31,10 +31,7 @@ public: using ChangeEvent = FilePathWatcherFSEventsChangeTracker::ChangeEvent; - // We only call FSEventStreamCreate once per FilePathWatcher. This number is - // used to report usage. If more FSEventStreamCreate calls are added, this - // number must be updated. - static constexpr size_t kNumberOfFSEventStreamCreateCalls = 1; + static constexpr size_t kNumberOfWatches = 1; FilePathWatcherFSEvents(); FilePathWatcherFSEvents(const FilePathWatcherFSEvents&) = delete;
diff --git a/content/browser/file_system_access/file_path_watcher/file_path_watcher_inotify.cc b/content/browser/file_system_access/file_path_watcher/file_path_watcher_inotify.cc index 0d83433..fa046d1 100644 --- a/content/browser/file_system_access/file_path_watcher/file_path_watcher_inotify.cc +++ b/content/browser/file_system_access/file_path_watcher/file_path_watcher_inotify.cc
@@ -45,7 +45,6 @@ #include "base/trace_event/base_tracing.h" #include "base/types/expected.h" #include "build/build_config.h" -#include "content/browser/file_system_access/features.h" #include "content/browser/file_system_access/file_path_watcher/file_path_watcher.h" #include "content/browser/file_system_access/file_path_watcher/file_path_watcher_histogram.h" @@ -59,6 +58,11 @@ constexpr char kInotifyMaxUserWatchesPath[] = "/proc/sys/fs/inotify/max_user_watches"; +// This is a soft limit. If there are more than |kExpectedFilePathWatches| +// FilePathWatchers for a user, than they might affect each other's inotify +// watchers limit. +constexpr size_t kExpectedFilePathWatchers = 16u; + // The default max inotify watchers limit per user, if reading // /proc/sys/fs/inotify/max_user_watches fails. constexpr size_t kDefaultInotifyMaxUserWatches = 8192u; @@ -71,23 +75,6 @@ // Used by test to override inotify watcher limit. size_t g_override_max_inotify_watches = 0u; -// Rounds `value` down to nearest multiple of `multiple`. -size_t RoundDownToNearestMultiple(size_t value, size_t multiple) { - return value / multiple * multiple; -} - -size_t GetQuotaLimitFromSystemLimit(size_t system_limit) { - size_t nearest_bucket = RoundDownToNearestMultiple( - system_limit, - features::kFileSystemObserverQuotaLimitLinuxBucketSize.Get()); - - size_t effective_system_limit = std::max( - nearest_bucket, features::kFileSystemObserverQuotaLimitLinuxMin.Get()); - - return features::kFileSystemObserverQuotaLimitLinuxPercent.Get() * - effective_system_limit; -} - class InotifyReaderThreadDelegate final : public base::PlatformThread::Delegate { public: @@ -1358,10 +1345,10 @@ std::ifstream in(kInotifyMaxUserWatchesPath); if (!in.is_open() || !(in >> max_number_of_inotify_watches)) { LOG(ERROR) << "Failed to read " << kInotifyMaxUserWatchesPath; - return kDefaultInotifyMaxUserWatches; + return kDefaultInotifyMaxUserWatches / kExpectedFilePathWatchers; } - return max_number_of_inotify_watches; + return max_number_of_inotify_watches / kExpectedFilePathWatchers; }(); return g_override_max_inotify_watches ? g_override_max_inotify_watches : max; #endif // if BUILDFLAG(IS_FUCHSIA) @@ -1378,18 +1365,9 @@ g_override_max_inotify_watches = 0u; } -size_t GetQuotaLimitFromSystemLimitForTesting(size_t system_limit) { - return GetQuotaLimitFromSystemLimit(system_limit); -} - FilePathWatcher::FilePathWatcher() : FilePathWatcher(std::make_unique<FilePathWatcherImpl>()) {} -// static -size_t FilePathWatcher::GetQuotaLimitImpl() { - return GetQuotaLimitFromSystemLimit(GetMaxNumberOfInotifyWatches()); -} - #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) // Put inside "BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)" because Android // includes file_path_watcher_linux.cc.
diff --git a/content/browser/file_system_access/file_path_watcher/file_path_watcher_inotify.h b/content/browser/file_system_access/file_path_watcher/file_path_watcher_inotify.h index 51182a58..7a8d27d 100644 --- a/content/browser/file_system_access/file_path_watcher/file_path_watcher_inotify.h +++ b/content/browser/file_system_access/file_path_watcher/file_path_watcher_inotify.h
@@ -22,9 +22,6 @@ ~ScopedMaxNumberOfInotifyWatchesOverrideForTest(); }; -CONTENT_EXPORT size_t -GetQuotaLimitFromSystemLimitForTesting(size_t system_limit); - } // namespace content #endif // CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_PATH_WATCHER_FILE_PATH_WATCHER_INOTIFY_H_
diff --git a/content/browser/file_system_access/file_path_watcher/file_path_watcher_mac.cc b/content/browser/file_system_access/file_path_watcher/file_path_watcher_mac.cc index a442601..139b4a4 100644 --- a/content/browser/file_system_access/file_path_watcher/file_path_watcher_mac.cc +++ b/content/browser/file_system_access/file_path_watcher/file_path_watcher_mac.cc
@@ -8,7 +8,6 @@ #include "base/memory/ptr_util.h" #include "build/build_config.h" -#include "content/browser/file_system_access/features.h" #include "content/browser/file_system_access/file_path_watcher/file_path_watcher_kqueue.h" #if !BUILDFLAG(IS_IOS) @@ -19,11 +18,6 @@ namespace { -// From experiment, we determined that the max calls to FSEventStreamCreate per -// process is 512. There is a higher system wide limit (at least 970), but we -// use the process limit since we'll hit it first. -constexpr size_t kMaxCreateFSEventCalls = 512u; - class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate { public: FilePathWatcherImpl() = default; @@ -77,13 +71,4 @@ FilePathWatcher::FilePathWatcher() : FilePathWatcher(std::make_unique<FilePathWatcherImpl>()) {} -// static -size_t FilePathWatcher::GetQuotaLimitImpl() { - // TODO(crbug.com/383148762): This is only applicable to the - // `FilePathWatcherFSEvents` implementation. `FilePathWatcherKQueue` is unused - // so this shouldn't matter. - return kMaxCreateFSEventCalls * - features::kFileSystemObserverQuotaLimitMacPercent.Get(); -} - } // namespace content
diff --git a/content/browser/file_system_access/file_path_watcher/file_path_watcher_stub.cc b/content/browser/file_system_access/file_path_watcher/file_path_watcher_stub.cc index cc000d0..d41f454 100644 --- a/content/browser/file_system_access/file_path_watcher/file_path_watcher_stub.cc +++ b/content/browser/file_system_access/file_path_watcher/file_path_watcher_stub.cc
@@ -42,9 +42,4 @@ FilePathWatcher::FilePathWatcher() : FilePathWatcher(std::make_unique<FilePathWatcherImpl>()) {} -// static -size_t FilePathWatcher::GetQuotaLimitImpl() { - return std::numeric_limits<size_t>::max(); -} - } // namespace content
diff --git a/content/browser/file_system_access/file_path_watcher/file_path_watcher_unittest.cc b/content/browser/file_system_access/file_path_watcher/file_path_watcher_unittest.cc index 75f2db8..db9f3811 100644 --- a/content/browser/file_system_access/file_path_watcher/file_path_watcher_unittest.cc +++ b/content/browser/file_system_access/file_path_watcher/file_path_watcher_unittest.cc
@@ -21,13 +21,11 @@ #include "base/run_loop.h" #include "base/sequence_checker.h" #include "base/strings/stringprintf.h" -#include "base/strings/to_string.h" #include "base/task/bind_post_task.h" #include "base/task/sequenced_task_runner.h" #include "base/task/single_thread_task_runner.h" #include "base/test/bind.h" #include "base/test/run_until.h" -#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/test/test_file_util.h" #include "base/test/test_future.h" @@ -35,7 +33,6 @@ #include "base/thread_annotations.h" #include "base/threading/thread.h" #include "build/build_config.h" -#include "content/browser/file_system_access/features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -1874,53 +1871,6 @@ } } -TEST_F(FilePathWatcherTest, InotifyQuotaLimit) { - size_t quota_bucket_size = 100000; - size_t quota_min = 8192; - double quota_percent = 0.8; - - base::FieldTrialParams params; - params["file_system_observer_quota_limit_linux_bucket_size"] = - base::ToString(quota_bucket_size); - params["file_system_observer_quota_limit_linux_min"] = - base::ToString(quota_min); - params["file_system_observer_quota_limit_linux_percent"] = - base::ToString(quota_percent); - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeatureWithParameters( - features::kFileSystemAccessObserverQuotaLimit, params); - - // The quota limit is always set to the `quota_percent` of a "effective system - // limit" which is the system limit we choose and is less than or equal to the - // actual system limit. - - // The first bucket's effective system limit is the `quota_min`. - size_t expected_min_quota_limit = quota_min * quota_percent; - - // The first bucket should have a quota limit of `expected_min_quota_limit`. - EXPECT_EQ(GetQuotaLimitFromSystemLimitForTesting(0), - expected_min_quota_limit); - EXPECT_EQ(GetQuotaLimitFromSystemLimitForTesting(quota_bucket_size / 2), - expected_min_quota_limit); - EXPECT_EQ(GetQuotaLimitFromSystemLimitForTesting(quota_bucket_size - 1), - expected_min_quota_limit); - - // Every other bucket should have an effective system limit of the bucket's - // minimum value. - for (size_t bucket = quota_bucket_size; bucket < 10 * quota_bucket_size; - bucket += quota_bucket_size) { - size_t expected_quota_limit = bucket * quota_percent; - EXPECT_EQ(GetQuotaLimitFromSystemLimitForTesting(bucket), - expected_quota_limit); - EXPECT_EQ( - GetQuotaLimitFromSystemLimitForTesting(bucket + quota_bucket_size / 2), - expected_quota_limit); - EXPECT_EQ( - GetQuotaLimitFromSystemLimitForTesting(bucket + quota_bucket_size - 1), - expected_quota_limit); - } -} - // Verify that "Watch()" returns false and callback is not invoked when limit is // hit during setup. TEST_F(FilePathWatcherTest, InotifyLimitInWatch) {
diff --git a/content/browser/file_system_access/file_path_watcher/file_path_watcher_win.cc b/content/browser/file_system_access/file_path_watcher/file_path_watcher_win.cc index a9c672a..14e58c59 100644 --- a/content/browser/file_system_access/file_path_watcher/file_path_watcher_win.cc +++ b/content/browser/file_system_access/file_path_watcher/file_path_watcher_win.cc
@@ -39,7 +39,6 @@ #include "base/win/object_watcher.h" #include "base/win/scoped_handle.h" #include "base/win/windows_types.h" -#include "content/browser/file_system_access/features.h" #include "content/browser/file_system_access/file_path_watcher/file_path_watcher_change_tracker.h" #include "content/browser/file_system_access/file_path_watcher/file_path_watcher_histogram.h" @@ -794,9 +793,4 @@ FilePathWatcher::FilePathWatcher() : FilePathWatcher(std::make_unique<FilePathWatcherImpl>()) {} -// static -size_t FilePathWatcher::GetQuotaLimitImpl() { - return features::kFileSystemObserverQuotaLimitWindows.Get(); -} - } // namespace content
diff --git a/content/browser/file_system_access/file_system_access_clipboard_browsertest.cc b/content/browser/file_system_access/file_system_access_clipboard_browsertest.cc index c03acb11..34633551 100644 --- a/content/browser/file_system_access/file_system_access_clipboard_browsertest.cc +++ b/content/browser/file_system_access/file_system_access_clipboard_browsertest.cc
@@ -8,7 +8,6 @@ #include "base/files/scoped_temp_dir.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h"
diff --git a/content/browser/file_system_access/file_system_access_file_modification_host_impl_browsertest.cc b/content/browser/file_system_access/file_system_access_file_modification_host_impl_browsertest.cc index a63ab87e..e8c8581 100644 --- a/content/browser/file_system_access/file_system_access_file_modification_host_impl_browsertest.cc +++ b/content/browser/file_system_access/file_system_access_file_modification_host_impl_browsertest.cc
@@ -6,7 +6,6 @@ #include "base/memory/scoped_refptr.h" #include "base/test/bind.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h"
diff --git a/content/browser/file_system_access/file_system_access_safe_move_helper.cc b/content/browser/file_system_access/file_system_access_safe_move_helper.cc index 4fe08e48..1925a6c 100644 --- a/content/browser/file_system_access/file_system_access_safe_move_helper.cc +++ b/content/browser/file_system_access/file_system_access_safe_move_helper.cc
@@ -13,7 +13,6 @@ #include "base/task/thread_pool.h" #include "base/thread_annotations.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/services/quarantine/quarantine.h" #include "content/browser/file_system_access/features.h" #include "content/browser/file_system_access/file_system_access_error.h" @@ -325,7 +324,7 @@ // On ChromeOS on the other hand anything that isn't in the sandboxed file // system is also uniquely identifiable by its FileSystemURL::path(), and // thus we accept all other FileSystemURL types. -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) DCHECK(target_url.type() != storage::kFileSystemTypeTemporary && target_url.type() != storage::kFileSystemTypePersistent) << target_url.type();
diff --git a/content/browser/form_controls_browsertest.cc b/content/browser/form_controls_browsertest.cc index 689e48a..71825876 100644 --- a/content/browser/form_controls_browsertest.cc +++ b/content/browser/form_controls_browsertest.cc
@@ -5,7 +5,6 @@ #include "base/files/file_util.h" #include "base/path_service.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/test/pixel_comparator.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/common/content_paths.h"
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc index 672cfb0d..761672c0 100644 --- a/content/browser/gpu/browser_gpu_channel_host_factory.cc +++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -18,7 +18,6 @@ #include "base/timer/timer.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/viz/host/gpu_host_impl.h" #include "content/browser/child_process_host_impl.h" #include "content/browser/gpu/gpu_data_manager_impl.h" @@ -341,7 +340,7 @@ // CrOS and this check failed when tested on an experimental builder. Revert // https://crrev.com/c/3174621 to enable it. See go/chrome-dcheck-on-cros // or http://crbug.com/1113456 for more details. -#if !BUILDFLAG(IS_CHROMEOS_ASH) +#if !BUILDFLAG(IS_CHROMEOS) DCHECK(!pending_request_.get()); #endif // Recreate the channel if it has been lost.
diff --git a/content/browser/gpu/chromeos/video_capture_dependencies.cc b/content/browser/gpu/chromeos/video_capture_dependencies.cc index a29543bb..6deb825 100644 --- a/content/browser/gpu/chromeos/video_capture_dependencies.cc +++ b/content/browser/gpu/chromeos/video_capture_dependencies.cc
@@ -5,7 +5,6 @@ #include "content/browser/gpu/chromeos/video_capture_dependencies.h" #include "base/functional/bind.h" -#include "build/chromeos_buildflags.h" #include "content/browser/gpu/gpu_process_host.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -33,7 +32,7 @@ } } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // static void VideoCaptureDependencies::CreateJpegEncodeAccelerator( mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator> @@ -54,6 +53,6 @@ LOG(ERROR) << "No GpuProcessHost"; } } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } // namespace content
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index 486d4fc..815d9cb 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc
@@ -24,7 +24,6 @@ #include "base/system/sys_info.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/base/switches.h" #include "components/viz/common/features.h" #include "content/browser/compositor/image_transport_factory.h"
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc index 8e2f989a..c845384 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -42,7 +42,6 @@ #include "base/trace_event/trace_event.h" #include "base/version.h" #include "build/chromecast_buildflags.h" -#include "build/chromeos_buildflags.h" #include "cc/base/switches.h" #include "components/viz/common/features.h" #include "content/browser/gpu/gpu_memory_buffer_manager_singleton.h" @@ -513,7 +512,7 @@ // Android and Chrome OS can't switch to software compositing. If the GPU // process initialization fails or GPU process is too unstable then crash the // browser process to reset everything. -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) fallback_modes_.push_back(gpu::GpuMode::DISPLAY_COMPOSITOR); if (SwiftShaderAllowed()) fallback_modes_.push_back(gpu::GpuMode::SWIFTSHADER); @@ -531,7 +530,7 @@ #endif // BUILDFLAG(IS_CASTOS) #if (BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CAST_ANDROID)) || \ - BUILDFLAG(IS_CHROMEOS_ASH) + BUILDFLAG(IS_CHROMEOS) NOTREACHED() << "GPU acceleration is required on certain platforms!"; #endif } else if (features::IsSkiaGraphiteEnabled(command_line)) {
diff --git a/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc b/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc index 3cec508..d3dcebb 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
@@ -18,7 +18,6 @@ #include "base/time/time.h" #include "build/build_config.h" #include "build/chromecast_buildflags.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/gpu_data_manager_observer.h" #include "content/public/common/content_switches.h" #include "gpu/command_buffer/service/gpu_switches.h" @@ -487,7 +486,7 @@ // Android and Chrome OS do not support software compositing, while Fuchsia does // not support falling back to software from Vulkan. -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_IOS) +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_IOS) #if !BUILDFLAG(IS_FUCHSIA) TEST_F(GpuDataManagerImplPrivateTest, NoDefaultFallbackToSwiftShader) { base::test::ScopedFeatureList feature_list; @@ -573,7 +572,7 @@ EXPECT_EQ(gpu::GpuMode::DISPLAY_COMPOSITOR, manager->GetGpuMode()); } #endif // !defined(CAST_AUDIO_ONLY) -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) && +#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) && // !BUILDFLAG(IS_IOS) // Chromecast audio-only builds should not launch the GPU process. @@ -628,14 +627,14 @@ // The first fallback should go to the display compositor on platforms where // fallback to software is allowed. -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_IOS) +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_IOS) manager->FallBackToNextGpuMode(); EXPECT_EQ(gpu::GpuMode::DISPLAY_COMPOSITOR, manager->GetGpuMode()); -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) && +#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) && // !BUILDFLAG(IS_IOS) } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_IOS) +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_IOS) TEST_F(GpuDataManagerImplPrivateTest, FallbackFromVulkanWithGLDisabled) { base::test::ScopedFeatureList feature_list; feature_list.InitWithFeatures({features::kVulkan}, @@ -651,7 +650,7 @@ manager->FallBackToNextGpuMode(); EXPECT_EQ(gpu::GpuMode::DISPLAY_COMPOSITOR, manager->GetGpuMode()); } -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) && +#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) && // !BUILDFLAG(IS_IOS) #endif // !BUILDFLAG(IS_FUCHSIA) #endif // BUILDFLAG(ENABLE_VULKAN)
diff --git a/content/browser/gpu/gpu_ipc_browsertests.cc b/content/browser/gpu/gpu_ipc_browsertests.cc index 2681a46..cc7ce54 100644 --- a/content/browser/gpu/gpu_ipc_browsertests.cc +++ b/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -105,7 +105,6 @@ #define CONTEXT_TEST_F IN_PROC_BROWSER_TEST_F #include "base/functional/bind.h" #include "base/task/single_thread_task_runner.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/browser_thread.h" #include "gpu/ipc/client/gpu_context_tests.h"
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 9112c7c4..4bdf399 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -34,7 +34,6 @@ #include "base/threading/thread.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/discardable_memory/service/discardable_shared_memory_manager.h" #include "components/tracing/common/tracing_switches.h" #include "components/viz/common/features.h" @@ -1156,7 +1155,7 @@ } void GpuProcessHost::DisableGpuCompositing() { -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) DLOG(ERROR) << "Can't disable GPU compositing"; #else // TODO(crbug.com/40565996): The switch from GPU to software compositing
diff --git a/content/browser/gpu/gpu_process_host_receiver_bindings.cc b/content/browser/gpu/gpu_process_host_receiver_bindings.cc index bbf984c..004b4e1 100644 --- a/content/browser/gpu/gpu_process_host_receiver_bindings.cc +++ b/content/browser/gpu/gpu_process_host_receiver_bindings.cc
@@ -7,7 +7,6 @@ #include "content/browser/gpu/gpu_process_host.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" @@ -20,7 +19,7 @@ #include "media/mojo/mojom/android_overlay.mojom.h" #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "components/services/font/public/mojom/font_service.mojom.h" // nogncheck #include "content/browser/font_service.h" // nogncheck #endif @@ -49,7 +48,7 @@ } #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) if (auto font_receiver = generic_receiver.As<font_service::mojom::FontService>()) { ConnectToFontService(std::move(font_receiver));
diff --git a/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc b/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc index affbe73..27d54f5 100644 --- a/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc +++ b/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc
@@ -12,7 +12,6 @@ #include "base/task/thread_pool.h" #include "base/test/metrics/histogram_tester.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/viz/test/gpu_host_impl_test_api.h" #include "content/browser/gpu/gpu_process_host.h" #include "content/public/browser/browser_task_traits.h" @@ -72,7 +71,7 @@ void OnDiskCacheHandleDestoyed( const gpu::GpuDiskCacheHandle& handle) override {} void CloseChannel(int32_t client_id) override {} -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) void CreateArcVideoDecodeAccelerator( mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver) @@ -95,7 +94,7 @@ void CreateJpegEncodeAccelerator( mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator> jea_receiver) override {} -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(IS_WIN) void RegisterDCOMPSurfaceHandle( mojo::PlatformHandle surface_handle,
diff --git a/content/browser/handwriting/handwriting_recognition_service_impl_cros.cc b/content/browser/handwriting/handwriting_recognition_service_impl_cros.cc index aa1af7b..fed945c 100644 --- a/content/browser/handwriting/handwriting_recognition_service_impl_cros.cc +++ b/content/browser/handwriting/handwriting_recognition_service_impl_cros.cc
@@ -9,13 +9,12 @@ #include "base/command_line.h" #include "base/memory/ptr_util.h" -#include "build/chromeos_buildflags.h" #include "content/browser/handwriting/handwriting_recognizer_impl_cros.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "third_party/blink/public/mojom/handwriting/handwriting.mojom.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "chromeos/services/machine_learning/public/cpp/ml_switches.h" #endif @@ -27,7 +26,7 @@ // supported by the CrOS Downloadable Content (DLC) service other than on // rootfs. bool IsCrOSLibHandwritingRootfsEnabled() { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // TODO(https://crbug.com/1168978): mlservice should provide an interface to // query this. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index 413084d..9e82343 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -33,7 +33,6 @@ #include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" #include "components/services/storage/privileged/mojom/indexed_db_control.mojom-test-utils.h" #include "components/services/storage/privileged/mojom/indexed_db_control_test.mojom.h"
diff --git a/content/browser/indexed_db/indexed_db_feature_observer_browsertest.cc b/content/browser/indexed_db/indexed_db_feature_observer_browsertest.cc index 337bb89f..477d188 100644 --- a/content/browser/indexed_db/indexed_db_feature_observer_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_feature_observer_browsertest.cc
@@ -6,7 +6,6 @@ #include "base/task/single_thread_task_runner.h" #include "base/test/test_timeouts.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/feature_observer.h" #include "content/public/browser/back_forward_cache.h" #include "content/public/browser/content_browser_client.h" @@ -193,7 +192,7 @@ // IndexedDB connections (notifications only when the number of held connections // switches between zero and non-zero). // Disabled on ChromeOS release build for flakiness. See crbug.com/1030733. -#if BUILDFLAG(IS_CHROMEOS_ASH) && defined(NDEBUG) +#if BUILDFLAG(IS_CHROMEOS) && defined(NDEBUG) #define MAYBE_ObserverTwoLocks DISABLED_ObserverTwoLocks #else #define MAYBE_ObserverTwoLocks ObserverTwoLocks
diff --git a/content/browser/interest_group/interest_group_auction.cc b/content/browser/interest_group/interest_group_auction.cc index 54c63d0..ab8d5a8 100644 --- a/content/browser/interest_group/interest_group_auction.cc +++ b/content/browser/interest_group/interest_group_auction.cc
@@ -4834,6 +4834,8 @@ // BuyerHelper may filter out additional interest groups on construction. if (buyer_helper->has_potential_bidder()) { buyer_helpers_.emplace_back(std::move(buyer_helper)); + interest_group_manager_->UpdateCachedOriginsIfEnabled( + interest_groups[0]->interest_group.owner); } else { // `buyer_helper` has a raw pointer to `this`, so if it's not added to // buyer_helpers_, delete it now to avoid a dangling pointer, since
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc index a119e8fa..7be3abda 100644 --- a/content/browser/interest_group/interest_group_browsertest.cc +++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -23913,8 +23913,6 @@ url::Origin joining_origin = url::Origin::Create(joining_url); ASSERT_TRUE(NavigateToURL(shell(), joining_url)); - // Join an interest group. The owner, a.test, will be in the in-memory - // cache. GURL ad_url = embedded_https_test_server().GetURL("a.test", "/echo?render_winner"); // Use a bidding script that does not bid to prevent the auction from having a @@ -23934,8 +23932,6 @@ WaitForAccessObserved({{"global", TestInterestGroupObserver::kJoin, interest_group.owner, "interest_group"}}); std::optional<url::Origin> cached_signals_origin; - EXPECT_TRUE(manager_->GetCachedOwnerAndSignalsOrigins(interest_group.owner, - cached_signals_origin)); const char kConfigTemplate[] = R"({ seller: $1, @@ -23965,6 +23961,26 @@ component_seller_script, interest_group.owner, url::Origin::Create(embedded_https_test_server().GetURL("b.test", "/"))); + // Run an auction so that a.test will be cached. + { + base::HistogramTester histogram_tester; + auto result = RunAuctionAndWait(auction_config); + histogram_tester.ExpectUniqueSample("Ads.InterestGroup.Auction.Result", + AuctionResult::kNoBids, 1); + histogram_tester.ExpectUniqueSample( + "Ads.InterestGroup.Auction.Seller.RequestWorkletServiceOutcome", + AuctionProcessManager::RequestWorkletServiceOutcome:: + kCreatedNewDedicatedProcess, + 2); + histogram_tester.ExpectUniqueSample( + "Ads.InterestGroup.Auction.Buyer.RequestWorkletServiceOutcome", + AuctionProcessManager::RequestWorkletServiceOutcome:: + kCreatedNewDedicatedProcess, + 1); + EXPECT_TRUE(manager_->GetCachedOwnerAndSignalsOrigins( + interest_group.owner, cached_signals_origin)); + } + // Run the auction. // // 1. a.test, the first buyer, is cached. That means we should start an @@ -23977,18 +23993,21 @@ // // Overall there will be 1 anticipatory process started and 3 worklets // requested. - base::HistogramTester histogram_tester; - auto result = RunAuctionAndWait(auction_config); - histogram_tester.ExpectUniqueSample("Ads.InterestGroup.Auction.Result", - AuctionResult::kNoBids, 1); - histogram_tester.ExpectUniqueSample( - "Ads.InterestGroup.Auction.Seller.RequestWorkletServiceOutcome", - AuctionProcessManager::RequestWorkletServiceOutcome:: - kCreatedNewDedicatedProcess, - 2); - histogram_tester.ExpectUniqueSample( - "Ads.InterestGroup.Auction.Buyer.RequestWorkletServiceOutcome", - AuctionProcessManager::RequestWorkletServiceOutcome::kUsedIdleProcess, 1); + { + base::HistogramTester histogram_tester; + auto result = RunAuctionAndWait(auction_config); + histogram_tester.ExpectUniqueSample("Ads.InterestGroup.Auction.Result", + AuctionResult::kNoBids, 1); + histogram_tester.ExpectUniqueSample( + "Ads.InterestGroup.Auction.Seller.RequestWorkletServiceOutcome", + AuctionProcessManager::RequestWorkletServiceOutcome:: + kCreatedNewDedicatedProcess, + 2); + histogram_tester.ExpectUniqueSample( + "Ads.InterestGroup.Auction.Buyer.RequestWorkletServiceOutcome", + AuctionProcessManager::RequestWorkletServiceOutcome::kUsedIdleProcess, + 1); + } } class AuctionConfigReportingTimeoutEnabledTest @@ -26603,13 +26622,16 @@ // Join the interest group with no ads so that when we run an auction, it will // get filtered after it's loaded -- but we'll still preconnect to the server. - // This join will cache the bidding signals and owner origins. + // Loading the interest group and running UpdateCachedOriginsIfEnabled will + // cache the bidding signals and owner origins. blink::InterestGroup interest_group_without_ads = interest_group; interest_group_without_ads.ads = std::nullopt; AttachInterestGroupObserver(); manager_->JoinInterestGroup(interest_group_without_ads, joining_url); WaitForAccessObserved({{"global", TestInterestGroupObserver::kJoin, interest_group_without_ads.owner, "interest_group"}}); + GetInterestGroupsForOwner(interest_group.owner); + manager_->UpdateCachedOriginsIfEnabled(interest_group.owner); std::optional<url::Origin> cached_signals_origin; EXPECT_TRUE(manager_->GetCachedOwnerAndSignalsOrigins( interest_group_without_ads.owner, cached_signals_origin));
diff --git a/content/browser/interest_group/interest_group_caching_storage.cc b/content/browser/interest_group/interest_group_caching_storage.cc index 1641a84a..20b12fac 100644 --- a/content/browser/interest_group/interest_group_caching_storage.cc +++ b/content/browser/interest_group/interest_group_caching_storage.cc
@@ -195,6 +195,32 @@ return true; } +void InterestGroupCachingStorage::UpdateCachedOriginsIfEnabled( + const url::Origin& owner) { + if (!base::FeatureList::IsEnabled(features::kFledgeUsePreconnectCache) && + !base::FeatureList::IsEnabled( + features::kFledgeStartAnticipatoryProcesses)) { + return; + } + + auto cached_groups_it = cached_interest_groups_.find(owner); + if (cached_groups_it == cached_interest_groups_.end()) { + return; + } + scoped_refptr<StorageInterestGroups> groups = cached_groups_it->second.get(); + if (groups->IsExpired() || groups->size() == 0) { + return; + } + + CachedOriginsInfo cached_origins_info; + for (const StorageInterestGroup& group : groups->storage_interest_groups_) { + if (group.interest_group.expiry > cached_origins_info.expiry) { + cached_origins_info = CachedOriginsInfo(group.interest_group); + } + } + cached_owners_and_signals_origins_[owner] = std::move(cached_origins_info); +} + void InterestGroupCachingStorage::JoinInterestGroup( const blink::InterestGroup& group, const GURL& main_frame_joining_url, @@ -535,13 +561,9 @@ auto it = cached_owners_and_signals_origins_.find(owner); if (it != cached_owners_and_signals_origins_.end()) { if (it->second.interest_group_name == - cached_origins_info.interest_group_name || - it->second.expiry < cached_origins_info.expiry) { + cached_origins_info.interest_group_name) { it->second = std::move(cached_origins_info); } - } else { - cached_owners_and_signals_origins_[owner] = - std::move(cached_origins_info); } } std::move(callback).Run(std::move(update)); @@ -557,8 +579,6 @@ return; } - UpdateCachedOriginsIfEnabled(owner, interest_groups); - scoped_refptr<StorageInterestGroups> interest_groups_ptr = base::MakeRefCounted<StorageInterestGroups>(std::move(interest_groups)); @@ -621,25 +641,4 @@ weak_factory_.GetWeakPtr(), owner, groups)); } -void InterestGroupCachingStorage::UpdateCachedOriginsIfEnabled( - const url::Origin& owner, - const std::vector<StorageInterestGroup>& interest_groups) { - if (!base::FeatureList::IsEnabled(features::kFledgeUsePreconnectCache) && - !base::FeatureList::IsEnabled( - features::kFledgeStartAnticipatoryProcesses)) { - return; - } - if (interest_groups.empty()) { - cached_owners_and_signals_origins_.erase(owner); - return; - } - CachedOriginsInfo cached_origins_info; - for (const StorageInterestGroup& group : interest_groups) { - if (group.interest_group.expiry > cached_origins_info.expiry) { - cached_origins_info = CachedOriginsInfo(group.interest_group); - } - } - cached_owners_and_signals_origins_[owner] = std::move(cached_origins_info); -} - } // namespace content
diff --git a/content/browser/interest_group/interest_group_caching_storage.h b/content/browser/interest_group/interest_group_caching_storage.h index d7d363bb..35add7dc 100644 --- a/content/browser/interest_group/interest_group_caching_storage.h +++ b/content/browser/interest_group/interest_group_caching_storage.h
@@ -141,23 +141,27 @@ base::OnceCallback<void(scoped_refptr<StorageInterestGroups>)> callback); // For a given `owner`, return whether the owner origin and bidding signal - // origin were cached in-memory in previous calls to - // GetInterestGroupsForOwner and JoinInterestGroup. If the `owner` origin was - // cached, update `signals_origin` to the one that was cached -- or set to - // nullopt if no bidding signals origin was cached or if it would be the same - // as the owner origin. The cache includes at most one entry per origin, and - // may not reflect the results of interest group updates. It's intended to be - // used for best-effort preconnecting, and should not be considered - // authoritative. It is guaranteed not to contain interest groups that have - // are beyond the max expiration time limit, so preconnecting should not leak - // data the bidder would otherwise have access to, if it so desired. That is, - // manual voluntarily removing or expiring of an interest group may not be - // reflected in the result, but hitting the the global interest group lifetime - // cap will be respected. + // origin were cached in-memory via UpdateCachedOriginsIfEnabled. + // If the `owner` origin was cached, update `signals_origin` to the one that + // was cached -- or set to nullopt if no bidding signals origin was cached or + // if it would be the same as the owner origin. The cache includes at most one + // entry per origin, and may not reflect the results of interest group + // updates. It's intended to be used for best-effort preconnecting, and should + // not be considered authoritative. It is guaranteed not to contain interest + // groups that have are beyond the max expiration time limit, so preconnecting + // should not leak data the bidder would otherwise have access to, if it so + // desired. That is, manual voluntarily removing or expiring of an interest + // group may not be reflected in the result, but hitting the the global + // interest group lifetime cap will be respected. bool GetCachedOwnerAndSignalsOrigins( const url::Origin& owner, std::optional<url::Origin>& signals_origin); + // Update the cached owner and signal origins for an owner's interest groups + // if kFledgeUsePreconnectCache or kFledgeStartAnticipatoryProcesses are + // enabled and the owner's IGs are still in memory. + void UpdateCachedOriginsIfEnabled(const url::Origin& owner); + // Joins an interest group. If the interest group does not exist, a new one // is created based on the provided group information. If the interest group // exists, the existing interest group is overwritten. In either case a join @@ -320,8 +324,8 @@ base::RepeatingCallback<void(base::Time)> callback) const; private: - // Once JoinInterestGroup completes successfully, maybe cache the associated - // CachedOriginsInfo and run the callback. + // Once JoinInterestGroup completes successfully, maybe update the cached + // origins and run the callback. void OnJoinInterestGroup( const url::Origin& owner, CachedOriginsInfo cached_origins_info, @@ -361,12 +365,6 @@ timed_holds_of_interest_groups_.erase(owner); } - // Update `cached_owners_and_signals_origins_` for an owner's interest groups - // if kFledgeUsePreconnectCache is enabled. - void UpdateCachedOriginsIfEnabled( - const url::Origin& owner, - const std::vector<StorageInterestGroup>& interest_groups); - base::SequenceBound<InterestGroupStorage> interest_group_storage_; // Used to retrieve interest groups that are still in memory (e.g. because @@ -396,14 +394,14 @@ // interest_groups_sequenced_callbacks_ becomes empty. std::map<url::Origin, uint32_t> valid_interest_group_versions_; - // For each owner for which we've loaded or joined interest groups, - // hold onto the owner origin and origin of the bidding signals url for the - // purpose of preconnecting to them in later auctions. CachedOriginsInfo - // tracks the latest expiring interest group that we know about to prevent - // preconnecting to origins no longer in the database. Owners may be cleared - // from the map if the corresponding interest group is left or expired. - // A flat map is used because the number of interest group owners is expected - // to be relatively small. + // For each owner for which we've run UpdateCachedOriginsIfEnabled, + // hold onto the owner origin and the origin of the bidding signals url for + // the purpose of preconnecting to them or starting worklets for them in later + // auctions. CachedOriginsInfo tracks the latest expiring interest group that + // we know about to prevent preconnecting to origins no longer in the + // database. Owners may be cleared from the map if the corresponding interest + // group is left or expired. A flat map is used because the number of interest + // group owners is expected to be relatively small. base::flat_map<url::Origin, CachedOriginsInfo> cached_owners_and_signals_origins_;
diff --git a/content/browser/interest_group/interest_group_caching_storage_unittest.cc b/content/browser/interest_group/interest_group_caching_storage_unittest.cc index 59ad059..e9ec1a2d 100644 --- a/content/browser/interest_group/interest_group_caching_storage_unittest.cc +++ b/content/browser/interest_group/interest_group_caching_storage_unittest.cc
@@ -63,6 +63,12 @@ return result; } + void UpdateCachedOrigins(InterestGroupCachingStorage* caching_storage, + const url::Origin& owner) { + GetInterestGroupsForOwner(caching_storage, owner); + caching_storage->UpdateCachedOriginsIfEnabled(owner); + } + std::optional<SingleStorageInterestGroup> GetInterestGroup( InterestGroupCachingStorage* caching_storage, const blink::InterestGroupKey& group_key) { @@ -858,27 +864,40 @@ GURL test_url("https://www.test.test"); - // Join an interest group without a bidding signals url. + // We shouldn't be able to cache owners which aren't in the + // database. + UpdateCachedOrigins(caching_storage.get(), owner1); + ASSERT_FALSE(caching_storage->GetCachedOwnerAndSignalsOrigins( + owner1, loaded_signals_origin)); + ASSERT_FALSE(loaded_signals_origin); + + // Join an interest group without a bidding signals url. We should be able to + // cache the owner. JoinInterestGroup(caching_storage.get(), ig1, test_url); + UpdateCachedOrigins(caching_storage.get(), owner1); ASSERT_TRUE(caching_storage->GetCachedOwnerAndSignalsOrigins( owner1, loaded_signals_origin)); ASSERT_FALSE(loaded_signals_origin); - // Join an interest group with a bidding signals url (different origin). + // Join an interest group with a bidding signals url (different origin as the + // owner). task_environment_.FastForwardBy(base::Minutes(1)); blink::InterestGroup ig2 = MakeInterestGroup(owner1, "2"); ig2.trusted_bidding_signals_url = GURL("https://www.other.test"); JoinInterestGroup(caching_storage.get(), ig2, test_url); + UpdateCachedOrigins(caching_storage.get(), owner1); ASSERT_TRUE(caching_storage->GetCachedOwnerAndSignalsOrigins( owner1, loaded_signals_origin)); ASSERT_EQ(loaded_signals_origin, url::Origin::Create(*ig2.trusted_bidding_signals_url)); - // Join an interest group with a bidding signals url (same origin). + // Join an interest group with a bidding signals url (same origin as the + // owner). task_environment_.FastForwardBy(base::Minutes(1)); blink::InterestGroup ig3 = MakeInterestGroup(owner1, "3"); ig3.trusted_bidding_signals_url = owner1.GetURL(); JoinInterestGroup(caching_storage.get(), ig3, test_url); + UpdateCachedOrigins(caching_storage.get(), owner1); ASSERT_TRUE(caching_storage->GetCachedOwnerAndSignalsOrigins( owner1, loaded_signals_origin)); ASSERT_FALSE(loaded_signals_origin); @@ -893,6 +912,7 @@ ig4.expiry = ig3.expiry + base::Minutes(3); ig4.trusted_bidding_signals_url = GURL("https://www.other.test"); JoinInterestGroup(caching_storage.get(), ig4, test_url); + UpdateCachedOrigins(caching_storage.get(), owner2); InterestGroupCachingStorage::CachedOriginsInfo expected_owner2_cached_info( ig4); @@ -912,6 +932,7 @@ ig5.name = "5"; ig5.expiry = ig3.expiry; JoinInterestGroup(caching_storage.get(), ig5, test_url); + UpdateCachedOrigins(caching_storage.get(), owner2); ASSERT_TRUE(caching_storage->GetCachedOwnerAndSignalsOrigins( owner1, loaded_signals_origin)); ASSERT_FALSE(loaded_signals_origin); @@ -975,6 +996,7 @@ task_environment_.FastForwardBy(base::Seconds(1)); blink::InterestGroup ig8 = MakeInterestGroup(owner1, "8"); JoinInterestGroup(caching_storage.get(), ig8, test_url); + UpdateCachedOrigins(caching_storage.get(), owner1); ASSERT_TRUE(caching_storage->GetCachedOwnerAndSignalsOrigins( owner1, loaded_signals_origin)); ASSERT_FALSE(loaded_signals_origin); @@ -1010,6 +1032,7 @@ // We can get this cache again from an IG load. The signals URL reflects // the update to ig8. groups = GetInterestGroupsForOwner(caching_storage.get(), owner1); + UpdateCachedOrigins(caching_storage.get(), owner1); ASSERT_TRUE(caching_storage->GetCachedOwnerAndSignalsOrigins( owner1, loaded_signals_origin)); ASSERT_EQ(loaded_signals_origin, @@ -1032,9 +1055,11 @@ ASSERT_FALSE(caching_storage->GetCachedOwnerAndSignalsOrigins( owner1, loaded_signals_origin)); - // We can get the cache again by loading IGs because there were other interest - // groups with the same owner. Now the latest expiring IG will be ig7. + // We can get the cache again by loading IGs + running + // UpdateCachedOriginsIfEnabled because there were other interest groups with + // the same owner. Now the latest expiring IG will be ig7. groups = GetInterestGroupsForOwner(caching_storage.get(), owner1); + UpdateCachedOrigins(caching_storage.get(), owner1); ASSERT_TRUE(groups.has_value()); ASSERT_GT(groups.value()->size(), 0u); ASSERT_TRUE(caching_storage->GetCachedOwnerAndSignalsOrigins( @@ -1063,11 +1088,26 @@ // When the latest expiring interest group expires, the cache does too. blink::InterestGroup ig9 = MakeInterestGroup(owner1, "9"); JoinInterestGroup(caching_storage.get(), ig9, test_url); + UpdateCachedOrigins(caching_storage.get(), owner1); ASSERT_TRUE(caching_storage->GetCachedOwnerAndSignalsOrigins( owner1, loaded_signals_origin)); task_environment_.FastForwardBy(base::Days(1) + base::Minutes(2)); ASSERT_FALSE(caching_storage->GetCachedOwnerAndSignalsOrigins( owner1, loaded_signals_origin)); + + // When we join the same interest group twice, the earlier expiry is + // respected. + blink::InterestGroup ig10 = MakeInterestGroup(owner1, "10"); + JoinInterestGroup(caching_storage.get(), ig10, test_url); + UpdateCachedOrigins(caching_storage.get(), owner1); + ig10.expiry = ig10.expiry - base::Minutes(1); + ASSERT_TRUE(caching_storage->GetCachedOwnerAndSignalsOrigins( + owner1, loaded_signals_origin)); + JoinInterestGroup(caching_storage.get(), ig10, test_url); + task_environment_.FastForwardBy(base::Days(1) - base::Minutes(1) + + base::Milliseconds(1)); + ASSERT_FALSE(caching_storage->GetCachedOwnerAndSignalsOrigins( + owner1, loaded_signals_origin)); } } // namespace content
diff --git a/content/browser/interest_group/interest_group_manager_impl.cc b/content/browser/interest_group/interest_group_manager_impl.cc index 87bb423..02e30f8 100644 --- a/content/browser/interest_group/interest_group_manager_impl.cc +++ b/content/browser/interest_group/interest_group_manager_impl.cc
@@ -531,6 +531,11 @@ signals_origin); } +void InterestGroupManagerImpl::UpdateCachedOriginsIfEnabled( + const url::Origin& owner) { + caching_storage_.UpdateCachedOriginsIfEnabled(owner); +} + void InterestGroupManagerImpl::DeleteInterestGroupData( StoragePartition::StorageKeyMatcherFunction storage_key_matcher, base::OnceClosure completion_callback) {
diff --git a/content/browser/interest_group/interest_group_manager_impl.h b/content/browser/interest_group/interest_group_manager_impl.h index 4f8e680..29e6757 100644 --- a/content/browser/interest_group/interest_group_manager_impl.h +++ b/content/browser/interest_group/interest_group_manager_impl.h
@@ -304,23 +304,27 @@ base::OnceCallback<void(scoped_refptr<StorageInterestGroups>)> callback); // For a given `owner`, return whether the owner origin and bidding signal - // origin were cached in-memory in previous calls to - // GetInterestGroupsForOwner and JoinInterestGroup. If the `owner` origin was - // cached, update `signals_origin` to the one that was cached -- or set to - // nullopt if no bidding signals origin was cached or if it would be the same - // as the owner origin. The cache includes at most one entry per origin, and - // may not reflect the results of interest group updates. It's intended to be - // used for best-effort preconnecting, and should not be considered - // authoritative. It is guaranteed not to contain interest groups that have - // are beyond the max expiration time limit, so preconnecting should not leak - // data the bidder would otherwise have access to, if it so desired. That is, - // manual voluntarily removing or expiring of an interest group may not be - // reflected in the result, but hitting the the global interest group lifetime - // cap will be respected. + // origin were cached in-memory via UpdateCachedOriginsIfEnabled. If the + // `owner` origin was cached, update `signals_origin` to the one that was + // cached -- or set to nullopt if no bidding signals origin was cached or if + // it would be the same as the owner origin. The cache includes at most one + // entry per origin, and may not reflect the results of interest group + // updates. It's intended to be used for best-effort preconnecting, and should + // not be considered authoritative. It is guaranteed not to contain interest + // groups that have are beyond the max expiration time limit, so preconnecting + // should not leak data the bidder would otherwise have access to, if it so + // desired. That is, manual voluntarily removing or expiring of an interest + // group may not be reflected in the result, but hitting the the global + // interest group lifetime cap will be respected. bool GetCachedOwnerAndSignalsOrigins( const url::Origin& owner, std::optional<url::Origin>& signals_origin); + // Update the cached owner and signal origins for an owner's interest groups + // if kFledgeUsePreconnectCache or kFledgeStartAnticipatoryProcesses are + // enabled and the owner's IGs are still in memory. + void UpdateCachedOriginsIfEnabled(const url::Origin& owner); + // Clear out storage for the matching owning storage key. If the matcher is // empty then apply to all storage keys. void DeleteInterestGroupData(
diff --git a/content/browser/launch_as_mojo_client_browsertest.cc b/content/browser/launch_as_mojo_client_browsertest.cc index 30169a1..c8097d4 100644 --- a/content/browser/launch_as_mojo_client_browsertest.cc +++ b/content/browser/launch_as_mojo_client_browsertest.cc
@@ -13,7 +13,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/variations/field_trial_config/field_trial_util.h" #include "components/variations/variations_switches.h" #include "content/public/common/content_switches.h" @@ -30,7 +29,7 @@ #include "ui/ozone/public/ozone_switches.h" #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(MEMORY_SANITIZER) +#if BUILDFLAG(IS_CHROMEOS) || defined(MEMORY_SANITIZER) #include "ui/gl/gl_switches.h" #endif @@ -76,7 +75,7 @@ command_line.CopySwitchesFrom(cmdline, kSwitchesToCopy); #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) command_line.AppendSwitchASCII(switches::kUseGL, gl::kGLImplementationANGLEName); command_line.AppendSwitchASCII(switches::kUseANGLE,
diff --git a/content/browser/loader/cors_file_origin_browsertest.cc b/content/browser/loader/cors_file_origin_browsertest.cc index c7486b333..e6d3e7a 100644 --- a/content/browser/loader/cors_file_origin_browsertest.cc +++ b/content/browser/loader/cors_file_origin_browsertest.cc
@@ -14,7 +14,6 @@ #include "base/synchronization/waitable_event.h" #include "base/test/scoped_command_line.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_paths.h"
diff --git a/content/browser/manifest/manifest_browsertest.cc b/content/browser/manifest/manifest_browsertest.cc index d89ac67c..71aaa68 100644 --- a/content/browser/manifest/manifest_browsertest.cc +++ b/content/browser/manifest/manifest_browsertest.cc
@@ -19,7 +19,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/public/browser/page.h" #include "content/public/browser/render_frame_host.h"
diff --git a/content/browser/media/audio_input_stream_broker.cc b/content/browser/media/audio_input_stream_broker.cc index 0e4b468d..22d5ed1d 100644 --- a/content/browser/media/audio_input_stream_broker.cc +++ b/content/browser/media/audio_input_stream_broker.cc
@@ -14,7 +14,6 @@ #include "base/metrics/histogram_macros.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/browser_main_loop.h" #include "content/browser/media/audio_stream_broker_helper.h" #include "content/browser/media/media_internals.h"
diff --git a/content/browser/media/audio_stream_monitor_unittest.cc b/content/browser/media/audio_stream_monitor_unittest.cc index 2abe07f..727c80b5 100644 --- a/content/browser/media/audio_stream_monitor_unittest.cc +++ b/content/browser/media/audio_stream_monitor_unittest.cc
@@ -12,7 +12,6 @@ #include "base/functional/callback_helpers.h" #include "base/memory/raw_ptr.h" #include "base/time/time.h" -#include "build/chromeos_buildflags.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/invalidate_type.h" #include "content/public/browser/web_contents_delegate.h"
diff --git a/content/browser/media/capture/aura_window_video_capture_device.cc b/content/browser/media/capture/aura_window_video_capture_device.cc index 45dd780..65eeb6f7 100644 --- a/content/browser/media/capture/aura_window_video_capture_device.cc +++ b/content/browser/media/capture/aura_window_video_capture_device.cc
@@ -14,7 +14,6 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/task/single_thread_task_runner.h" -#include "build/chromeos_buildflags.h" #include "content/browser/media/capture/mouse_cursor_overlay_controller.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h"
diff --git a/content/browser/media/capture/aura_window_video_capture_device.h b/content/browser/media/capture/aura_window_video_capture_device.h index b739cfd..3081c8e8 100644 --- a/content/browser/media/capture/aura_window_video_capture_device.h +++ b/content/browser/media/capture/aura_window_video_capture_device.h
@@ -9,7 +9,6 @@ #include "base/memory/weak_ptr.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/media/capture/frame_sink_video_capture_device.h" #include "content/common/content_export.h" #include "content/public/browser/browser_thread.h"
diff --git a/content/browser/media/capture/aura_window_video_capture_device_browsertest.cc b/content/browser/media/capture/aura_window_video_capture_device_browsertest.cc index 5860f468..661e70b8 100644 --- a/content/browser/media/capture/aura_window_video_capture_device_browsertest.cc +++ b/content/browser/media/capture/aura_window_video_capture_device_browsertest.cc
@@ -9,7 +9,6 @@ #include "base/run_loop.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/test/pixel_test_utils.h" #include "components/viz/common/features.h" #include "content/browser/media/capture/content_capture_device_browsertest_base.h" @@ -338,7 +337,7 @@ } #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Disabled (https://crbug.com/1096946) // On ChromeOS, another window may occlude a window that is being captured. // Make sure the visibility is set to visible during capture if it's occluded. @@ -362,7 +361,7 @@ window.reset(); StopAndDeAllocate(); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) class AuraWindowVideoCaptureDeviceBrowserTestP : public AuraWindowVideoCaptureDeviceBrowserTest, @@ -376,7 +375,7 @@ } }; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) INSTANTIATE_TEST_SUITE_P( All, AuraWindowVideoCaptureDeviceBrowserTestP, @@ -393,7 +392,7 @@ true /* software compositing */), testing::Values(false /* variable aspect ratio */, true /* fixed aspect ratio */))); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) // Disabled (https://crbug.com/1096946) // Tests that the device successfully captures a series of content changes,
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc index fba9bdf..3ba87e5 100644 --- a/content/browser/media/capture/desktop_capture_device.cc +++ b/content/browser/media/capture/desktop_capture_device.cc
@@ -30,7 +30,6 @@ #include "base/timer/timer.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/media/capture/desktop_capture_device_uma_types.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h"
diff --git a/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc b/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc index c45dda87..6aa87c8 100644 --- a/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc +++ b/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc
@@ -13,7 +13,6 @@ #include "base/memory/raw_ptr.h" #include "base/memory/read_only_shared_memory_region.h" #include "base/memory/shared_memory_mapping.h" -#include "build/chromeos_buildflags.h" #include "components/viz/common/surfaces/region_capture_bounds.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h"
diff --git a/content/browser/media/capture/mouse_cursor_overlay_controller_browsertest.cc b/content/browser/media/capture/mouse_cursor_overlay_controller_browsertest.cc index 8ca8c30..03385a2 100644 --- a/content/browser/media/capture/mouse_cursor_overlay_controller_browsertest.cc +++ b/content/browser/media/capture/mouse_cursor_overlay_controller_browsertest.cc
@@ -7,7 +7,6 @@ #include "base/run_loop.h" #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_tick_clock.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" @@ -23,10 +22,10 @@ #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size_f.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "ui/aura/client/cursor_shape_client.h" #include "ui/wm/core/cursor_loader.h" // nogncheck -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) using ::testing::Mock; @@ -91,10 +90,10 @@ // On Ash content browsertests, ash::Shell isn't initialized and thus // neither NativeCursorManagerAsh, the owner of CursorLoader. -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) cursor_loader_ = std::make_unique<wm::CursorLoader>(); aura::client::SetCursorShapeClient(cursor_loader_.get()); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) controller_.SetTargetView(shell()->web_contents()->GetNativeView()); controller_.DisconnectFromToolkitForTesting(); @@ -246,7 +245,7 @@ MouseCursorOverlayController controller_; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) std::unique_ptr<wm::CursorLoader> cursor_loader_; #endif };
diff --git a/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc b/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc index e9e09d1a..dc0b606 100644 --- a/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc +++ b/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
@@ -13,7 +13,6 @@ #include "base/strings/stringprintf.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/test/pixel_test_utils.h" #include "content/browser/media/capture/content_capture_device_browsertest_base.h" #include "content/browser/media/capture/fake_video_capture_stack.h" @@ -605,7 +604,7 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) INSTANTIATE_TEST_SUITE_P( All, WebContentsVideoCaptureDeviceBrowserTestP, @@ -660,7 +659,7 @@ // TODO(crbug/329654821): Also flaky for ChromeOS ASAN LSAN and debug. #if defined(MEMORY_SANITIZER) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ (BUILDFLAG(IS_CHROMEOS) && defined(ADDRESS_SANITIZER)) || \ - (BUILDFLAG(IS_CHROMEOS_ASH) && !defined(NDEBUG)) + (BUILDFLAG(IS_CHROMEOS) && !defined(NDEBUG)) #define MAYBE_CapturesContentChanges DISABLED_CapturesContentChanges #else #define MAYBE_CapturesContentChanges CapturesContentChanges
diff --git a/content/browser/media/cdm_registry_impl.cc b/content/browser/media/cdm_registry_impl.cc index 539a6b4..34f5f393b 100644 --- a/content/browser/media/cdm_registry_impl.cc +++ b/content/browser/media/cdm_registry_impl.cc
@@ -17,7 +17,6 @@ #include "base/types/expected.h" #include "base/types/optional_util.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/common/cdm_info.h" #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h"
diff --git a/content/browser/media/cdm_registry_impl_unittest.cc b/content/browser/media/cdm_registry_impl_unittest.cc index 4402ff64..b9799af 100644 --- a/content/browser/media/cdm_registry_impl_unittest.cc +++ b/content/browser/media/cdm_registry_impl_unittest.cc
@@ -28,7 +28,6 @@ #include "base/test/scoped_feature_list.h" #include "base/types/expected.h" #include "base/version.h" -#include "build/chromeos_buildflags.h" #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/public/common/cdm_info.h" #include "content/public/test/browser_task_environment.h"
diff --git a/content/browser/media/media_browsertest.cc b/content/browser/media/media_browsertest.cc index 006b0aa..39d6dd7 100644 --- a/content/browser/media/media_browsertest.cc +++ b/content/browser/media/media_browsertest.cc
@@ -11,7 +11,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/gpu_utils.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h"
diff --git a/content/browser/media/media_color_browsertest.cc b/content/browser/media/media_color_browsertest.cc index a4fcee2..3885c28e 100644 --- a/content/browser/media/media_color_browsertest.cc +++ b/content/browser/media/media_color_browsertest.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/media/media_browsertest.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h"
diff --git a/content/browser/media/media_interface_proxy.cc b/content/browser/media/media_interface_proxy.cc index 2153e46..357d53a 100644 --- a/content/browser/media/media_interface_proxy.cc +++ b/content/browser/media/media_interface_proxy.cc
@@ -18,7 +18,6 @@ #include "base/time/time.h" #include "base/unguessable_token.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/media/cdm_storage_common.h" #include "content/browser/renderer_host/render_frame_host_delegate.h" #include "content/browser/renderer_host/render_frame_host_impl.h"
diff --git a/content/browser/media/media_interface_proxy.h b/content/browser/media/media_interface_proxy.h index 414cb62c..9e601d5 100644 --- a/content/browser/media/media_interface_proxy.h +++ b/content/browser/media/media_interface_proxy.h
@@ -13,7 +13,6 @@ #include "base/threading/thread_checker.h" #include "base/unguessable_token.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/media/media_interface_factory_holder.h" #include "content/public/browser/document_user_data.h" #include "content/public/common/cdm_info.h"
diff --git a/content/browser/media/media_keys_listener_manager_impl.cc b/content/browser/media/media_keys_listener_manager_impl.cc index 96c0aa8..e87c180 100644 --- a/content/browser/media/media_keys_listener_manager_impl.cc +++ b/content/browser/media/media_keys_listener_manager_impl.cc
@@ -10,7 +10,6 @@ #include "base/metrics/histogram_functions.h" #include "base/observer_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/system_media_controls/system_media_controls.h" #include "content/browser/browser_main_loop.h" #include "content/browser/media/active_media_session_controller.h"
diff --git a/content/browser/media/media_keys_listener_manager_impl_browsertest.cc b/content/browser/media/media_keys_listener_manager_impl_browsertest.cc index dc9264a..3229ec2 100644 --- a/content/browser/media/media_keys_listener_manager_impl_browsertest.cc +++ b/content/browser/media/media_keys_listener_manager_impl_browsertest.cc
@@ -7,7 +7,6 @@ #include "base/containers/flat_set.h" #include "base/memory/raw_ptr.h" #include "base/test/scoped_feature_list.h" -#include "build/chromeos_buildflags.h" #include "content/browser/browser_main_loop.h" #include "content/browser/media/active_media_session_controller.h" #include "content/public/test/browser_test.h"
diff --git a/content/browser/media/session/media_session_browsertest.cc b/content/browser/media/session/media_session_browsertest.cc index 8ca12ca..46edf62 100644 --- a/content/browser/media/session/media_session_browsertest.cc +++ b/content/browser/media/session/media_session_browsertest.cc
@@ -14,7 +14,6 @@ #include "base/synchronization/lock.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h"
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc index 5941763..897773e6 100644 --- a/content/browser/media/session/media_session_impl.cc +++ b/content/browser/media/session/media_session_impl.cc
@@ -836,6 +836,10 @@ GetVolumeMultiplier()); } + for (const auto& it : one_shot_players_) { + it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier()); + } + for (const auto& it : pepper_players_) it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier()); }
diff --git a/content/browser/media/session/media_session_impl_browsertest.cc b/content/browser/media/session/media_session_impl_browsertest.cc index 4d11caf2..d09f5c28 100644 --- a/content/browser/media/session/media_session_impl_browsertest.cc +++ b/content/browser/media/session/media_session_impl_browsertest.cc
@@ -21,7 +21,6 @@ #include "base/test/simple_test_tick_clock.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/media/session/audio_focus_delegate.h" #include "content/browser/media/session/mock_media_session_player_observer.h" #include "content/browser/media/session/mock_media_session_service_impl.h" @@ -3041,7 +3040,7 @@ } } -#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) // TODO(crbug.com/40097218): Re-enable this test. #define MAYBE_PositionStateRouteWithOnePlayer \ DISABLED_PositionStateRouteWithOnePlayer
diff --git a/content/browser/media/stable_video_decoder_factory.cc b/content/browser/media/stable_video_decoder_factory.cc index 8dee2eb..76298c00 100644 --- a/content/browser/media/stable_video_decoder_factory.cc +++ b/content/browser/media/stable_video_decoder_factory.cc
@@ -10,7 +10,6 @@ #include "content/public/browser/stable_video_decoder_factory.h" #include "base/containers/queue.h" -#include "build/chromeos_buildflags.h" #include "components/viz/common/switches.h" #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/public/browser/browser_task_traits.h"
diff --git a/content/browser/network/trust_token_browsertest.cc b/content/browser/network/trust_token_browsertest.cc index a3fc4ade..c0eea90 100644 --- a/content/browser/network/trust_token_browsertest.cc +++ b/content/browser/network/trust_token_browsertest.cc
@@ -11,7 +11,6 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/test/bind.h" -#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/network_service_instance.h" @@ -24,7 +23,6 @@ #include "content/public/test/url_loader_monitor.h" #include "content/shell/browser/shell.h" #include "net/dns/mock_host_resolver.h" -#include "services/network/public/cpp/features.h" #include "services/network/public/cpp/is_potentially_trustworthy.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/trust_token_http_headers.h" @@ -93,15 +91,7 @@ } // namespace -TrustTokenBrowsertest::TrustTokenBrowsertest() { - auto& field_trial_param = - network::features::kTrustTokenOperationsRequiringOriginTrial; - features_.InitAndEnableFeatureWithParameters( - network::features::kPrivateStateTokens, - {{field_trial_param.name, - field_trial_param.GetName(network::features::TrustTokenOriginTrialSpec:: - kOriginTrialNotRequired)}}); -} +TrustTokenBrowsertest::TrustTokenBrowsertest() = default; void TrustTokenBrowsertest::SetUpOnMainThread() { host_resolver()->AddRule("*", "127.0.0.1");
diff --git a/content/browser/network/trust_token_origin_trial_browsertest.cc b/content/browser/network/trust_token_origin_trial_browsertest.cc deleted file mode 100644 index d025769..0000000 --- a/content/browser/network/trust_token_origin_trial_browsertest.cc +++ /dev/null
@@ -1,394 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/string_util.h" -#include "base/test/bind.h" -#include "base/test/scoped_feature_list.h" -#include "base/thread_annotations.h" -#include "content/public/test/browser_test.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/content_browser_test.h" -#include "content/public/test/content_browser_test_utils.h" -#include "content/public/test/url_loader_monitor.h" -#include "content/shell/browser/shell.h" -#include "services/network/public/cpp/features.h" -#include "services/network/public/cpp/resource_request.h" -#include "services/network/public/mojom/trust_tokens.mojom.h" -#include "services/network/test/trust_token_test_util.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -// These integration tests cover the interaction between the Trust Token API's -// Fetch and iframe surfaces and various configuration requiring Origin Trial -// tokens to execute some or all of the Trust Tokens operations (issuance, -// redemption, and signing). -// -// There are two configuration modes: -// - "third-party origin trial": all Trust Tokens operations require an origin -// trial token to execute and, if a token is missing, the Trust Tokens interface -// disppears so that attempts to execute operations will silently no-op. This is -// because the Trust Tokens interface manifests itself as an additional argument -// in fetch's RequestInit dictionary, which does not throw errors when -// unexpected arguments are provided. -// - "standard origin trial": only Trust Tokens issuance requires an origin -// trial token to execute and, if a token is missing, issuance will fail. -// -// As an example, consider -// -// fetch("https://chromium.org", { -// privateToken: { -// version: 1, -// operation: 'token-request'}}) -// -// a representative fetch with an associated Trust Tokens issuance operation. -// When Trust Tokens is completely disabled (e.g. "third-party origin trial" -// mode with no token), the trustToken argument will be ignored. On the other -// hand, when Trust Tokens is enabled but issuance is forbidden ("standard -// origin trial" mode with no token), this will reject with an exception. - -namespace content { - -namespace { - -using ::testing::Combine; -using ::testing::Values; -using ::testing::ValuesIn; - -// Trust Tokens has three interfaces: fetch, XHR, and iframe. However, the XHR -// and fetch interfaces use essentially identical code paths, so we exclude the -// XHR interface in order to save some test duration. -enum class Interface { - kFetch, - kIframe, -}; - -// Prints a string representation to use for generating test names. -std::string ToString(Interface interface) { - switch (interface) { - case Interface::kFetch: - return "Fetch"; - case Interface::kIframe: - return "Iframe"; - } -} - -using Op = network::mojom::TrustTokenOperationType; - -enum class Outcome { - // A request with Trust Tokens parameters should reach the network stack. - kSuccess, - // A request without Trust Tokens parameters should reach the network stack. - kSuccessWithoutTrustTokenParams, - // The Trust Tokens operation should error out. For the Fetch interface, this - // means an exception gets thrown; for the iframe interface, it means we - // continue the request with no Trust Tokens parameters (i.e., it's equivalent - // to kSuccessWithoutTrustTokenParams). - kFailure, -}; - -enum class TrialEnabled { - // The Trust Tokens operation at hand will be executed from a context with an - // origin trial token. - kEnabled, - // The Trust Tokens operation at hand will be executed from a context lacking - // an origin trial token. - kDisabled, -}; - -// Prints a string representation to use for generating test names. -std::string ToString(TrialEnabled trial_enabled) { - switch (trial_enabled) { - case TrialEnabled::kEnabled: - return "TrialEnabled"; - case TrialEnabled::kDisabled: - return "TrialDisabled"; - } -} - -using TrialType = network::features::TrustTokenOriginTrialSpec; - -// Prints a string representation to use for generating test names. -std::string ToString(TrialType trial_type) { - switch (trial_type) { - case TrialType::kAllOperationsRequireOriginTrial: - return "AllOpsNeedTrial"; - case TrialType::kOnlyIssuanceRequiresOriginTrial: - return "OnlyIssuanceNeedsTrial"; - default: - NOTREACHED(); - } -} - -struct TestDescription { - Op op; - Outcome outcome; - TrialType trial_type; - TrialEnabled trial_enabled; -}; - -class TrustTokenOriginTrialBrowsertest - : public ContentBrowserTest, - public ::testing::WithParamInterface< - std::tuple<Interface, TestDescription>> { - public: - TrustTokenOriginTrialBrowsertest() { - auto& field_trial_param = - network::features::kTrustTokenOperationsRequiringOriginTrial; - // kPrivateStateTokens ignores origin trial params - features_.InitWithFeaturesAndParameters( - {{network::features::kFledgePst, - {{field_trial_param.name, - field_trial_param.GetName(std::get<1>(GetParam()).trial_type)}}}}, - {network::features::kPrivateStateTokens}); - } - - // kPageWithOriginTrialToken is a landing page from which we execute Trust - // Tokens operations in test cases that require an origin trial token to be - // present. We use a deterministic port and swap in the landing page with - // URLLoaderInterceptor, rather than serving the page from - // EmbeddedTestServer, because the token is generated offline and bound to a - // specific origin. - const GURL kPageWithOriginTrialToken{"http://localhost:5555"}; - - // kTrustTokenUrl is the destination URL of the executed Trust Tokens - // operations. It's arbitrary, since the tests just need to intercept - // requests en route to check if they bear Trust Tokens parameters. - const GURL kTrustTokenUrl{kPageWithOriginTrialToken.Resolve("/trust-token")}; - - protected: - // OnRequest is a URLLoaderInterceptor callback. It: - // - serves the Origin Trials token when navigating to the landing page - // - quits the run loop, and stores the obtained request, when receiving a - // request to the Trust Tokens URL - // - declines to intercept otherwise (e.g. on favicon load) - // - // For the reasons discussed in |kPageWithOriginTrialToken|'s member comment, - // we need to use an interceptor to serve the landing page. Since we're - // already stuck with having an interceptor around, we use the same - // interceptor---instead of, say, registering an EmbeddedTestServer - // callback---to verify that requests sent to the Trust Tokens endpoint bear - // (or omit) Trust Tokens parameters. (This also lets us avoid having to set - // up all of the server-side logic necessary for executing a Trust Tokens - // operation end to end.) - bool OnRequest(URLLoaderInterceptor::RequestParams* params) { - if (params->url_request.url == kPageWithOriginTrialToken) { - // Origin Trials key generated with: - // - // tools/origin_trials/generate_token.py --expire-days 5000 --version 3 \ - // http://localhost:5555 TrustTokens - // - // Note that you can't have an origin trial token with expiry more than - // 2^31-1 seconds past the epoch, so (for instance) --expire-days 10000 - // would not have generated a valid token. - URLLoaderInterceptor::WriteResponse( - base::ReplaceStringPlaceholders( - "HTTP/1.1 200 OK\n" - "Content-type: text/html\n" - "Origin-Trial: $1\n\n", - {"A220DaFwmOb78vs8TojpryN1mfL9+zHjNDdo+rJTwRcaPkCIzU4/" - "vP9pnSHyI2ye8WsoxToBprvd7YH+" - "SdR0FgAAAABTeyJvcmlnaW4iOiAiaHR0cDovL2xvY2FsaG9zdDo1NTU1IiwgImZ" - "lYXR1cmUiOiAiVHJ1c3RUb2tlbnMiLCAiZXhwaXJ5IjogMjAyNTQ1OTI0MX0="}, - /*offsets=*/nullptr), - /*body=*/"", params->client.get()); - return true; - } - - if (params->url_request.url == kTrustTokenUrl) { - { - base::AutoLock lock(mutex_); - CHECK(!trust_token_request_) - << "Unexpected second Trust Tokens request"; - trust_token_request_ = params->url_request; - } - - // Write a response here so that the request doesn't fail: this is - // necessary so that tests expecting kFailure do not erroneously pass in - // cases where the request does not error out. - URLLoaderInterceptor::WriteResponse( - "HTTP/1.1 200 OK\nContent-type: text/html\n\n", /*body=*/"", - params->client.get()); - - base::OnceClosure done; - { - base::AutoLock lock(mutex_); - done = std::move(on_received_request_); - } - - std::move(done).Run(); - - return true; - } - - return false; - } - - base::test::ScopedFeatureList features_; - - // The request data is written on the IO sequence and read on the main - // sequence. - base::Lock mutex_; - - // |on_received_request_| is called once a request arrives at - // |kTrustTokenUrl|; the request is then placed in |trust_token_request_|. - base::OnceClosure on_received_request_ GUARDED_BY(mutex_); - std::optional<network::ResourceRequest> trust_token_request_ - GUARDED_BY(mutex_); -}; - -const TestDescription kTestDescriptions[] = { - {Op::kIssuance, Outcome::kSuccess, - TrialType::kOnlyIssuanceRequiresOriginTrial, TrialEnabled::kEnabled}, - - {Op::kRedemption, Outcome::kSuccess, - TrialType::kOnlyIssuanceRequiresOriginTrial, TrialEnabled::kEnabled}, - - {Op::kRedemption, Outcome::kSuccess, - TrialType::kOnlyIssuanceRequiresOriginTrial, TrialEnabled::kDisabled}, - - {Op::kIssuance, Outcome::kSuccess, - TrialType::kAllOperationsRequireOriginTrial, TrialEnabled::kEnabled}, - - {Op::kIssuance, Outcome::kSuccessWithoutTrustTokenParams, - TrialType::kAllOperationsRequireOriginTrial, TrialEnabled::kDisabled}, - - {Op::kRedemption, Outcome::kSuccess, - TrialType::kAllOperationsRequireOriginTrial, TrialEnabled::kEnabled}, - - {Op::kRedemption, Outcome::kSuccessWithoutTrustTokenParams, - TrialType::kAllOperationsRequireOriginTrial, TrialEnabled::kDisabled}, -}; - -// Prints a string representation to use for generating test names. -std::string ToString(Op op) { - switch (op) { - case Op::kIssuance: - return "Issuance"; - case Op::kRedemption: - return "Redemption"; - default: - NOTREACHED(); - } -} - -std::string TestParamToString( - const ::testing::TestParamInfo<std::tuple<Interface, TestDescription>>& - info) { - Interface interface = std::get<0>(info.param); - const TestDescription& test_description = std::get<1>(info.param); - - return base::ReplaceStringPlaceholders( - "$1_$2_$3_$4", - {ToString(interface), ToString(test_description.op), - ToString(test_description.trial_type), - ToString(test_description.trial_enabled)}, - nullptr); -} - -} // namespace - -// Each parameter has to be a valid JSON encoding of a TrustToken JS object -// *and* valid to directly substitute into JS: this is because the iframe API -// requires a JSON encoding of the parameters object, while the Fetch and XHR -// APIs require actual objects. -INSTANTIATE_TEST_SUITE_P(ExecutingAllOperations, - TrustTokenOriginTrialBrowsertest, - Combine(Values(Interface::kFetch, Interface::kIframe), - ValuesIn(kTestDescriptions)), - &TestParamToString); - -// Test that a Trust Tokens request passes parameters to the network stack -// only when permitted by the origin trials framework (either because -// configuration specifies that no origin trial token is required, or because an -// origin trial token is present in the executing context). -IN_PROC_BROWSER_TEST_P(TrustTokenOriginTrialBrowsertest, - ProvidesParamsOnlyWhenAllowed) { - TestDescription test_description = std::get<1>(GetParam()); - Interface interface = std::get<0>(GetParam()); - - URLLoaderInterceptor interceptor(base::BindLambdaForTesting( - [this](URLLoaderInterceptor::RequestParams* params) { - return OnRequest(params); - })); - - switch (test_description.trial_enabled) { - case TrialEnabled::kEnabled: - ASSERT_TRUE(NavigateToURL(shell(), kPageWithOriginTrialToken)); - break; - case TrialEnabled::kDisabled: - ASSERT_TRUE(embedded_test_server()->Start()); - ASSERT_TRUE(NavigateToURL( - shell(), embedded_test_server()->GetURL("/title1.html"))); - break; - } - - base::RunLoop run_loop; - - { - base::AutoLock lock(mutex_); - on_received_request_ = run_loop.QuitClosure(); - } - - network::TrustTokenTestParameters trust_token_params( - 1, test_description.op, std::nullopt, std::nullopt); - - network::TrustTokenParametersAndSerialization - expected_params_and_serialization = - network::SerializeTrustTokenParametersAndConstructExpectation( - trust_token_params); - - std::string command; - switch (interface) { - case Interface::kFetch: - command = JsReplace("fetch($1, {privateToken: ", kTrustTokenUrl) + - expected_params_and_serialization.serialized_params + "});"; - break; - case Interface::kIframe: - if (test_description.op != Op::kSigning) { - return; - } - command = JsReplace( - "let iframe = document.createElement('iframe');" - "iframe.src = $1;" - "iframe.trustToken = $2;" - "document.body.appendChild(iframe);", - kTrustTokenUrl, expected_params_and_serialization.serialized_params); - - // When a Trust Tokens operation fails via the iframe interface, the - // request itself will still execute, just without an associated Trust - // Tokens operation. - if (test_description.outcome == Outcome::kFailure) - test_description.outcome = Outcome::kSuccessWithoutTrustTokenParams; - break; - } - - if (test_description.outcome == Outcome::kFailure) { - // Use EvalJs here to wait for promises to resolve. - EXPECT_THAT(EvalJs(shell(), command), EvalJsResult::IsError()); - return; - } - - ASSERT_TRUE(ExecJs(shell(), command)); - - run_loop.Run(); - - // URLLoaderInterceptor writes to trust_token_request_ on the IO sequence. - base::AutoLock lock(mutex_); - - ASSERT_TRUE(trust_token_request_); - - switch (test_description.outcome) { - case Outcome::kSuccess: - EXPECT_TRUE(trust_token_request_->trust_token_params); - break; - case Outcome::kSuccessWithoutTrustTokenParams: - EXPECT_FALSE(trust_token_request_->trust_token_params); - break; - case Outcome::kFailure: - NOTREACHED(); // Handled earlier. - } -} - -} // namespace content
diff --git a/content/browser/network/trust_token_parameters_browsertest.cc b/content/browser/network/trust_token_parameters_browsertest.cc index 6155efa..a570d7e 100644 --- a/content/browser/network/trust_token_parameters_browsertest.cc +++ b/content/browser/network/trust_token_parameters_browsertest.cc
@@ -6,7 +6,6 @@ #include "base/strings/escape.h" #include "base/strings/strcat.h" #include "base/test/bind.h" -#include "base/test/scoped_feature_list.h" #include "content/public/browser/network_service_util.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -17,7 +16,6 @@ #include "content/shell/browser/shell.h" #include "content/shell/browser/shell_content_browser_client.h" #include "net/dns/mock_host_resolver.h" -#include "services/network/public/cpp/features.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/trust_tokens.mojom.h" @@ -25,7 +23,6 @@ #include "services/network/test/trust_token_test_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/features.h" // These integration tests verify that calling the Fetch API with Trust Tokens // parameters results in the parameters' counterparts appearing downstream in @@ -40,19 +37,7 @@ : public ::testing::WithParamInterface<network::TrustTokenTestParameters>, public ContentBrowserTest { public: - TrustTokenParametersBrowsertest() { - auto& field_trial_param = - network::features::kTrustTokenOperationsRequiringOriginTrial; - features_.InitAndEnableFeatureWithParameters( - network::features::kFledgePst, - {{field_trial_param.name, - field_trial_param.GetName( - network::features::TrustTokenOriginTrialSpec:: - kOriginTrialNotRequired)}}); - } - - protected: - base::test::ScopedFeatureList features_; + TrustTokenParametersBrowsertest() = default; }; INSTANTIATE_TEST_SUITE_P( @@ -175,16 +160,11 @@ class TrustTokenPermissionsPolicyBrowsertest : public ContentBrowserTest { public: - TrustTokenPermissionsPolicyBrowsertest() { - features_.InitAndEnableFeature(network::features::kPrivateStateTokens); - } + TrustTokenPermissionsPolicyBrowsertest() = default; void SetUpOnMainThread() override { host_resolver()->AddRule("*", "127.0.0.1"); } - - protected: - base::test::ScopedFeatureList features_; }; IN_PROC_BROWSER_TEST_F(TrustTokenPermissionsPolicyBrowsertest, @@ -453,7 +433,6 @@ private: content::test::FencedFrameTestHelper fenced_frame_helper_; - base::test::ScopedFeatureList features_; }; INSTANTIATE_TEST_SUITE_P(All,
diff --git a/content/browser/network_context_client_base_impl.cc b/content/browser/network_context_client_base_impl.cc index 51ff367b..e4dca468 100644 --- a/content/browser/network_context_client_base_impl.cc +++ b/content/browser/network_context_client_base_impl.cc
@@ -10,7 +10,6 @@ #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/file_access/scoped_file_access.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/public/browser/content_browser_client.h"
diff --git a/content/browser/network_service_instance_impl.cc b/content/browser/network_service_instance_impl.cc index 84fc35a..0466122 100644 --- a/content/browser/network_service_instance_impl.cc +++ b/content/browser/network_service_instance_impl.cc
@@ -40,7 +40,6 @@ #include "base/threading/thread_restrictions.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/browser_main_loop.h" #include "content/browser/first_party_sets/first_party_sets_handler_impl.h" #include "content/browser/network/http_cache_backend_file_operations_factory.h"
diff --git a/content/browser/payments/payment_app_browsertest.cc b/content/browser/payments/payment_app_browsertest.cc index 442c50f..b44c4e7 100644 --- a/content/browser/payments/payment_app_browsertest.cc +++ b/content/browser/payments/payment_app_browsertest.cc
@@ -7,7 +7,6 @@ #include "base/command_line.h" #include "base/functional/bind.h" #include "base/run_loop.h" -#include "build/chromeos_buildflags.h" #include "content/browser/storage_partition_impl.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/installed_payment_apps_finder.h"
diff --git a/content/browser/pointer_lock_browsertest.cc b/content/browser/pointer_lock_browsertest.cc index 4381505..f15bb423 100644 --- a/content/browser/pointer_lock_browsertest.cc +++ b/content/browser/pointer_lock_browsertest.cc
@@ -9,7 +9,6 @@ #include "base/memory/raw_ptr.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/input/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/frame_tree.h" #include "content/browser/renderer_host/render_widget_host_impl.h" @@ -833,7 +832,7 @@ #if defined(USE_AURA) // TODO(crbug.com/40635377): Remove failure test when fully implemented -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) #define MAYBE_ChangeUnadjustedMovementFailure \ DISABLED_ChangeUnadjustedMovementFailure #else
diff --git a/content/browser/preloading/prefetch/prefetch_container.cc b/content/browser/preloading/prefetch/prefetch_container.cc index 21a4be2..248597a4 100644 --- a/content/browser/preloading/prefetch/prefetch_container.cc +++ b/content/browser/preloading/prefetch/prefetch_container.cc
@@ -1061,10 +1061,6 @@ void PrefetchContainer::AddXClientDataHeader( network::ResourceRequest& request) { - if (!base::FeatureList::IsEnabled(features::kPrefetchXClientDataHeader)) { - return; - } - if (browser_context_) { // Add X-Client-Data header with experiment IDs from field trials. variations::AppendVariationsHeader(request.url,
diff --git a/content/browser/preloading/prefetch/prefetch_container_unittest.cc b/content/browser/preloading/prefetch/prefetch_container_unittest.cc index 07e72ab..c6de160 100644 --- a/content/browser/preloading/prefetch/prefetch_container_unittest.cc +++ b/content/browser/preloading/prefetch/prefetch_container_unittest.cc
@@ -172,13 +172,10 @@ class PrefetchContainerXClientDataHeaderTest : public PrefetchContainerTestBase, - // In incognito or not, is X-Client-Header prefetch support enabled or - // not. - public ::testing::WithParamInterface<std::tuple<bool, bool>> { + // In incognito or not. + public ::testing::WithParamInterface<bool> { private: void SetUp() override { - scoped_feature_list_.InitWithFeatureState( - features::kPrefetchXClientDataHeader, get<1>(GetParam())); PrefetchContainerTestBase::SetUp(); } @@ -188,7 +185,7 @@ protected: std::unique_ptr<BrowserContext> CreateBrowserContext() override { auto browser_context = std::make_unique<TestBrowserContext>(); - auto is_incognito = get<0>(GetParam()); + auto is_incognito = GetParam(); browser_context->set_is_off_the_record(is_incognito); return browser_context; } @@ -205,12 +202,11 @@ prefetch_container->MakeResourceRequest({}); auto* request = prefetch_container->GetResourceRequest(); - bool is_incognito, is_x_client_data_header_enabled; - std::tie(is_incognito, is_x_client_data_header_enabled) = GetParam(); + bool is_incognito = GetParam(); // Don't add the header when in incognito mode. EXPECT_EQ( request->cors_exempt_headers.HasHeader(variations::kClientDataHeader), - !is_incognito && is_x_client_data_header_enabled); + !is_incognito); } TEST_P(PrefetchContainerXClientDataHeaderTest, @@ -246,11 +242,10 @@ request->cors_exempt_headers.HasHeader(variations::kClientDataHeader)); AddRedirectHop(prefetch_container.get(), kTestEligibleUrl); - bool is_incognito, is_x_client_data_header_enabled; - std::tie(is_incognito, is_x_client_data_header_enabled) = GetParam(); + bool is_incognito = GetParam(); EXPECT_EQ( request->cors_exempt_headers.HasHeader(variations::kClientDataHeader), - !is_incognito && is_x_client_data_header_enabled); + !is_incognito); } TEST_P(PrefetchContainerXClientDataHeaderTest, @@ -276,8 +271,7 @@ INSTANTIATE_TEST_SUITE_P(PrefetchContainerXClientDataTests, PrefetchContainerXClientDataHeaderTest, - ::testing::Combine(::testing::Bool(), - ::testing::Bool())); + ::testing::Bool()); TEST_P(PrefetchContainerTest, CreatePrefetchContainer) { blink::DocumentToken document_token;
diff --git a/content/browser/preloading/prefetch/prefetch_features.cc b/content/browser/preloading/prefetch/prefetch_features.cc index af5c01ca..bce9d38 100644 --- a/content/browser/preloading/prefetch/prefetch_features.cc +++ b/content/browser/preloading/prefetch/prefetch_features.cc
@@ -32,10 +32,6 @@ "PrefetchClientHints", base::FEATURE_ENABLED_BY_DEFAULT); -BASE_FEATURE(kPrefetchXClientDataHeader, - "PrefetchXClientDataHeader", - base::FEATURE_ENABLED_BY_DEFAULT); - constexpr base::FeatureParam<PrefetchClientHintsCrossSiteBehavior>::Option kPrefetchClientHintsCrossSiteBehaviorOptions[] = { {PrefetchClientHintsCrossSiteBehavior::kNone, "none"},
diff --git a/content/browser/preloading/prefetch/prefetch_features.h b/content/browser/preloading/prefetch/prefetch_features.h index a989b14..fb24b3bb 100644 --- a/content/browser/preloading/prefetch/prefetch_features.h +++ b/content/browser/preloading/prefetch/prefetch_features.h
@@ -54,9 +54,6 @@ PrefetchClientHintsCrossSiteBehavior> kPrefetchClientHintsCrossSiteBehavior; -// If enabled, prefetch requests may include X-Client-Data request header. -CONTENT_EXPORT BASE_DECLARE_FEATURE(kPrefetchXClientDataHeader); - // If enabled, then prefetch serving will apply mitigations if it may have been // contaminated by cross-partition state. CONTENT_EXPORT BASE_DECLARE_FEATURE(kPrefetchStateContaminationMitigation);
diff --git a/content/browser/preloading/prefetch/prefetch_match_resolver.cc b/content/browser/preloading/prefetch/prefetch_match_resolver.cc index af3b7c0b..7fed181a 100644 --- a/content/browser/preloading/prefetch/prefetch_match_resolver.cc +++ b/content/browser/preloading/prefetch/prefetch_match_resolver.cc
@@ -9,6 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" #include "base/ranges/algorithm.h" +#include "base/trace_event/trace_event.h" #include "content/browser/preloading/prefetch/prefetch_container.h" #include "content/browser/preloading/prefetch/prefetch_params.h" #include "content/browser/preloading/prefetch/prefetch_service.h" @@ -200,6 +201,7 @@ base::WeakPtr<PrefetchServingPageMetricsContainer> serving_page_metrics_container, Callback callback) { + TRACE_EVENT0("loading", "PrefetchMatchResolver2::FindPrefetch"); // See the comment of `self_`. auto prefetch_match_resolver = base::WrapUnique(new PrefetchMatchResolver2( std::move(navigated_key), prefetch_service.GetWeakPtr(), @@ -431,6 +433,8 @@ void PrefetchMatchResolver2::UnblockForMatch( const PrefetchContainer::Key& prefetch_key) { + TRACE_EVENT0("loading", "PrefetchMatchResolver2::UnblockForMatch"); + // By #prefetch-key-availability CHECK(candidates_.contains(prefetch_key)); auto& candidate_data = candidates_[prefetch_key]; @@ -472,6 +476,7 @@ } void PrefetchMatchResolver2::UnblockForNoCandidates() { + TRACE_EVENT0("loading", "PrefetchMatchResolver2::UnblockForNoCandidates"); UnblockInternal({}); }
diff --git a/content/browser/preloading/prefetch/prefetch_network_context_client.cc b/content/browser/preloading/prefetch/prefetch_network_context_client.cc index 5466aec..c787fcb 100644 --- a/content/browser/preloading/prefetch/prefetch_network_context_client.cc +++ b/content/browser/preloading/prefetch/prefetch_network_context_client.cc
@@ -7,7 +7,6 @@ #include <memory> #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "mojo/public/cpp/bindings/remote.h" #include "net/base/net_errors.h" #include "services/network/public/mojom/trust_tokens.mojom.h"
diff --git a/content/browser/preloading/prefetch/prefetch_network_context_client.h b/content/browser/preloading/prefetch/prefetch_network_context_client.h index c0110ef..e30964de 100644 --- a/content/browser/preloading/prefetch/prefetch_network_context_client.h +++ b/content/browser/preloading/prefetch/prefetch_network_context_client.h
@@ -6,7 +6,6 @@ #define CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_NETWORK_CONTEXT_CLIENT_H_ #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/network/public/cpp/network_service_buildflags.h" #include "services/network/public/mojom/network_context_client.mojom.h"
diff --git a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.cc b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.cc index a9275bb3..95b85ec1 100644 --- a/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.cc +++ b/content/browser/preloading/prefetch/prefetch_url_loader_interceptor.cc
@@ -74,6 +74,7 @@ BrowserContext* browser_context, NavigationLoaderInterceptor::LoaderCallback callback, NavigationLoaderInterceptor::FallbackCallback fallback_callback) { + TRACE_EVENT0("loading", "PrefetchURLLoaderInterceptor::MaybeCreateLoader"); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CHECK(!loader_callback_); @@ -163,6 +164,7 @@ PrefetchMatchResolver& prefetch_match_resolver, base::OnceCallback<void(PrefetchContainer::Reader)> get_prefetch_callback) const { + TRACE_EVENT0("loading", "PrefetchURLLoaderInterceptor::GetPrefetch"); PrefetchService* prefetch_service = PrefetchService::GetFromFrameTreeNodeId(frame_tree_node_id_); if (!prefetch_service) { @@ -212,6 +214,8 @@ void PrefetchURLLoaderInterceptor::OnGetPrefetchComplete( PrefetchContainer::Reader reader) { + TRACE_EVENT0("loading", + "PrefetchURLLoaderInterceptor::OnGetPrefetchComplete"); PrefetchRequestHandler request_handler; if (!reader || !(request_handler = reader.CreateRequestHandler())) { // Do not intercept the request.
diff --git a/content/browser/preloading/prerender/prerender_browsertest.cc b/content/browser/preloading/prerender/prerender_browsertest.cc index 2f35dd0..4fdcce7d 100644 --- a/content/browser/preloading/prerender/prerender_browsertest.cc +++ b/content/browser/preloading/prerender/prerender_browsertest.cc
@@ -34,7 +34,6 @@ #include "base/thread_annotations.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/base/features.h" #include "components/input/render_widget_host_input_event_router.h" #include "components/services/storage/public/mojom/storage_service.mojom.h" @@ -653,6 +652,8 @@ expected_prediction_entry); } + void TestActivateOnWindowOpen(std::string_view window_features); + void TestHostPrerenderingState(const GURL& prerender_url) { const GURL kInitialUrl = GetUrl("/empty.html"); @@ -3121,81 +3122,33 @@ /*accurate=*/false)}); } -// Tests that window.open() annotated with "_blank" and "noopener" can activate -// a prerender whose target_hint is "_blank". -IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ActivateOnWindowOpen_NewTab) { - const GURL kInitialUrl = GetUrl("/simple_links.html"); - const GURL kPrerenderingUrl = GetUrl("/title2.html"); - - // Navigate to an initial page which has a link to `kPrerenderingUrl`. - ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); - - // Start prerendering `kPrerenderingUrl`. - FrameTreeNodeId host_id = prerender_helper()->AddPrerender( - kPrerenderingUrl, /*eagerness=*/std::nullopt, "_blank"); - auto* prerender_web_contents = WebContents::FromFrameTreeNodeId(host_id); - ASSERT_NE(prerender_web_contents, web_contents_impl()); - ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents); - - // Open a new window with "_blank" and "noopener". This should activate the - // prerendered page. - TestNavigationObserver activation_observer(kPrerenderingUrl); - activation_observer.WatchExistingWebContents(); - test::PrerenderHostObserver prerender_observer(*prerender_web_contents, - host_id); - const std::string kWindowOpenScript = R"( - window.open("title2.html", "_blank", "noopener"); - )"; - EXPECT_TRUE(ExecJs(web_contents(), kWindowOpenScript)); - activation_observer.WaitForNavigationFinished(); - EXPECT_EQ(prerender_web_contents->GetLastCommittedURL(), kPrerenderingUrl); - EXPECT_EQ(activation_observer.last_navigation_url(), kPrerenderingUrl); - EXPECT_TRUE(prerender_observer.was_activated()); - EXPECT_FALSE(HasHostForUrl(*prerender_web_contents, kPrerenderingUrl)); - - ExpectFinalStatusForSpeculationRule(PrerenderFinalStatus::kActivated); - - ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id(); - ExpectPreloadingAttemptUkm({attempt_ukm_entry_builder().BuildEntry( - ukm_source_id, PreloadingType::kPrerender, - PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed, - PreloadingTriggeringOutcome::kSuccess, - PreloadingFailureReason::kUnspecified, - /*accurate=*/true, - /*ready_time=*/kMockElapsedTime, - blink::mojom::SpeculationEagerness::kEager)}); - - // The navigation occurred in a new WebContents, so the original WebContents - // should still be showing the initial trigger page. - EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl); -} - -// Tests that window.open() annotated with "_blank" and "noopener,popup" can -// activate a prerender whose target_hint is "_blank". -IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ActivateOnWindowOpen_PopUp) { +// `window_features` is passed to the 3rd argument of window.open(). +void PrerenderBrowserTest::TestActivateOnWindowOpen( + std::string_view window_features) { const GURL initial_url = GetUrl("/simple_links.html"); const GURL prerendering_url = GetUrl("/title2.html"); - // Navigate to an initial page which has a link to `kPrerenderingUrl`. + // Navigate to an initial page which has a link to `prerendering_url`. ASSERT_TRUE(NavigateToURL(shell(), initial_url)); - // Start prerendering `kPrerenderingUrl`. + // Start prerendering `prerendering_url`. FrameTreeNodeId host_id = prerender_helper()->AddPrerender( prerendering_url, /*eagerness=*/std::nullopt, "_blank"); auto* prerender_web_contents = WebContents::FromFrameTreeNodeId(host_id); ASSERT_NE(prerender_web_contents, web_contents_impl()); ExpectWebContentsIsForNewTabPrerendering(*prerender_web_contents); - // Open a new window with "_blank" and "noopener,popup". This should activate + // Open a new window with "_blank" and `window_features`. This should activate // the prerendered page. TestNavigationObserver activation_observer(prerendering_url); activation_observer.WatchExistingWebContents(); test::PrerenderHostObserver prerender_observer(*prerender_web_contents, host_id); - const std::string kWindowOpenScript = R"( - window.open("title2.html", "_blank", "noopener,popup"); - )"; - EXPECT_TRUE(ExecJs(web_contents(), kWindowOpenScript)); + const std::string script = base::StringPrintf(R"( + window.open("title2.html", "_blank", "%s"); + )", + window_features); + EXPECT_TRUE(ExecJs(web_contents(), script)); activation_observer.WaitForNavigationFinished(); EXPECT_EQ(prerender_web_contents->GetLastCommittedURL(), prerendering_url); EXPECT_EQ(activation_observer.last_navigation_url(), prerendering_url); @@ -3219,6 +3172,18 @@ EXPECT_EQ(web_contents()->GetLastCommittedURL(), initial_url); } +// Tests that window.open() annotated with "_blank" and "noopener" can activate +// a prerender whose target_hint is "_blank". +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ActivateOnWindowOpen_NewTab) { + TestActivateOnWindowOpen("noopener"); +} + +// Tests that window.open() annotated with "_blank" and "noopener,popup" can +// activate a prerender whose target_hint is "_blank". +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ActivateOnWindowOpen_PopUp) { + TestActivateOnWindowOpen("noopener,popup"); +} + // TODO(crbug.com/40234240): Add more test cases for prerender-in-new-tab: // - Multiple prerendering requests with the same URL but different target hint. // - Navigation in a new tab to the prerendering URL multiple times. Only the
diff --git a/content/browser/renderer_host/clipboard_host_impl.cc b/content/browser/renderer_host/clipboard_host_impl.cc index b5132979..47c36e0 100644 --- a/content/browser/renderer_host/clipboard_host_impl.cc +++ b/content/browser/renderer_host/clipboard_host_impl.cc
@@ -53,9 +53,9 @@ #include "ui/base/data_transfer_policy/data_transfer_policy_controller.h" #include "url/gurl.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "content/public/common/url_constants.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) namespace content { @@ -223,14 +223,14 @@ clipboard->IsFormatAvailable(ui::ClipboardFormatType::FilenamesType(), clipboard_buffer, data_endpoint.get()); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // ChromeOS FilesApp must include the custom 'fs/sources', etc data for // paste that it put on the clipboard during copy (b/271078230). if (render_frame_host().GetMainFrame()->GetLastCommittedURL().SchemeIs( kChromeUIScheme)) { file_type_only = false; } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) if (file_type_only) { types = {base::UTF8ToUTF16(ui::kMimeTypeURIList)};
diff --git a/content/browser/renderer_host/data_transfer_util.cc b/content/browser/renderer_host/data_transfer_util.cc index 5198a51..27850b5a 100644 --- a/content/browser/renderer_host/data_transfer_util.cc +++ b/content/browser/renderer_host/data_transfer_util.cc
@@ -13,7 +13,6 @@ #include "base/files/file_path.h" #include "base/strings/utf_string_conversions.h" #include "base/uuid.h" -#include "build/chromeos_buildflags.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/file_system_access/file_system_access_manager_impl.h" #include "content/public/browser/browser_thread.h" @@ -40,7 +39,7 @@ // updates `entry_path` to the path that should be used by the File System // Access implementation. content::PathType MaybeRemapPath(base::FilePath* entry_path) { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) base::FilePath virtual_path; auto* external_mount_points = storage::ExternalMountPoints::GetSystemInstance();
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index a5528d57..ad54a1a 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -17,7 +17,6 @@ #include "base/task/single_thread_task_runner.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/base/switches.h" #include "components/viz/common/features.h" #include "components/viz/common/frame_sinks/copy_output_request.h" @@ -465,7 +464,7 @@ // TODO(crbug.com/1227661): Revert https://crrev.com/c/3222541 to re-enable this // CHECK on CrOS. -#if !BUILDFLAG(IS_CHROMEOS_ASH) +#if !BUILDFLAG(IS_CHROMEOS) CHECK_NE(frame_eviction_state_, FrameEvictionState::kNotStarted); #endif SetFrameEvictionStateAndNotifyObservers(FrameEvictionState::kNotStarted); @@ -485,7 +484,7 @@ client_->DelegatedFrameHostGetLayer()->Add(stale_content_layer_.get()); // TODO(crbug.com/40812011): This DCHECK occasionally gets hit on Chrome OS. -#if !BUILDFLAG(IS_CHROMEOS_ASH) +#if !BUILDFLAG(IS_CHROMEOS) CHECK(!stale_content_layer_->has_external_content()); #endif stale_content_layer_->SetVisible(true);
diff --git a/content/browser/renderer_host/input/fling_browsertest.cc b/content/browser/renderer_host/input/fling_browsertest.cc index 29ce2316..4234dff 100644 --- a/content/browser/renderer_host/input/fling_browsertest.cc +++ b/content/browser/renderer_host/input/fling_browsertest.cc
@@ -9,7 +9,6 @@ #include "base/task/single_thread_task_runner.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/input/render_widget_host_input_event_router.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/input/synthetic_smooth_scroll_gesture.h" @@ -425,7 +424,7 @@ } // Touchpad fling only happens on ChromeOS. -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchpadInertialGSUsBubbleFromOOPIF) { LoadPageWithOOPIF(); @@ -443,7 +442,7 @@ SimulateTouchpadFling(child_view_->host(), GetWidgetHost(), fling_velocity); WaitForFrameScroll(GetRootNode(), 15, true /* upward */); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) // TODO(crbug.com/40230295): flaky. IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest,
diff --git a/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc b/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc index c37c578f..830e374b 100644 --- a/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc +++ b/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc
@@ -12,7 +12,6 @@ #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/input/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_base.h"
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc index 7fe5f9b..732833b4 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc +++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
@@ -16,7 +16,6 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_timeouts.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/render_widget_host_view_aura.h" #include "content/browser/renderer_host/render_widget_host_view_child_frame.h" #include "content/browser/renderer_host/render_widget_host_view_event_handler.h" @@ -1290,7 +1289,7 @@ } #endif // BUILDFLAG(IS_CHROMEOS) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Tests that touch selection dragging records a histogram entry. IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, SelectionDraggingMetrics) { @@ -1335,7 +1334,7 @@ histogram_tester.ExpectUniqueSample( ui::kTouchSelectionSessionTouchDownCountHistogramName, 3, 1); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) // Tests that the quick menu is hidden whenever a touch point is active. // Flaky: https://crbug.com/803576
diff --git a/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc b/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc index a1411b4..b8f9329 100644 --- a/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc +++ b/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc
@@ -5,7 +5,6 @@ #include "base/run_loop.h" #include "base/task/single_thread_task_runner.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/input/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -254,7 +253,7 @@ EvalJs(shell(), "scrollableDiv.getBoundingClientRect().bottom") .ExtractDouble()) / 2; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) bool precise = true; #else bool precise = false;
diff --git a/content/browser/renderer_host/media/audio_input_device_manager.cc b/content/browser/renderer_host/media/audio_input_device_manager.cc index 5a52e52f..eb3ec3a3 100644 --- a/content/browser/renderer_host/media/audio_input_device_manager.cc +++ b/content/browser/renderer_host/media/audio_input_device_manager.cc
@@ -14,7 +14,6 @@ #include "base/observer_list.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h"
diff --git a/content/browser/renderer_host/media/audio_input_device_manager.h b/content/browser/renderer_host/media/audio_input_device_manager.h index 8f3203b..608f26d7 100644 --- a/content/browser/renderer_host/media/audio_input_device_manager.h +++ b/content/browser/renderer_host/media/audio_input_device_manager.h
@@ -22,7 +22,6 @@ #include "base/threading/thread.h" #include "base/unguessable_token.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/media/media_stream_provider.h" #include "content/common/content_export.h" #include "third_party/blink/public/common/mediastream/media_stream_request.h"
diff --git a/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc b/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc index 9e6d0b8..cafecb1 100644 --- a/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc +++ b/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc
@@ -11,7 +11,6 @@ #include "base/functional/callback_forward.h" #include "base/task/single_thread_task_runner.h" #include "base/token.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/browser_context.h" #include "media/capture/mojom/video_capture_types.mojom.h" #include "media/capture/video/video_capture_buffer_pool_impl.h" @@ -19,9 +18,9 @@ #include "media/capture/video/video_capture_device_client.h" #include "media/capture/video/video_frame_receiver_on_task_runner.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "media/capture/video/chromeos/video_capture_jpeg_decoder.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) namespace { @@ -105,7 +104,7 @@ new media::VideoCaptureBufferPoolImpl( media::VideoCaptureBufferType::kSharedMemory)); #endif // BUILDFLAG(IS_WIN) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) auto device_client = std::make_unique<media::VideoCaptureDeviceClient>( std::make_unique<media::VideoFrameReceiverOnTaskRunner>( receiver, base::SingleThreadTaskRunner::GetCurrentDefault()), @@ -117,7 +116,7 @@ std::make_unique<media::VideoFrameReceiverOnTaskRunner>( receiver, base::SingleThreadTaskRunner::GetCurrentDefault()), std::move(buffer_pool), std::nullopt); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) device->AllocateAndStart(params, std::move(device_client)); auto launched_device = std::make_unique<FakeLaunchedVideoCaptureDevice>(std::move(device));
diff --git a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc index e7db48a..68f0d2c 100644 --- a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc +++ b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
@@ -17,7 +17,6 @@ #include "base/task/single_thread_task_runner.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/media/capture/native_screen_capture_picker.h" #include "content/browser/renderer_host/media/in_process_launched_video_capture_device.h" #include "content/browser/renderer_host/media/video_capture_controller.h" @@ -54,19 +53,19 @@ #endif #endif // BUILDFLAG(ENABLE_SCREEN_CAPTURE) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "content/browser/gpu/chromeos/video_capture_dependencies.h" #include "media/capture/video/chromeos/scoped_video_capture_jpeg_decoder.h" #include "media/capture/video/chromeos/video_capture_jpeg_decoder_impl.h" #elif BUILDFLAG(IS_WIN) #include "media/capture/video/win/video_capture_device_factory_win.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) namespace content { namespace { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder( media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb, base::RepeatingCallback<void(const std::string&)> send_log_message_cb) { @@ -79,7 +78,7 @@ std::move(send_log_message_cb)), io_task_runner); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(ENABLE_SCREEN_CAPTURE) @@ -401,7 +400,7 @@ requested_buffer_type, buffer_pool_max_buffer_count); #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) return std::make_unique<media::VideoCaptureDeviceClient>( std::move(receiver), std::move(buffer_pool), base::BindRepeating( @@ -413,7 +412,7 @@ #else return std::make_unique<media::VideoCaptureDeviceClient>( std::move(receiver), std::move(buffer_pool), std::nullopt); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } void InProcessVideoCaptureDeviceLauncher::OnDeviceStarted(
diff --git a/content/browser/renderer_host/media/media_devices_manager.cc b/content/browser/renderer_host/media/media_devices_manager.cc index af68814..bac62e8 100644 --- a/content/browser/renderer_host/media/media_devices_manager.cc +++ b/content/browser/renderer_host/media/media_devices_manager.cc
@@ -25,7 +25,6 @@ #include "base/task/single_thread_task_runner.h" #include "base/threading/thread_checker.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/media/media_devices_permission_checker.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/media/video_capture_manager.h"
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc index 4388970..e84403ef 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -29,7 +29,6 @@ #include "base/test/test_future.h" #include "base/unguessable_token.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/media/media_devices_util.h" #include "content/browser/renderer_host/media/audio_input_device_manager.h" #include "content/browser/renderer_host/media/media_stream_manager.h" @@ -61,7 +60,7 @@ #include "url/gurl.h" #include "url/origin.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "chromeos/ash/components/audio/cras_audio_handler.h" #include "chromeos/ash/components/dbus/audio/cras_audio_client.h" #endif @@ -338,7 +337,7 @@ base::BindRepeating(&MediaStreamDispatcherHostTest::MockOnBadMessage, base::Unretained(this))); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) ash::CrasAudioClient::InitializeFake(); ash::CrasAudioHandler::InitializeForTesting(); #endif @@ -346,7 +345,7 @@ ~MediaStreamDispatcherHostTest() override { audio_manager_->Shutdown(); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) ash::CrasAudioHandler::Shutdown(); ash::CrasAudioClient::Shutdown(); #endif
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc index 46c8f54f..55ae2600 100644 --- a/content/browser/renderer_host/media/media_stream_manager.cc +++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -30,7 +30,6 @@ #include "base/threading/thread.h" #include "base/uuid.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/media/capture/desktop_capture_device_uma_types.h" @@ -91,7 +90,7 @@ #include "base/win/scoped_com_initializer.h" #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "chromeos/ash/components/audio/cras_audio_handler.h" #include "content/browser/gpu/chromeos/video_capture_dependencies.h" #include "content/browser/gpu/gpu_memory_buffer_manager_singleton.h" @@ -138,7 +137,7 @@ void EnableHotwordEffect(const StreamControls& controls, int* effects) { DCHECK(effects); if (controls.hotword_enabled) { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Only enable if a hotword device exists. if (ash::CrasAudioHandler::Get()->HasHotwordDevice()) { *effects |= media::AudioParameters::HOTWORD; @@ -1603,7 +1602,7 @@ device_task_runner = video_capture_thread_->task_runner(); #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) if (media::ShouldUseCrosCameraService()) { jpeg_accelerator_provider_ = std::make_unique<media::JpegAcceleratorProviderImpl>(
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h index 2dc655f..3eeed15 100644 --- a/content/browser/renderer_host/media/media_stream_manager.h +++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -55,7 +55,7 @@ namespace media { class AudioSystem; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) class JpegAcceleratorProviderImpl; class SystemEventMonitorImpl; #endif @@ -871,7 +871,7 @@ GenerateStreamTestCallback generate_stream_test_callback_; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) std::unique_ptr<media::JpegAcceleratorProviderImpl> jpeg_accelerator_provider_;
diff --git a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc index 1146ca6..89323bfa 100644 --- a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc +++ b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc
@@ -12,7 +12,6 @@ #include "base/functional/callback_helpers.h" #include "base/run_loop.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/media/forwarding_audio_stream_factory.h" #include "content/browser/renderer_host/media/audio_input_device_manager.h" #include "content/browser/renderer_host/media/media_stream_manager.h"
diff --git a/content/browser/renderer_host/media/service_video_capture_provider.cc b/content/browser/renderer_host/media/service_video_capture_provider.cc index a64e66b..45f9585 100644 --- a/content/browser/renderer_host/media/service_video_capture_provider.cc +++ b/content/browser/renderer_host/media/service_video_capture_provider.cc
@@ -11,7 +11,6 @@ #include "base/metrics/histogram_functions.h" #include "base/trace_event/common/trace_event_common.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/child_process_host_impl.h" #include "content/browser/renderer_host/media/service_video_capture_device_launcher.h" #include "content/browser/renderer_host/media/virtual_video_capture_devices_changed_observer.h" @@ -28,22 +27,22 @@ #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "services/video_capture/public/mojom/video_capture_service.mojom.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "content/public/browser/chromeos/delegate_to_browser_gpu_service_accelerator_factory.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) namespace { using GetSourceInfosResult = video_capture::mojom::VideoSourceProvider::GetSourceInfosResult; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) std::unique_ptr<video_capture::mojom::AcceleratorFactory> CreateAcceleratorFactory() { return std::make_unique< content::DelegateToBrowserGpuServiceAcceleratorFactory>(); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) // Do not reorder, used for UMA Media.VideoCapture.GetDeviceInfosResult enum class GetDeviceInfosResult { @@ -119,7 +118,7 @@ const base::RepeatingClosure stop_callback_; }; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) ServiceVideoCaptureProvider::ServiceVideoCaptureProvider( base::RepeatingCallback<void(const std::string&)> emit_log_message_cb) : ServiceVideoCaptureProvider(base::NullCallback(), @@ -131,12 +130,12 @@ : create_accelerator_factory_cb_(std::move(create_accelerator_factory_cb)), emit_log_message_cb_(std::move(emit_log_message_cb)), launcher_has_connected_to_source_provider_(false) { -#else // BUILDFLAG(IS_CHROMEOS_ASH) +#else // BUILDFLAG(IS_CHROMEOS) ServiceVideoCaptureProvider::ServiceVideoCaptureProvider( base::RepeatingCallback<void(const std::string&)> emit_log_message_cb) : emit_log_message_cb_(std::move(emit_log_message_cb)), launcher_has_connected_to_source_provider_(false) { -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) if (features::IsVideoCaptureServiceEnabledForOutOfProcess()) { service_process_observer_.emplace( GetUIThreadTaskRunner({}), @@ -251,7 +250,7 @@ time_of_last_connect_ = base::TimeTicks::Now(); auto ui_task_runner = GetUIThreadTaskRunner({}); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) mojo::PendingRemote<video_capture::mojom::AcceleratorFactory> accelerator_factory; if (!create_accelerator_factory_cb_) @@ -262,7 +261,7 @@ accelerator_factory.InitWithNewPipeAndPassReceiver()); GetVideoCaptureService().InjectGpuDependencies( std::move(accelerator_factory)); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(IS_WIN) // Pass active gpu info.
diff --git a/content/browser/renderer_host/media/service_video_capture_provider.h b/content/browser/renderer_host/media/service_video_capture_provider.h index 4e29dd3..ef6e898 100644 --- a/content/browser/renderer_host/media/service_video_capture_provider.h +++ b/content/browser/renderer_host/media/service_video_capture_provider.h
@@ -11,7 +11,6 @@ #include "base/threading/thread_checker.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/media/ref_counted_video_source_provider.h" #include "content/browser/renderer_host/media/video_capture_provider.h" #include "content/common/content_export.h" @@ -36,7 +35,7 @@ explicit ServiceVideoCaptureProvider( base::RepeatingCallback<void(const std::string&)> emit_log_message_cb); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) using CreateAcceleratorFactoryCallback = base::RepeatingCallback< std::unique_ptr<video_capture::mojom::AcceleratorFactory>()>; // Lets clients provide a custom factory method for creating instances of @@ -44,7 +43,7 @@ ServiceVideoCaptureProvider( CreateAcceleratorFactoryCallback create_accelerator_factory_cb, base::RepeatingCallback<void(const std::string&)> emit_log_message_cb); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) ~ServiceVideoCaptureProvider() override; @@ -88,9 +87,9 @@ void OnLostConnectionToSourceProvider(); void OnServiceConnectionClosed(ReasonForDisconnect reason); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) CreateAcceleratorFactoryCallback create_accelerator_factory_cb_; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) base::RepeatingCallback<void(const std::string&)> emit_log_message_cb_; base::WeakPtr<RefCountedVideoSourceProvider> weak_service_connection_;
diff --git a/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc b/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc index 9b00547..ac5d30f 100644 --- a/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc +++ b/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc
@@ -13,7 +13,6 @@ #include "base/test/mock_callback.h" #include "base/test/scoped_feature_list.h" #include "base/threading/thread.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/video_capture_device_launcher.h" #include "content/public/browser/video_capture_service.h" #include "content/public/common/content_features.h" @@ -81,7 +80,7 @@ // macOS. scoped_feature_list_.InitAndDisableFeature( features::kRetryGetVideoCaptureDeviceInfos); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) provider_ = std::make_unique<ServiceVideoCaptureProvider>( base::BindRepeating([]() { return std::unique_ptr<video_capture::mojom::AcceleratorFactory>(); @@ -90,7 +89,7 @@ #else provider_ = std::make_unique<ServiceVideoCaptureProvider>(kIgnoreLogMessageCB); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) ON_CALL(mock_video_capture_service_, DoConnectToVideoSourceProvider(_)) .WillByDefault(Invoke(
diff --git a/content/browser/renderer_host/media/video_capture_browsertest.cc b/content/browser/renderer_host/media/video_capture_browsertest.cc index 8583442..9d7130fd 100644 --- a/content/browser/renderer_host/media/video_capture_browsertest.cc +++ b/content/browser/renderer_host/media/video_capture_browsertest.cc
@@ -12,7 +12,6 @@ #include "base/test/scoped_feature_list.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/browser_main_loop.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/media/video_capture_controller.h" @@ -298,7 +297,7 @@ std::move(quit_run_loop_on_current_thread_cb), true); bool must_wait_for_gpu_decode_to_start = false; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) if (params_.exercise_accelerated_jpeg_decoding) { // Since the GPU jpeg decoder is created asynchronously while decoding // in software is ongoing, we have to keep pushing frames until a message @@ -311,7 +310,7 @@ must_wait_for_gpu_decode_to_start = false; })); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) EXPECT_CALL(mock_controller_event_handler_, DoOnNewBuffer(_, _, _)) .Times(AtLeast(1)); EXPECT_CALL(mock_controller_event_handler_, OnBufferReady(_, _))
diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc index 857840b..c6887b0 100644 --- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -21,7 +21,6 @@ #include "base/task/single_thread_task_runner.h" #include "base/test/bind.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/media/media_stream_provider.h" #include "content/browser/renderer_host/media/mock_video_capture_provider.h" #include "content/browser/renderer_host/media/video_capture_controller_event_handler.h" @@ -40,9 +39,9 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "media/capture/video/chromeos/video_capture_jpeg_decoder_impl.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) using ::testing::_; using ::testing::AnyNumber; @@ -190,7 +189,7 @@ void InitializeNewDeviceClientAndBufferPoolInstances() { buffer_pool_ = new media::VideoCaptureBufferPoolImpl( media::VideoCaptureBufferType::kSharedMemory, kPoolSize); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) device_client_ = std::make_unique<media::VideoCaptureDeviceClient>( std::make_unique<media::VideoFrameReceiverOnTaskRunner>( controller_->GetWeakPtrForIOThread(), GetIOThreadTaskRunner({})), @@ -200,7 +199,7 @@ std::make_unique<media::VideoFrameReceiverOnTaskRunner>( controller_->GetWeakPtrForIOThread(), GetIOThreadTaskRunner({})), buffer_pool_, std::nullopt); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } void SendStubFrameToDeviceClient(const media::VideoCaptureFormat format,
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc index 5b81be69..da335c4 100644 --- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -27,7 +27,6 @@ #include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/process_lock.h" #include "content/browser/renderer_host/frame_navigation_entry.h"
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index d42bf5c..cc3a158 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -41,7 +41,6 @@ #include "base/types/pass_key.h" #include "build/build_config.h" #include "build/buildflag.h" -#include "build/chromeos_buildflags.h" #include "components/viz/host/host_frame_sink_manager.h" #include "content/browser/agent_cluster_key.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h"
diff --git a/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc b/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc index 6cbc547..ec820ec2 100644 --- a/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc +++ b/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc
@@ -6,7 +6,6 @@ #include "base/location.h" #include "base/strings/string_number_conversions.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/frame_tree_node.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h"
diff --git a/content/browser/renderer_host/panel_rotation_browsertest.cc b/content/browser/renderer_host/panel_rotation_browsertest.cc index 227d527..2435243 100644 --- a/content/browser/renderer_host/panel_rotation_browsertest.cc +++ b/content/browser/renderer_host/panel_rotation_browsertest.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "build/chromeos_buildflags.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" @@ -13,7 +12,7 @@ namespace content { // TODO(crbug.com/41478398): Add test coverage across all platforms. -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) class PanelRotationBrowserTest : public ContentBrowserTest { protected: void SetPanelRotation(display::Display::Rotation rotation) { @@ -40,6 +39,6 @@ SetPanelRotation(display::Display::ROTATE_270); EXPECT_EQ(ReadScreenOrientationAngle(), 90); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } // namespace content
diff --git a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc index 97f6e2e..301882846 100644 --- a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc +++ b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc
@@ -6,7 +6,6 @@ #include <stddef.h> #include <utility> -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/pepper_browser_font_singleton_host.h"
diff --git a/content/browser/renderer_host/pepper/pepper_socket_utils.cc b/content/browser/renderer_host/pepper/pepper_socket_utils.cc index 3abbecd9..70a92ad 100644 --- a/content/browser/renderer_host/pepper/pepper_socket_utils.cc +++ b/content/browser/renderer_host/pepper/pepper_socket_utils.cc
@@ -12,7 +12,6 @@ #include "base/strings/string_util.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/render_frame_host.h"
diff --git a/content/browser/renderer_host/pepper/pepper_socket_utils.h b/content/browser/renderer_host/pepper/pepper_socket_utils.h index 3f9a2d7..7f3f8336 100644 --- a/content/browser/renderer_host/pepper/pepper_socket_utils.h +++ b/content/browser/renderer_host/pepper/pepper_socket_utils.h
@@ -6,7 +6,6 @@ #define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_SOCKET_UTILS_H_ #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/common/socket_permission_request.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "ppapi/c/pp_stdint.h"
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc index 7ee1f27..b288305 100644 --- a/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc
@@ -12,7 +12,6 @@ #include "base/logging.h" #include "base/task/sequenced_task_runner.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" #include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h index 6818c797..b71e25c 100644 --- a/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h +++ b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h
@@ -16,7 +16,6 @@ #include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h"
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc index 9ac6319..984dfaf 100644 --- a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
@@ -17,7 +17,6 @@ #include "base/strings/cstring_view.h" #include "base/task/sequenced_task_runner.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" #include "content/public/browser/browser_context.h"
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h index dd800689..ac731cb87 100644 --- a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h +++ b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
@@ -18,7 +18,6 @@ #include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc index f5a4908..eba4ea1 100644 --- a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc
@@ -15,7 +15,6 @@ #include "base/metrics/histogram_macros.h" #include "base/task/sequenced_task_runner.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" #include "content/public/browser/browser_context.h"
diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h index 206f89d..ad91ddb 100644 --- a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h +++ b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h
@@ -18,7 +18,6 @@ #include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/common/content_export.h" #include "content/public/common/process_type.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
diff --git a/content/browser/renderer_host/private_network_access_util.cc b/content/browser/renderer_host/private_network_access_util.cc index 888d8be..8dc4130 100644 --- a/content/browser/renderer_host/private_network_access_util.cc +++ b/content/browser/renderer_host/private_network_access_util.cc
@@ -6,7 +6,6 @@ #include "base/command_line.h" #include "base/feature_list.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/policy_container_host.h" #include "content/common/features.h" #include "content/public/browser/content_browser_client.h" @@ -203,11 +202,11 @@ // This only handles schemes that are known to the content/ layer. // List here: content/public/common/url_constants.cc. const char* special_content_schemes[] = { - kChromeDevToolsScheme, - kChromeUIScheme, - kChromeUIUntrustedScheme, -#if BUILDFLAG(IS_CHROMEOS_ASH) - kExternalFileScheme, + kChromeDevToolsScheme, + kChromeUIScheme, + kChromeUIUntrustedScheme, +#if BUILDFLAG(IS_CHROMEOS) + kExternalFileScheme, #endif };
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 97571cc..ad80b79 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -13561,17 +13561,6 @@ return; } - // Both flags are enforced in benign renderers by the - // RuntimeEnabled=PrivateStateTokens IDL attribute (the base::Feature's value - // is tied to the RuntimeEnabledFeature's). - if (!base::FeatureList::IsEnabled(network::features::kPrivateStateTokens) && - !base::FeatureList::IsEnabled(network::features::kFledgePst)) { - mojo::ReportBadMessage( - "Attempted to get a TrustTokenQueryAnswerer with Private State Tokens " - "disabled."); - return; - } - // TODO(crbug.com/40729410): Document.hasPrivateToken is restricted to // secure contexts, so we could additionally add a check verifying that the // bind request "is coming from a secure context"---but there's currently no
diff --git a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc index 98c72d3..f68c5623 100644 --- a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
@@ -32,7 +32,6 @@ #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/process_lock.h" #include "content/browser/renderer_host/frame_tree_node.h"
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index c8c0c2c..bc2e3f9 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -69,7 +69,6 @@ #include "base/trace_event/typed_macros.h" #include "base/tracing/protos/chrome_track_event.pbzero.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/base/switches.h" #include "components/metrics/histogram_controller.h" #include "components/metrics/single_sample_metrics.h" @@ -2138,7 +2137,7 @@ std::move(receiver)); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void RenderProcessHostImpl::ReinitializeLogging( uint32_t logging_dest, base::ScopedFD log_file_descriptor) { @@ -2148,7 +2147,7 @@ mojo::PlatformHandle(std::move(log_file_descriptor)); child_process_->ReinitializeLogging(std::move(logging_settings)); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) void RenderProcessHostImpl::SetBatterySaverMode( bool battery_saver_mode_enabled) { @@ -3283,7 +3282,7 @@ switches::kDisableInProcessStackTraces, sandbox::policy::switches::kDisableSeccompFilterSandbox, sandbox::policy::switches::kNoSandbox, -#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) switches::kDisableDevShmUsage, #endif #if BUILDFLAG(IS_MAC) @@ -3489,7 +3488,7 @@ if (browser_cmd.HasSwitch(switches::kDisableGpuCompositing)) { renderer_cmd->AppendSwitch(switches::kDisableGpuCompositing); } -#elif !BUILDFLAG(IS_CHROMEOS_ASH) +#elif !BUILDFLAG(IS_CHROMEOS) // If gpu compositing is not being used, tell the renderer at startup. This // is inherently racey, as it may change while the renderer is being // launched, but the renderer will hear about the correct state eventually.
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index f938e8d6..e818b03 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -29,7 +29,6 @@ #include "base/threading/sequence_bound.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/metrics/histogram_child_process.h" #include "components/services/storage/public/cpp/buckets/bucket_id.h" #include "components/services/storage/public/cpp/buckets/bucket_info.h" @@ -354,7 +353,7 @@ #if BUILDFLAG(CLANG_PROFILING_INSIDE_SANDBOX) void DumpProfilingData(base::OnceClosure callback) override; #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void ReinitializeLogging(uint32_t logging_dest, base::ScopedFD log_file_descriptor) override; #endif
diff --git a/content/browser/renderer_host/render_process_host_unittest.cc b/content/browser/renderer_host/render_process_host_unittest.cc index 72d5b77..61fcca0 100644 --- a/content/browser/renderer_host/render_process_host_unittest.cc +++ b/content/browser/renderer_host/render_process_host_unittest.cc
@@ -13,7 +13,6 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/renderer_host/spare_render_process_host_manager_impl.h" @@ -77,7 +76,7 @@ RenderProcessHostImpl::GetExistingProcessHost(site_instance.get())); } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) TEST_F(RenderProcessHostUnitTest, RendererProcessLimit) { // This test shouldn't run with --site-per-process mode, which prohibits // the renderer process reuse this test explicitly exercises. @@ -105,7 +104,7 @@ } #endif -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) TEST_F(RenderProcessHostUnitTest, NoRendererProcessLimitOnAndroidOrChromeOS) { // Add a few dummy process hosts. static constexpr size_t kMaxRendererProcessCountForTesting = 82;
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 2889577..1dc9195 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -954,11 +954,7 @@ // <webview>, and PDF. These may have a compositor surface as well, // in which case we need to explore not the outer node only, but the inner // ones as well. - FrameTree::NodeRange node_range = - base::FeatureList::IsEnabled( - features::kInnerFrameCompositorSurfaceEviction) - ? tree.NodesIncludingInnerTreeNodes() - : tree.SubtreeNodes(root); + FrameTree::NodeRange node_range = tree.NodesIncludingInnerTreeNodes(); CollectSurfaceIdsForEvictionForFrameTreeNodeRange(node_range, ids); } else if (is_in_back_forward_cache_) { // `FrameTree::SubtreeAndInnerTreeNodes` starts with the children of `rfh`
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 4ab0948..de62d87 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -22,7 +22,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/layers/layer.h" #include "cc/trees/layer_tree_settings.h" #include "components/input/cursor_manager.h" @@ -129,7 +128,7 @@ #include "ui/linux/linux_ui.h" #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "ui/wm/core/ime_util_chromeos.h" #endif @@ -736,10 +735,10 @@ if (!window || window->GetRootWindow() != root_window) { return true; } -#elif !BUILDFLAG(IS_CHROMEOS_ASH) +#elif !BUILDFLAG(IS_CHROMEOS) if (!screen->IsWindowUnderCursor(root_window)) return true; -#endif // !BUILDFLAG(IS_CHROMEOS_ASH) +#endif // !BUILDFLAG(IS_CHROMEOS) return false; } @@ -1817,7 +1816,7 @@ } aura::Window* top_level_window = window_->GetToplevelWindow(); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) wm::EnsureWindowNotInRect(top_level_window, keyboard_occluded_bounds_); #endif @@ -2029,7 +2028,7 @@ } #endif -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) ui::TextInputClient::EditingContext RenderWidgetHostViewAura::GetTextEditingContext() { ui::TextInputClient::EditingContext editing_context; @@ -2976,9 +2975,9 @@ ui::InputMethod* input_method = GetInputMethod(); if (input_method) { input_method->DetachTextInputClient(this); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) wm::RestoreWindowBoundsOnClientFocusLost(window_->GetToplevelWindow()); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } #if BUILDFLAG(IS_WIN)
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 2042f979..75519fa 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -22,7 +22,6 @@ #include "base/scoped_observation.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/layers/deadline_policy.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" @@ -312,7 +311,7 @@ bool is_composition_committed) override; #endif -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) // Returns the editing context of the active web content. // This is currently used by TSF and ChromeOS to fetch the URL of the active // web content.
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_aura_browsertest.cc index 02296de..1d741f0 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_browsertest.cc
@@ -10,7 +10,6 @@ #include "base/test/run_until.h" #include "base/test/test_timeouts.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/devtools/protocol/devtools_protocol_test_support.h" #include "content/browser/renderer_host/delegated_frame_host.h" #include "content/browser/renderer_host/frame_tree_node.h" @@ -44,7 +43,7 @@ namespace content { namespace { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) const char kMinimalPageDataURL[] = "data:text/html,<html><head></head><body>Hello, world</body></html>"; @@ -56,7 +55,7 @@ FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(250)); run_loop.Run(); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) class FakeWebContentsDelegate : public WebContentsDelegate { public: @@ -123,7 +122,7 @@ } #endif // BUILDFLAG(IS_WIN) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewAuraBrowserTest, // TODO(crbug.com/40874148): Re-enable this test // TODO(crbug.com/40873813): Re-enable this test @@ -243,7 +242,7 @@ EXPECT_FALSE( GetDelegatedFrameHost()->stale_content_layer_->has_external_content()); } -#endif // #if BUILDFLAG(IS_CHROMEOS_ASH) +#endif // #if BUILDFLAG(IS_CHROMEOS) IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewAuraBrowserTest, SetKeyboardFocusOnTapAfterDismissingPopup) { @@ -689,7 +688,7 @@ EXPECT_FALSE(FrameIsFocused(iframe)); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Verifies that getting active input control accounts for iframe positioning. // Flaky: crbug.com/1293700 IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewAuraActiveWidgetTest,
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 832dc66..bdb00be 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -28,7 +28,6 @@ #include "base/test/with_feature_override.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/trees/render_frame_metadata.h" #include "components/input/input_router.h" #include "components/input/mouse_wheel_event_queue.h" @@ -1211,7 +1210,7 @@ widget_host_->screen_rects().at(0).second); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Checks that a popup view is destroyed when a user clicks outside of the popup // view and focus does not change. This is the case when the user clicks on the // desktop background on Chrome OS. @@ -4948,7 +4947,7 @@ ReleaseAndResetDispatchedMessages(); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Check that when accessibility virtual keyboard is enabled, windows are // shifted up when focused and restored when focus is lost. TEST_F(RenderWidgetHostViewAuraTest, VirtualKeyboardFocusEnsureCaretInRect) { @@ -5041,7 +5040,7 @@ EXPECT_EQ(view_->insets_, resized_view_insets); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) // Tests that invalid touch events are consumed and handled // synchronously.
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc index 79c4bc8..9b2da394 100644 --- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -23,7 +23,6 @@ #include "base/test/test_timeouts.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/slim/layer_tree.h" #include "cc/slim/surface_layer.h" #include "components/viz/common/features.h" @@ -1480,7 +1479,7 @@ PerformTestWithLeftRightRects(html_rect_size, copy_rect, output_size); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // On ChromeOS there is no software compositing. static const auto kTestCompositingModes = testing::Values(GL_COMPOSITING); #else
diff --git a/content/browser/scheduler/responsiveness/jank_monitor_impl.cc b/content/browser/scheduler/responsiveness/jank_monitor_impl.cc index 6047c4c..300a7cf 100644 --- a/content/browser/scheduler/responsiveness/jank_monitor_impl.cc +++ b/content/browser/scheduler/responsiveness/jank_monitor_impl.cc
@@ -8,7 +8,6 @@ #include "base/observer_list.h" #include "base/task/thread_pool.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "ui/base/ui_base_features.h"
diff --git a/content/browser/screen_orientation/screen_orientation_browsertest.cc b/content/browser/screen_orientation/screen_orientation_browsertest.cc index 6237747..de8fde5 100644 --- a/content/browser/screen_orientation/screen_orientation_browsertest.cc +++ b/content/browser/screen_orientation/screen_orientation_browsertest.cc
@@ -10,7 +10,6 @@ #include "base/command_line.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/preloading/prerender/prerender_final_status.h" #include "content/browser/preloading/prerender/prerender_host_registry.h" #include "content/browser/renderer_host/frame_tree.h" @@ -135,7 +134,7 @@ // actually support MacOS X if and when it switches to Aura. #if defined(USE_AURA) || BUILDFLAG(IS_ANDROID) // Flaky on Chrome OS: http://crbug.com/468259 -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #define MAYBE_ScreenOrientationChange DISABLED_ScreenOrientationChange #else #define MAYBE_ScreenOrientationChange ScreenOrientationChange @@ -170,7 +169,7 @@ #endif // defined(USE_AURA) || BUILDFLAG(IS_ANDROID) // Flaky on Chrome OS: http://crbug.com/468259 -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #define MAYBE_WindowOrientationChange DISABLED_WindowOrientationChange #else #define MAYBE_WindowOrientationChange WindowOrientationChange @@ -326,7 +325,7 @@ // blink::mojom::FrameWidget::EnableDeviceEmulation, which calls // RenderWidget::Resize on the renderer side. The test fakes this by directly // sending the resize message to the widget. -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #define MAYBE_ScreenOrientationInPendingMainFrame \ DISABLED_ScreenOrientationInPendingMainFrame #else
diff --git a/content/browser/screenlock_monitor/screenlock_monitor_device_source.h b/content/browser/screenlock_monitor/screenlock_monitor_device_source.h index cc460e2..ce7c518 100644 --- a/content/browser/screenlock_monitor/screenlock_monitor_device_source.h +++ b/content/browser/screenlock_monitor/screenlock_monitor_device_source.h
@@ -8,7 +8,6 @@ #include <memory> #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/screenlock_monitor/screenlock_monitor_source.h" #include "content/common/content_export.h" @@ -18,11 +17,11 @@ #include <wtsapi32.h> #endif // BUILDFLAG(IS_WIN) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include <optional> #include "components/session_manager/core/session_manager_observer.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(IS_WIN) namespace gfx { @@ -93,7 +92,7 @@ void StopListeningForScreenlock(); #endif // BUILDFLAG(IS_MAC) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) class ScreenLockListener : public session_manager::SessionManagerObserver { public: ScreenLockListener(); @@ -111,7 +110,7 @@ }; ScreenLockListener screenlock_listener_; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) }; } // namespace content
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc index fb0e8a8..d617b5e 100644 --- a/content/browser/security_exploit_browsertest.cc +++ b/content/browser/security_exploit_browsertest.cc
@@ -88,7 +88,6 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "services/network/public/cpp/features.h" #include "services/network/public/cpp/network_switches.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/mojom/fetch_api.mojom.h" @@ -1923,12 +1922,7 @@ class SecurityExploitBrowserTestWithTrustTokensEnabled : public SecurityExploitBrowserTest { public: - SecurityExploitBrowserTestWithTrustTokensEnabled() { - feature_list_.InitAndEnableFeature(network::features::kPrivateStateTokens); - } - - private: - base::test::ScopedFeatureList feature_list_; + SecurityExploitBrowserTestWithTrustTokensEnabled() = default; }; // Test that the browser correctly reports a bad message when a child frame
diff --git a/content/browser/service_worker/service_worker_internals_ui_browsertest.cc b/content/browser/service_worker/service_worker_internals_ui_browsertest.cc index 5b14f415..8c7bfae9 100644 --- a/content/browser/service_worker/service_worker_internals_ui_browsertest.cc +++ b/content/browser/service_worker/service_worker_internals_ui_browsertest.cc
@@ -12,7 +12,6 @@ #include "base/strings/string_util.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" -#include "build/chromeos_buildflags.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_test_utils.h"
diff --git a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc index fc0bc31d..689d6f69 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc +++ b/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc
@@ -10,7 +10,6 @@ #include "base/functional/bind.h" #include "base/memory/ptr_util.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/navigation_request.h" #include "content/browser/renderer_host/navigation_request_info.h" #include "content/browser/service_worker/service_worker_client.h" @@ -44,11 +43,11 @@ url.scheme())) return true; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) return url.SchemeIs(kExternalFileScheme); -#else // BUILDFLAG(IS_CHROMEOS_ASH) +#else // BUILDFLAG(IS_CHROMEOS) return false; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } // Returns true if a ServiceWorkerMainResourceLoaderInterceptor should be
diff --git a/content/browser/service_worker/service_worker_main_resource_loader_interceptor_unittest.cc b/content/browser/service_worker/service_worker_main_resource_loader_interceptor_unittest.cc index 5b7824e..5ad518d 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader_interceptor_unittest.cc +++ b/content/browser/service_worker/service_worker_main_resource_loader_interceptor_unittest.cc
@@ -4,7 +4,6 @@ #include "content/browser/service_worker/service_worker_main_resource_loader_interceptor.h" -#include "build/chromeos_buildflags.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_browser_context.h" #include "testing/gtest/include/gtest/gtest.h" @@ -89,9 +88,9 @@ TEST_F(ServiceWorkerMainResourceLoaderInterceptorTest, ShouldCreateForNavigation_ExternalFileScheme) { bool expected_handler_created = false; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) expected_handler_created = true; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) EXPECT_EQ( expected_handler_created, ShouldCreateForNavigation(GURL("externalfile:drive/doc"),
diff --git a/content/browser/session_history_browsertest.cc b/content/browser/session_history_browsertest.cc index f25a755..e73298a3 100644 --- a/content/browser/session_history_browsertest.cc +++ b/content/browser/session_history_browsertest.cc
@@ -9,7 +9,6 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/content_navigation_policy.h" #include "content/public/browser/navigation_controller.h"
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index bb97f3e..6cda8dc0 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -49,7 +49,6 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/base/math_util.h" #include "cc/input/touch_action.h" #include "components/input/input_router.h" @@ -10859,7 +10858,7 @@ // // TODO(crbug.com/40561636): Disabled on Android, Mac, and ChromeOS due to // flakiness. -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS) #define MAYBE_OOPIFDetachDuringAnimation DISABLED_OOPIFDetachDuringAnimation #else #define MAYBE_OOPIFDetachDuringAnimation OOPIFDetachDuringAnimation @@ -12550,7 +12549,7 @@ } // Touchscreen DoubleTapZoom is only supported on Android & ChromeOS at present. -#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) // A test ContentBrowserClient implementation which enforces // WebPreferences' |double_tap_to_zoom_enabled| to be true. class DoubleTapZoomContentBrowserClient @@ -12651,7 +12650,7 @@ new_page_scale = observer_a.LastRenderFrameMetadata().page_scale_factor; } while (new_page_scale < target_scale); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_ANDROID) +#endif // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) class CrossProcessNavigationObjectElementTest : public SitePerProcessBrowserTestBase,
diff --git a/content/browser/site_per_process_layout_browsertest.cc b/content/browser/site_per_process_layout_browsertest.cc index 0d5b370..ec54fb5 100644 --- a/content/browser/site_per_process_layout_browsertest.cc +++ b/content/browser/site_per_process_layout_browsertest.cc
@@ -8,7 +8,6 @@ #include "base/task/single_thread_task_runner.h" #include "base/test/gmock_expected_support.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/base/math_util.h" #include "content/browser/renderer_host/cross_process_frame_connector.h" #include "content/browser/renderer_host/render_process_host_impl.h" @@ -39,7 +38,7 @@ #include "ui/base/test/scoped_preferred_scroller_style_mac.h" #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "ui/aura/test/test_screen.h" #endif @@ -406,7 +405,7 @@ testing::Values(1.0, 1.5, 2.0)); #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, SubframeUpdateToCorrectDeviceScaleFactor) { GURL main_url(embedded_test_server()->GetURL(
diff --git a/content/browser/snapshot_browsertest.cc b/content/browser/snapshot_browsertest.cc index 2f4d0aee9..b06ca09b 100644 --- a/content/browser/snapshot_browsertest.cc +++ b/content/browser/snapshot_browsertest.cc
@@ -16,7 +16,6 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -259,10 +258,8 @@ // Linux TSAN Tests // See crbug.com/771119 // TODO(crbug.com/40834774): Fix and enable on Fuchsia. -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH) || \ - ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && \ - defined(THREAD_SANITIZER)) || \ - BUILDFLAG(IS_FUCHSIA) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA) || \ + (BUILDFLAG(IS_LINUX) && defined(THREAD_SANITIZER)) #define MAYBE_SyncMultiWindowTest DISABLED_SyncMultiWindowTest #else #define MAYBE_SyncMultiWindowTest SyncMultiWindowTest @@ -325,8 +322,7 @@ // TODO(crbug.com/40740836): recently crashes flakily on // linux_chromium_asan_rel_ng and linux-rel. // TODO(crbug.com/40834774): Fix and enable on Fuchsia. -#if (BUILDFLAG(IS_WIN) && !defined(NDEBUG)) || BUILDFLAG(IS_CHROMEOS_ASH) || \ - (BUILDFLAG(IS_CHROMEOS) && defined(THREAD_SANITIZER)) || \ +#if (BUILDFLAG(IS_WIN) && !defined(NDEBUG)) || BUILDFLAG(IS_CHROMEOS) || \ BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_FUCHSIA) #define MAYBE_AsyncMultiWindowTest DISABLED_AsyncMultiWindowTest #else
diff --git a/content/browser/speech/speech_recognition_browsertest.cc b/content/browser/speech/speech_recognition_browsertest.cc index 39fa9b9..0eb76ab 100644 --- a/content/browser/speech/speech_recognition_browsertest.cc +++ b/content/browser/speech/speech_recognition_browsertest.cc
@@ -50,13 +50,12 @@ #include "content/browser/speech/soda_speech_recognition_engine_impl.h" #include "media/base/media_switches.h" #include "media/mojo/mojom/audio_data.mojom.h" - -#if BUILDFLAG(IS_CHROMEOS_ASH) -#include "ash/constants/ash_features.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) - #endif // !BUILDFLAG(IS_FUCHSIA) +#if BUILDFLAG(IS_CHROMEOS) +#include "ash/constants/ash_features.h" +#endif // BUILDFLAG(IS_CHROMEOS) + using base::RunLoop; using CaptureCallback = media::AudioCapturerSource::CaptureCallback; @@ -198,9 +197,9 @@ /*enabled_features=*/ { media::kOnDeviceWebSpeech, -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) ash::features::kOnDeviceSpeechRecognition, -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) }, /*disabled_features=*/{}); }
diff --git a/content/browser/speech/speech_recognition_manager_impl_unittest.cc b/content/browser/speech/speech_recognition_manager_impl_unittest.cc index 98dac49..700baae2 100644 --- a/content/browser/speech/speech_recognition_manager_impl_unittest.cc +++ b/content/browser/speech/speech_recognition_manager_impl_unittest.cc
@@ -11,9 +11,9 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "ash/constants/ash_features.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) namespace content { @@ -44,9 +44,9 @@ /*enabled_features=*/ { media::kOnDeviceWebSpeech, -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) ash::features::kOnDeviceSpeechRecognition, -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) }, /*disabled_features=*/{}); }
diff --git a/content/browser/speech/tts_controller_impl.cc b/content/browser/speech/tts_controller_impl.cc index 399f6dd..e16d147 100644 --- a/content/browser/speech/tts_controller_impl.cc +++ b/content/browser/speech/tts_controller_impl.cc
@@ -20,7 +20,6 @@ #include "base/task/single_thread_task_runner.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/speech/tts_utterance_impl.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/tts_utterance.h" @@ -32,7 +31,7 @@ #include "third_party/blink/public/mojom/speech/speech_synthesis.mojom.h" #include "ui/base/l10n/l10n_util.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "content/public/browser/tts_controller_delegate.h" #endif @@ -44,7 +43,7 @@ // A value to be used to indicate that there is no length available. const int kInvalidLength = -1; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) bool VoiceIdMatches( const std::optional<TtsControllerDelegate::PreferredVoiceId>& id, const content::VoiceData& voice) { @@ -55,7 +54,7 @@ return id->name == voice.name && id->id.empty(); return id->name == voice.name && id->id == voice.engine_id; } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) TtsUtteranceImpl* AsUtteranceImpl(TtsUtterance* utterance) { return static_cast<TtsUtteranceImpl*>(utterance); @@ -380,7 +379,7 @@ } void TtsControllerImpl::OnTtsUtteranceBecameInvalid(int utterance_id) { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // This handles the case that the utterance originated from the standalone // browser becomes invalid, we need to stop RemoveUtteranceAndStopIfNeeded(utterance_id); @@ -720,7 +719,7 @@ double rate = utterance->GetContinuousParameters().rate; double pitch = utterance->GetContinuousParameters().pitch; double volume = utterance->GetContinuousParameters().volume; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) if (GetTtsControllerDelegate()) GetTtsControllerDelegate()->UpdateUtteranceDefaultsFromPrefs( utterance, &rate, &pitch, &volume); @@ -733,7 +732,7 @@ pitch = blink::mojom::kSpeechSynthesisDefaultPitch; if (volume == blink::mojom::kSpeechSynthesisDoublePrefNotSet) volume = blink::mojom::kSpeechSynthesisDefaultVolume; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) utterance->SetContinuousParameters(rate, pitch, volume); } @@ -818,12 +817,12 @@ // match, something will be returned if there are any voices. int best_score = -1; int best_score_index = -1; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) TtsControllerDelegate* delegate = GetTtsControllerDelegate(); std::unique_ptr<TtsControllerDelegate::PreferredVoiceIds> preferred_ids = delegate ? delegate->GetPreferredVoiceIdsForUtterance(utterance) : nullptr; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) for (size_t i = 0; i < voices.size(); ++i) { const content::VoiceData& voice = voices[i]; int score = 0; @@ -877,7 +876,7 @@ score += 32; } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) if (preferred_ids) { // First prefer the user's preference voice for the utterance language, // if the utterance language is specified. @@ -897,7 +896,7 @@ if (VoiceIdMatches(preferred_ids->any_locale_voice_id, voice)) score += 4; } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) // Finally, prefer system language. if (!voice.lang.empty()) { @@ -1036,7 +1035,7 @@ } } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) TtsControllerDelegate* TtsControllerImpl::GetTtsControllerDelegate() { if (delegate_) return delegate_; @@ -1051,6 +1050,6 @@ TtsControllerDelegate* delegate) { delegate_ = delegate; } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } // namespace content
diff --git a/content/browser/speech/tts_controller_impl.h b/content/browser/speech/tts_controller_impl.h index eda452a..7492a73 100644 --- a/content/browser/speech/tts_controller_impl.h +++ b/content/browser/speech/tts_controller_impl.h
@@ -18,7 +18,6 @@ #include "base/observer_list.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/common/content_export.h" #include "content/public/browser/tts_controller.h" #include "content/public/browser/tts_platform.h" @@ -30,7 +29,7 @@ namespace content { class BrowserContext; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) class TtsControllerDelegate; #endif @@ -202,7 +201,7 @@ void OnNetworkChanged( net::NetworkChangeNotifier::ConnectionType type) override; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) TtsControllerDelegate* GetTtsControllerDelegate(); void SetTtsControllerDelegateForTesting(TtsControllerDelegate* delegate); raw_ptr<TtsControllerDelegate, DanglingUntriaged> delegate_ = nullptr;
diff --git a/content/browser/speech/tts_controller_unittest.cc b/content/browser/speech/tts_controller_unittest.cc index 6ca91a2..9cffe4d 100644 --- a/content/browser/speech/tts_controller_unittest.cc +++ b/content/browser/speech/tts_controller_unittest.cc
@@ -10,7 +10,6 @@ #include "base/memory/raw_ptr.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/speech/tts_utterance_impl.h" #include "content/public/browser/tts_platform.h" #include "content/public/browser/visibility.h" @@ -22,7 +21,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/speech/speech_synthesis.mojom.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "content/public/browser/tts_controller_delegate.h" #endif @@ -180,7 +179,7 @@ int stop_called_ = 0; }; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) class MockTtsControllerDelegate : public TtsControllerDelegate { public: MockTtsControllerDelegate() = default; @@ -228,7 +227,7 @@ using TtsControllerImpl::GetMatchingVoice; using TtsControllerImpl::SpeakNextUtterance; using TtsControllerImpl::UpdateUtteranceDefaults; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) using TtsControllerImpl::SetTtsControllerDelegateForTesting; #endif using TtsControllerImpl::IsPausedForTesting; @@ -253,7 +252,7 @@ // since it has no extensions. controller()->SetTtsEngineDelegate(&engine_delegate_); #endif // !BUILDFLAG(IS_ANDROID) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) controller()->SetTtsControllerDelegateForTesting(&delegate_); #endif controller()->AddVoicesChangedDelegate(&voices_changed_); @@ -269,7 +268,7 @@ TestBrowserContext* browser_context() { return browser_context_.get(); } MockTtsEngineDelegate* engine_delegate() { return &engine_delegate_; } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) MockTtsControllerDelegate* delegate() { return &delegate_; } #endif void ReleaseTtsController() { @@ -311,13 +310,13 @@ std::unique_ptr<MockTtsPlatformImpl> platform_impl_; std::unique_ptr<TestBrowserContext> browser_context_; MockTtsEngineDelegate engine_delegate_; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) MockTtsControllerDelegate delegate_; #endif MockVoicesChangedDelegate voices_changed_; }; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) TEST_F(TtsControllerTest, TestBrowserContextRemoved) { std::vector<VoiceData> voices; VoiceData voice_data; @@ -470,7 +469,7 @@ utterance->SetEngineId("id5"); EXPECT_EQ(5, controller()->GetMatchingVoice(utterance.get(), voices)); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) TtsControllerDelegate::PreferredVoiceIds preferred_voice_ids; preferred_voice_ids.locale_voice_id.emplace("Voice7", "id7"); preferred_voice_ids.any_locale_voice_id.emplace("Android", ""); @@ -537,7 +536,7 @@ utterance->SetLang(""); EXPECT_EQ(1, controller()->GetMatchingVoice(utterance.get(), voices)); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // voice0 is matched against the system language which has no region piece. TestContentBrowserClient::GetInstance()->set_application_locale("en"); EXPECT_EQ(0, controller()->GetMatchingVoice(utterance.get(), voices)); @@ -575,7 +574,7 @@ utterance->SetLang("EN-US"); EXPECT_EQ(0, controller()->GetMatchingVoice(utterance.get(), voices)); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Add another English voice. VoiceData voice2; voice2.engine_id = "id1";
diff --git a/content/browser/speech/tts_platform_impl.cc b/content/browser/speech/tts_platform_impl.cc index 01d8de7..2a2c8922 100644 --- a/content/browser/speech/tts_platform_impl.cc +++ b/content/browser/speech/tts_platform_impl.cc
@@ -10,7 +10,6 @@ #include <string> -#include "build/chromeos_buildflags.h" namespace content {
diff --git a/content/browser/speech/tts_utterance_impl.h b/content/browser/speech/tts_utterance_impl.h index 4fd59943..2666293 100644 --- a/content/browser/speech/tts_utterance_impl.h +++ b/content/browser/speech/tts_utterance_impl.h
@@ -13,7 +13,6 @@ #include "base/memory/weak_ptr.h" #include "base/unguessable_token.h" #include "base/values.h" -#include "build/chromeos_buildflags.h" #include "content/common/content_export.h" #include "content/public/browser/tts_utterance.h"
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 0d9c53cc..07c4665 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -37,7 +37,6 @@ #include "base/threading/sequence_local_storage_slot.h" #include "base/types/optional_util.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/attribution_reporting/features.h" #include "components/leveldb_proto/public/proto_database_provider.h" #include "components/services/storage/privileged/cpp/bucket_client_info.h"
diff --git a/content/browser/tracing/tracing_controller_browsertest.cc b/content/browser/tracing/tracing_controller_browsertest.cc index f7b2f6a9..e0082f4 100644 --- a/content/browser/tracing/tracing_controller_browsertest.cc +++ b/content/browser/tracing/tracing_controller_browsertest.cc
@@ -20,7 +20,6 @@ #include "base/values.h" #include "build/build_config.h" #include "build/chromecast_buildflags.h" -#include "build/chromeos_buildflags.h" #include "content/browser/tracing/tracing_controller_impl.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -35,7 +34,7 @@ #include "services/tracing/public/cpp/trace_event_agent.h" #include "services/tracing/public/cpp/tracing_features.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "chromeos/ash/components/dbus/debug_daemon/debug_daemon_client.h" #include "chromeos/ash/components/system/fake_statistics_provider.h" #include "chromeos/ash/components/system/statistics_provider.h" @@ -104,7 +103,7 @@ enable_recording_done_callback_count_ = 0; disable_recording_done_callback_count_ = 0; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) ash::DebugDaemonClient::InitializeFake(); // Set statistic provider for hardware class tests. ash::system::StatisticsProvider::SetTestProvider( @@ -117,7 +116,7 @@ void TearDown() override { ContentBrowserTest::TearDown(); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) ash::DebugDaemonClient::Shutdown(); #endif } @@ -321,7 +320,7 @@ } } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) protected: ash::system::ScopedFakeStatisticsProvider fake_statistics_provider_; #endif @@ -412,7 +411,7 @@ ASSERT_TRUE(trace_config); EXPECT_EQ(TraceConfig().ToString(), *trace_config); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) std::string* hardware_class = metadata_json->FindString("hardware-class"); ASSERT_TRUE(hardware_class); EXPECT_EQ(*hardware_class, "test-hardware-class"); @@ -433,7 +432,7 @@ EXPECT_TRUE(KeyNotEquals(*metadata_json, "network-type", "__stripped__")); EXPECT_TRUE(KeyNotEquals(*metadata_json, "os-name", "__stripped__")); EXPECT_TRUE(KeyNotEquals(*metadata_json, "user-agent", "__stripped__")); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) EXPECT_TRUE(KeyNotEquals(*metadata_json, "hardware-class", "__stripped__")); #endif @@ -495,7 +494,7 @@ } // Only CrOS and Cast support system tracing. -#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CASTOS) +#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_CASTOS) #define MAYBE_SystemTraceEvents SystemTraceEvents #else #define MAYBE_SystemTraceEvents DISABLED_SystemTraceEvents
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc index 65b2d7f..266f7da 100644 --- a/content/browser/tracing/tracing_controller_impl.cc +++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -34,7 +34,6 @@ #include "base/values.h" #include "base/version_info/version_info.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/tracing/common/trace_to_console.h" #include "components/tracing/common/tracing_switches.h" #include "components/variations/active_field_trials.h" @@ -63,7 +62,7 @@ #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h" #include "v8/include/v8-version-string.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "chromeos/ash/components/system/statistics_provider.h" #include "content/browser/tracing/cros_tracing_agent.h" #endif @@ -191,7 +190,7 @@ AddAgents(); g_tracing_controller = this; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Bind hwclass once the statistics are available. ash::system::StatisticsProvider::GetInstance() ->ScheduleOnMachineStatisticsLoaded( @@ -209,7 +208,7 @@ tracing::TracedProcessImpl::GetInstance()->SetTaskRunner( base::SequencedTaskRunner::GetCurrentDefault()); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) agents_.push_back(std::make_unique<CrOSTracingAgent>()); #elif defined(CAST_TRACING_AGENT) agents_.push_back(std::make_unique<CastTracingAgent>()); @@ -302,13 +301,13 @@ #endif // OS -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) metadata_dict.Set("os-name", "CrOS"); if (are_statistics_loaded_) metadata_dict.Set("hardware-class", hardware_class_); #else metadata_dict.Set("os-name", base::SysInfo::OperatingSystemName()); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) metadata_dict.Set("os-version", base::SysInfo::OperatingSystemVersion()); #if BUILDFLAG(IS_WIN) if (base::win::OSInfo::GetArchitecture() == @@ -587,7 +586,7 @@ CompleteFlush(); } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void TracingControllerImpl::OnMachineStatisticsLoaded() { if (const std::optional<std::string_view> hardware_class = ash::system::StatisticsProvider::GetInstance()->GetMachineStatistic(
diff --git a/content/browser/tracing/tracing_controller_impl.h b/content/browser/tracing/tracing_controller_impl.h index 2845e931..1b4c2c3 100644 --- a/content/browser/tracing/tracing_controller_impl.h +++ b/content/browser/tracing/tracing_controller_impl.h
@@ -16,7 +16,6 @@ #include "base/task/task_traits.h" #include "base/timer/timer.h" #include "base/values.h" -#include "build/chromeos_buildflags.h" #include "content/common/content_export.h" #include "content/public/browser/tracing_controller.h" #include "mojo/public/cpp/bindings/receiver.h" @@ -99,7 +98,7 @@ void InitStartupTracingForDuration(); void EndStartupTracing(); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void OnMachineStatisticsLoaded(); #endif @@ -115,7 +114,7 @@ bool is_data_complete_ = false; bool read_buffers_complete_ = false; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) bool are_statistics_loaded_ = false; std::string hardware_class_; base::WeakPtrFactory<TracingControllerImpl> weak_ptr_factory_{this};
diff --git a/content/browser/utility_process_sandbox_browsertest.cc b/content/browser/utility_process_sandbox_browsertest.cc index 5c3d43528..2d0027e 100644 --- a/content/browser/utility_process_sandbox_browsertest.cc +++ b/content/browser/utility_process_sandbox_browsertest.cc
@@ -11,7 +11,6 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/utility_process_host.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -28,9 +27,9 @@ #include "sandbox/policy/sandbox_type.h" #include "sandbox/policy/switches.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "chromeos/ash/components/assistant/buildflags.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) using sandbox::mojom::Sandbox; using sandbox::policy::SandboxLinux; @@ -121,17 +120,17 @@ } case Sandbox::kAudio: -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) case Sandbox::kHardwareVideoDecoding: -#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS) case Sandbox::kIme: case Sandbox::kTts: case Sandbox::kNearby: #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) case Sandbox::kLibassistant: #endif // BUILDFLAG(ENABLE_CROS_LIBASSISTANT) -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(IS_LINUX) case Sandbox::kVideoEffects: case Sandbox::kOnDeviceTranslation: @@ -168,9 +167,8 @@ }; IN_PROC_BROWSER_TEST_P(UtilityProcessSandboxBrowserTest, VerifySandboxType) { -#if BUILDFLAG(IS_LINUX) || \ - (BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(USE_VAAPI) && \ - !BUILDFLAG(USE_V4L2_CODEC)) +#if BUILDFLAG(IS_LINUX) || (BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(USE_VAAPI) && \ + !BUILDFLAG(USE_V4L2_CODEC)) if (GetParam() == Sandbox::kHardwareVideoDecoding) { // TODO(b/195769334): On Linux, this test fails with // Sandbox::kHardwareVideoDecoding because the pre-sandbox hook needs Ozone
diff --git a/content/browser/utility_sandbox_delegate.cc b/content/browser/utility_sandbox_delegate.cc index d8ef151..ab7c6ee 100644 --- a/content/browser/utility_sandbox_delegate.cc +++ b/content/browser/utility_sandbox_delegate.cc
@@ -8,7 +8,6 @@ #include "base/check.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/common/features.h" #include "content/public/common/sandboxed_process_launcher_delegate.h" #include "content/public/common/zygote/zygote_buildflags.h" @@ -25,9 +24,9 @@ #include "sandbox/policy/sandbox_type.h" #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "chromeos/ash/components/assistant/buildflags.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(IS_MAC) #include "base/mac/process_requirement.h" @@ -78,20 +77,18 @@ #if BUILDFLAG(IS_FUCHSIA) sandbox_type_ == sandbox::mojom::Sandbox::kVideoCapture || #endif -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH) - sandbox_type_ == sandbox::mojom::Sandbox::kHardwareVideoDecoding || -#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + sandbox_type_ == sandbox::mojom::Sandbox::kHardwareVideoDecoding || sandbox_type_ == sandbox::mojom::Sandbox::kHardwareVideoEncoding || #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) sandbox_type_ == sandbox::mojom::Sandbox::kIme || sandbox_type_ == sandbox::mojom::Sandbox::kTts || sandbox_type_ == sandbox::mojom::Sandbox::kNearby || #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) sandbox_type_ == sandbox::mojom::Sandbox::kLibassistant || #endif // BUILDFLAG(ENABLE_CROS_LIBASSISTANT) -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \ BUILDFLAG(IS_WIN) sandbox_type_ == sandbox::mojom::Sandbox::kScreenAI || @@ -146,20 +143,18 @@ // process upon startup. if (sandbox_type_ == sandbox::mojom::Sandbox::kNetwork || sandbox_type_ == sandbox::mojom::Sandbox::kOnDeviceModelExecution || -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH) - sandbox_type_ == sandbox::mojom::Sandbox::kHardwareVideoDecoding || -#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + sandbox_type_ == sandbox::mojom::Sandbox::kHardwareVideoDecoding || sandbox_type_ == sandbox::mojom::Sandbox::kHardwareVideoEncoding || #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) sandbox_type_ == sandbox::mojom::Sandbox::kIme || sandbox_type_ == sandbox::mojom::Sandbox::kTts || sandbox_type_ == sandbox::mojom::Sandbox::kNearby || #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) sandbox_type_ == sandbox::mojom::Sandbox::kLibassistant || #endif // BUILDFLAG(ENABLE_CROS_LIBASSISTANT) -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) sandbox_type_ == sandbox::mojom::Sandbox::kAudio || #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \ BUILDFLAG(IS_WIN)
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index c2f0752..ed31bcc 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -49,7 +49,6 @@ #include "base/trace_event/optional_trace_event.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/input/browser_controls_offset_tags_info.h" #include "components/attribution_reporting/features.h" #include "components/download/public/common/download_stats.h"
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index ad94b8f..2534ebe9 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -22,7 +22,6 @@ #include "base/test/test_future.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/download/public/common/download_url_parameters.h" #include "components/input/native_web_keyboard_event.h" #include "content/browser/child_process_security_policy_impl.h"
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index e6e75281..2d0345e 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -698,7 +698,7 @@ void WebContentsViewAura::PrepareDropData( DropData* drop_data, const ui::OSExchangeData& data) const { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // TODO(b/256022714): Using `IsRendererTainted()` breaks the Files app. Always // setting this to false is currently believed to be safe-ish because ChromeOS // separates URL and filename metadata and does not implement the DownloadURL
diff --git a/content/browser/web_contents/web_contents_view_aura_browsertest.cc b/content/browser/web_contents/web_contents_view_aura_browsertest.cc index dcfc9d6..ecb635fe 100644 --- a/content/browser/web_contents/web_contents_view_aura_browsertest.cc +++ b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
@@ -21,7 +21,6 @@ #include "base/test/test_timeouts.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/navigation_controller_impl.h" #include "content/browser/renderer_host/navigation_entry_impl.h" #include "content/browser/renderer_host/overscroll_controller.h" @@ -480,7 +479,7 @@ // Disabled because the test always fails the first time it runs on the Win Aura // bots, and usually but not always passes second-try (See crbug.com/179532). // Flaky on CrOS, Linux, and Fuchsia as well: https://crbug.com/856079 -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_LINUX) || \ +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || \ BUILDFLAG(IS_FUCHSIA) #define MAYBE_QuickOverscrollDirectionChange \ DISABLED_QuickOverscrollDirectionChange
diff --git a/content/browser/web_contents/web_contents_view_aura_unittest.cc b/content/browser/web_contents/web_contents_view_aura_unittest.cc index c9b1669..3ebe2328 100644 --- a/content/browser/web_contents/web_contents_view_aura_unittest.cc +++ b/content/browser/web_contents/web_contents_view_aura_unittest.cc
@@ -15,7 +15,6 @@ #include "base/test/scoped_command_line.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/common/content_features.h" @@ -385,7 +384,7 @@ // Simulate the drag originating in the renderer process, in which case // any file data should be filtered out (anchor drag scenario) except in - // CHROMEOS_ASH. + // CHROMEOS. data->MarkRendererTaintedFromOrigin(url::Origin()); ui::DropTargetEvent event(*data.get(), kClientPt, kScreenPt, @@ -405,7 +404,7 @@ EXPECT_EQ(string_data, view->current_drag_data_->text); #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) ASSERT_FALSE(view->current_drag_data_->filenames.empty()); #else ASSERT_TRUE(view->current_drag_data_->filenames.empty()); @@ -437,8 +436,8 @@ EXPECT_EQ(string_data, drop_complete_data_->drop_data.text); #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) - // CHROMEOS_ASH never filters out files from a drop, even if the drag +#if BUILDFLAG(IS_CHROMEOS) + // CHROMEOS never filters out files from a drop, even if the drag // originated from a renderer, because otherwise, it breaks the Files app. ASSERT_FALSE(drop_complete_data_->drop_data.filenames.empty()); #else @@ -768,7 +767,7 @@ } #endif // BUILDFLAG(IS_WIN) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) TEST_F(WebContentsViewAuraTest, StartDragging) { const char kGmailUrl[] = "http://mail.google.com/"; @@ -799,7 +798,7 @@ EXPECT_EQ(*(exchange_data->GetSource()->GetURL()), GURL(kGmailUrl)); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) TEST_F(WebContentsViewAuraTest, RejectDragFromPrivilegedWebContentsToNonPrivilegedWebContents) {
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc index b91c8044..e5e4fe82 100644 --- a/content/browser/webauth/authenticator_impl_unittest.cc +++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -53,7 +53,6 @@ #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "components/cbor/reader.h" #include "components/cbor/values.h" #include "components/ukm/test_ukm_recorder.h"
diff --git a/content/browser/webauth/is_uvpaa.cc b/content/browser/webauth/is_uvpaa.cc index 10cdbb66..5329b51 100644 --- a/content/browser/webauth/is_uvpaa.cc +++ b/content/browser/webauth/is_uvpaa.cc
@@ -6,7 +6,6 @@ #include "base/feature_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/authenticator_request_client_delegate.h" #include "content/public/common/content_client.h" #include "device/fido/features.h"
diff --git a/content/browser/webauth/is_uvpaa.h b/content/browser/webauth/is_uvpaa.h index 09907f0..95748acd 100644 --- a/content/browser/webauth/is_uvpaa.h +++ b/content/browser/webauth/is_uvpaa.h
@@ -7,7 +7,6 @@ #include "base/functional/callback.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/common/content_export.h" #if BUILDFLAG(IS_MAC)
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index dc1d0acf..a2035fd 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -1266,7 +1266,7 @@ if (get_info_it->second.provider->format) { // If a token format was specified, make sure that the configURL // supports it as well as the feature is enabled. - if (!IsFedCmIdPRegistrationEnabled() || + if (!IsFedCmDelegationEnabled() || !base::Contains(fetch_result.metadata->formats, kVcSdJwt)) { OnFetchDataForIdpFailed( std::move(idp_info), @@ -2307,7 +2307,7 @@ std::string query; if (idp_blindness) { // Checked previously. - DCHECK(IsFedCmIdPRegistrationEnabled()); + DCHECK(IsFedCmDelegationEnabled()); // Creates a throw away private key for a one-time use for // a single presentation. The public key gets sent to the @@ -2743,7 +2743,7 @@ void FederatedAuthRequestImpl::ProcessSdJwt(const GURL& config_url, const std::string& token) { // Checked previously. - DCHECK(IsFedCmIdPRegistrationEnabled()); + DCHECK(IsFedCmDelegationEnabled()); auto value = sdjwt::SdJwt::Parse(token); if (!value) {
diff --git a/content/browser/webid/flags.cc b/content/browser/webid/flags.cc index d274c426..fd60d46f 100644 --- a/content/browser/webid/flags.cc +++ b/content/browser/webid/flags.cc
@@ -42,6 +42,10 @@ return base::FeatureList::IsEnabled(features::kFedCmSelectiveDisclosure); } +bool IsFedCmDelegationEnabled() { + return base::FeatureList::IsEnabled(features::kFedCmDelegation); +} + bool IsFedCmIdPRegistrationEnabled() { return base::FeatureList::IsEnabled(features::kFedCmIdPRegistration); }
diff --git a/content/browser/webid/flags.h b/content/browser/webid/flags.h index 34a80119..5784993 100644 --- a/content/browser/webid/flags.h +++ b/content/browser/webid/flags.h
@@ -35,6 +35,9 @@ // Whether the Selective Disclosure API is enabled. bool IsFedCmSelectiveDisclosureEnabled(); +// Whether the Delegation API is enabled. +bool IsFedCmDelegationEnabled(); + // Whether the IdP Registration API is enabled. bool IsFedCmIdPRegistrationEnabled();
diff --git a/content/browser/webid/webid_browsertest.cc b/content/browser/webid/webid_browsertest.cc index b81271b..265cd3c 100644 --- a/content/browser/webid/webid_browsertest.cc +++ b/content/browser/webid/webid_browsertest.cc
@@ -1823,6 +1823,7 @@ std::vector<base::test::FeatureRef> features; features.push_back(features::kFedCm); + features.push_back(features::kFedCmDelegation); // Needs the fields API features.push_back(features::kFedCmAuthz); // Intended to be used in Active mode
diff --git a/content/browser/webrtc/webrtc_browsertest.cc b/content/browser/webrtc/webrtc_browsertest.cc index c2d4acee..3ca230d 100644 --- a/content/browser/webrtc/webrtc_browsertest.cc +++ b/content/browser/webrtc/webrtc_browsertest.cc
@@ -8,7 +8,6 @@ #include "base/test/scoped_feature_list.h" #include "base/threading/platform_thread.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/webrtc/webrtc_content_browsertest_base.h" #include "content/public/browser/network_service_util.h"
diff --git a/content/browser/webrtc/webrtc_content_browsertest_base.cc b/content/browser/webrtc/webrtc_content_browsertest_base.cc index cfd161ef..f74dcb3 100644 --- a/content/browser/webrtc/webrtc_content_browsertest_base.cc +++ b/content/browser/webrtc/webrtc_content_browsertest_base.cc
@@ -10,7 +10,6 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/audio_service.h" #include "content/public/common/content_switches.h" @@ -21,7 +20,7 @@ #include "media/base/media_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "chromeos/ash/components/audio/cras_audio_handler.h" #include "chromeos/ash/components/dbus/audio/cras_audio_client.h" #endif @@ -39,7 +38,7 @@ void WebRtcContentBrowserTestBase::SetUp() { // We need pixel output when we dig pixels out of video tags for verification. EnablePixelOutput(); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) ash::CrasAudioClient::InitializeFake(); ash::CrasAudioHandler::InitializeForTesting(); #endif @@ -50,7 +49,7 @@ void WebRtcContentBrowserTestBase::TearDown() { ContentBrowserTest::TearDown(); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) ash::CrasAudioHandler::Shutdown(); ash::CrasAudioClient::Shutdown(); #endif
diff --git a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc index fac490b6..28c5c29 100644 --- a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc +++ b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
@@ -14,7 +14,6 @@ #include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/browser/browser_main_loop.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/web_contents/web_contents_impl.h"
diff --git a/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc b/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc index 64ac366..e000588 100644 --- a/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc +++ b/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc
@@ -6,7 +6,6 @@ #include "base/strings/stringprintf.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/video_capture_service.h" #include "content/public/common/content_features.h"
diff --git a/content/browser/webui/shared_resources_data_source.cc b/content/browser/webui/shared_resources_data_source.cc index 20b4b20..e7f7f086 100644 --- a/content/browser/webui/shared_resources_data_source.cc +++ b/content/browser/webui/shared_resources_data_source.cc
@@ -11,14 +11,13 @@ #include <set> -#include "build/chromeos_buildflags.h" #include "content/public/browser/web_ui_data_source.h" #include "services/network/public/mojom/content_security_policy.mojom.h" #include "ui/base/webui/web_ui_util.h" #include "ui/resources/grit/webui_resources.h" #include "ui/resources/grit/webui_resources_map.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "ash/webui/grit/ash_webui_common_resources_map.h" #include "chromeos/ash/grit/ash_resources.h" #include "chromeos/ash/grit/ash_resources_map.h" @@ -34,7 +33,7 @@ namespace { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) const std::set<int> GetContentResourceIds() { return std::set<int>{ IDR_UNGUESSABLE_TOKEN_MOJO_JS, @@ -71,7 +70,7 @@ source->AddResourcePath(resource.path, resource.id); } } -#endif // !BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } // namespace @@ -84,7 +83,7 @@ // they are only used by one UI) or in //ui/webui/resources/mojo:build_ts // (if used by multiple UIs). source->AddResourcePaths(kWebuiResources); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) source->AddResourcePaths(kAshWebuiCommonResources); // Deprecated -lite style mojo bindings. source->AddResourcePaths(kMojoBindingsResources); @@ -94,7 +93,7 @@ kChromeosResourcesSize, source); AddResources(GetAshMojoResourceIds(), kAshResources, kAshResourcesSize, source); -#endif // !BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) } } // namespace content
diff --git a/content/browser/webui/web_ui_mojo_browsertest.cc b/content/browser/webui/web_ui_mojo_browsertest.cc index b7e6632..9b9c7c8 100644 --- a/content/browser/webui/web_ui_mojo_browsertest.cc +++ b/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -50,7 +50,7 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "third_party/blink/public/common/chrome_debug_urls.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) #include "content/test/data/web_ui_test.test-mojom.h" #include "content/test/data/web_ui_test_types.test-mojom.h" #endif @@ -62,7 +62,7 @@ const char kMojoWebUiTsHost[] = "mojo-web-ui-ts"; const char kDummyWebUiHost[] = "dummy-web-ui"; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) class WebUIMojoTestCacheImpl : public mojom::WebUIMojoTestCache { public: explicit WebUIMojoTestCacheImpl( @@ -161,7 +161,7 @@ {BindingsPolicyValue::kMojoWebUi})) : WebUIController(web_ui) { web_ui->SetBindings(bindings); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) { WebUIDataSource* data_source = WebUIDataSource::CreateAndAdd( web_ui->GetWebContents()->GetBrowserContext(), kMojoWebUiHost); @@ -199,7 +199,7 @@ TestWebUIController& operator=(const TestWebUIController&) = delete; protected: -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) std::unique_ptr<WebUIMojoTestCacheImpl> cache_; #endif std::unique_ptr<WebUITsMojoTestCacheImpl> ts_cache_; @@ -214,7 +214,7 @@ : TestWebUIController(web_ui) {} ~CacheTestWebUIController() override = default; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void BindInterface( mojo::PendingReceiver<mojom::WebUIMojoTestCache> receiver) { cache_ = std::make_unique<WebUIMojoTestCacheImpl>(std::move(receiver)); @@ -225,7 +225,7 @@ void BindInterface( mojo::PendingReceiver<mojom::WebUITsMojoTestCache> receiver) { ts_cache_ = std::make_unique<WebUITsMojoTestCacheImpl>(std::move(receiver)); -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) ASSERT_FALSE(cache_); #endif } @@ -317,7 +317,7 @@ void RegisterBrowserInterfaceBindersForFrame( RenderFrameHost* render_frame_host, mojo::BinderMapWithContext<content::RenderFrameHost*>* map) override { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) RegisterWebUIControllerInterfaceBinder<mojom::WebUIMojoTestCache, CacheTestWebUIController>(map); #endif @@ -369,7 +369,7 @@ // Test both JS and TS on Ash, since Ash widely uses both types of WebUI // bindings. Test TS only on other platforms. -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) INSTANTIATE_TEST_SUITE_P(All, WebUIMojoTest, testing::Bool()); #else INSTANTIATE_TEST_SUITE_P(All, WebUIMojoTest, testing::Values(true));
diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc index 8eca918..bd1013c 100644 --- a/content/browser/zygote_host/zygote_host_impl_linux.cc +++ b/content/browser/zygote_host/zygote_host_impl_linux.cc
@@ -16,7 +16,6 @@ #include "base/strings/string_number_conversions.h" #include "base/types/fixed_array.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "content/common/zygote/zygote_commands_linux.h" #include "content/common/zygote/zygote_communication_linux.h" #include "content/common/zygote/zygote_handle_impl_linux.h"
diff --git a/content/browser/zygote_host/zygote_host_impl_linux.h b/content/browser/zygote_host/zygote_host_impl_linux.h index 720d823..8ef884a 100644 --- a/content/browser/zygote_host/zygote_host_impl_linux.h +++ b/content/browser/zygote_host/zygote_host_impl_linux.h
@@ -15,7 +15,6 @@ #include "base/process/launch.h" #include "base/process/process_handle.h" #include "base/synchronization/lock.h" -#include "build/chromeos_buildflags.h" #include "content/common/content_export.h" #include "content/public/browser/zygote_host/zygote_host_linux.h"
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 93e49ca..341947d 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -214,6 +214,8 @@ kSetOnlyIfOverridden}, {wf::EnableFedCmAuthz, raw_ref(features::kFedCmAuthz), kSetOnlyIfOverridden}, + {wf::EnableFedCmDelegation, raw_ref(features::kFedCmDelegation), + kDefault}, {wf::EnableFedCmIdPRegistration, raw_ref(features::kFedCmIdPRegistration), kDefault}, {wf::EnableFedCmIdpSigninStatus, @@ -542,37 +544,6 @@ WebRuntimeFeatures::EnableBackForwardCache( content::IsBackForwardCacheEnabled()); - - if (base::FeatureList::IsEnabled(network::features::kPrivateStateTokens)) { - WebRuntimeFeatures::EnablePrivateStateTokens(true); - WebRuntimeFeatures::EnablePrivateStateTokensAlwaysAllowIssuance(true); - } else if (base::FeatureList::IsEnabled(network::features::kFledgePst)) { - // See https://bit.ly/configuring-trust-tokens. - using network::features::TrustTokenOriginTrialSpec; - switch ( - network::features::kTrustTokenOperationsRequiringOriginTrial.Get()) { - case TrustTokenOriginTrialSpec::kOriginTrialNotRequired: - // Setting PrivateStateTokens=true enables the Trust Tokens interface; - // PrivateStateTokensAlwaysAllowIssuance disables a runtime check - // during issuance that the origin trial is active (see - // blink/.../trust_token_issuance_authorization.h). - WebRuntimeFeatures::EnablePrivateStateTokens(true); - WebRuntimeFeatures::EnablePrivateStateTokensAlwaysAllowIssuance(true); - break; - case TrustTokenOriginTrialSpec::kAllOperationsRequireOriginTrial: - // The origin trial itself will be responsible for enabling the - // PrivateStateTokens RuntimeEnabledFeature. - WebRuntimeFeatures::EnablePrivateStateTokens(false); - WebRuntimeFeatures::EnablePrivateStateTokensAlwaysAllowIssuance(false); - break; - case TrustTokenOriginTrialSpec::kOnlyIssuanceRequiresOriginTrial: - // At issuance, a runtime check will be responsible for checking that - // the origin trial is present. - WebRuntimeFeatures::EnablePrivateStateTokens(true); - WebRuntimeFeatures::EnablePrivateStateTokensAlwaysAllowIssuance(false); - break; - } - } } // Ensures that the various ways of enabling/disabling features do not produce
diff --git a/content/common/features.cc b/content/common/features.cc index e3298ec..ffd508e0 100644 --- a/content/common/features.cc +++ b/content/common/features.cc
@@ -261,14 +261,6 @@ "InMemoryCodeCache", base::FEATURE_DISABLED_BY_DEFAULT); -// During compositor frame eviction, collect not only the surfaces that are -// reachable from the main frame tree, but also recurse into inner -// frames. Otherwise only toplevel frames and OOPIF are handled, and other -// cases, e.g. PDF tiles are ignored. See https://crbug.com/1360351 for details. -BASE_FEATURE(kInnerFrameCompositorSurfaceEviction, - "InnerFrameCompositorSurfaceEviction", - base::FEATURE_ENABLED_BY_DEFAULT); - // Enables the ability to use the updateIfOlderThanMs field in the trusted // bidding response to trigger a post-auction update if the group has been // updated more recently than updateIfOlderThanMs milliseconds, bypassing the
diff --git a/content/common/features.h b/content/common/features.h index 2db9b65..fce93d23 100644 --- a/content/common/features.h +++ b/content/common/features.h
@@ -70,7 +70,6 @@ #endif CONTENT_EXPORT BASE_DECLARE_FEATURE(kInMemoryCodeCache); -CONTENT_EXPORT BASE_DECLARE_FEATURE(kInnerFrameCompositorSurfaceEviction); CONTENT_EXPORT BASE_DECLARE_FEATURE(kInterestGroupUpdateIfOlderThan); #if BUILDFLAG(IS_MAC) CONTENT_EXPORT BASE_DECLARE_FEATURE(kIOSurfaceCapturer);
diff --git a/content/common/service_worker/race_network_request_url_loader_client.cc b/content/common/service_worker/race_network_request_url_loader_client.cc index fef5441..188ba92 100644 --- a/content/common/service_worker/race_network_request_url_loader_client.cc +++ b/content/common/service_worker/race_network_request_url_loader_client.cc
@@ -29,6 +29,10 @@ "ServiceWorker.LoadTiming.MainFrame.MainResource"; const char kSubresourceHistogramLoadTiming[] = "ServiceWorker.LoadTiming.Subresource"; +const char kMainResourceHistogramForRaceNetworkFetchEvent[] = + "ServiceWorker.FetchEvent.MainResource.RaceNetworkRequest"; +const char kSubresourceHistogramForRaceNetworkFetchEvent[] = + "ServiceWorker.FetchEvent.Subresource.RaceNetworkRequest"; } // namespace ServiceWorkerRaceNetworkRequestURLLoaderClient:: @@ -206,15 +210,12 @@ TRACE_ID_LOCAL(this), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "url", request_.url, "state", state_); - if (owner_->IsMainResourceLoader()) { - base::UmaHistogramBoolean( - "ServiceWorker.FetchEvent.MainResource.RaceNetworkRequest.Redirect", - redirected_); - } else { - base::UmaHistogramBoolean( - "ServiceWorker.FetchEvent.Subresource.RaceNetworkRequest.Redirect", - redirected_); - } + base::UmaHistogramBoolean( + base::StrCat({owner_->IsMainResourceLoader() + ? kMainResourceHistogramForRaceNetworkFetchEvent + : kSubresourceHistogramForRaceNetworkFetchEvent, + ".Redirect"}), + redirected_); switch (data_consume_policy_) { case DataConsumePolicy::kTeeResponse: @@ -370,6 +371,17 @@ read_buffer_manager_->IsWatching()) { read_buffer_manager_->CancelWatching(); } + } else if (clone_response_for_fetch_handler_completed_) { + // In some scenario, there is a case that data clonings for both network and + // fetch handler were finished, but still waiting for `OnComplete()` from + // the original resource loading. We need to call `OnComplete()` to complete + // the fetch handler if it's not called yet. crbug.com/384414080 for more + // contexts. + // + // Note: This is needed only when the + // ServiceWorkerStaticRouterRaceNetworkRequestPerformanceImprovement feature + // is enabled. + forwarding_client_->OnComplete(completion_status_.value()); } } @@ -691,9 +703,14 @@ void ServiceWorkerRaceNetworkRequestURLLoaderClient:: OnCloneCompletedForFetchHandler() { - CHECK(completion_status_.has_value()); - forwarding_client_->OnComplete(completion_status_.value()); - write_buffer_manager_for_fetch_handler_.ResetProducer(); + clone_response_for_fetch_handler_completed_ = true; + if (completion_status_.has_value()) { + // If `completion_status_` already exists, which means the resource load was + // already completed. Then the resource load for fetch handler should be + // completed as well. + forwarding_client_->OnComplete(completion_status_.value()); + write_buffer_manager_for_fetch_handler_.ResetProducer(); + } } void ServiceWorkerRaceNetworkRequestURLLoaderClient::TransitionState(
diff --git a/content/common/service_worker/race_network_request_url_loader_client.h b/content/common/service_worker/race_network_request_url_loader_client.h index 9024cde9..a1979d30 100644 --- a/content/common/service_worker/race_network_request_url_loader_client.h +++ b/content/common/service_worker/race_network_request_url_loader_client.h
@@ -249,6 +249,7 @@ std::optional<base::TimeTicks> fetch_handler_end_time_; std::optional<bool> is_fetch_handler_fallback_; bool is_main_resource_; + bool clone_response_for_fetch_handler_completed_ = false; base::TimeTicks request_start_; base::Time request_start_time_;
diff --git a/content/common/skia_utils.cc b/content/common/skia_utils.cc index ee8b8d1..2b145db 100644 --- a/content/common/skia_utils.cc +++ b/content/common/skia_utils.cc
@@ -24,11 +24,6 @@ // allocation that exceeds this limit. const size_t kImageCacheSingleAllocationByteLimit = 64 * 1024 * 1024; -// Decreases the size of the font cache to 1MiB. -BASE_FEATURE(kSmallerFontCache, - "SmallerFontCache", - base::FEATURE_ENABLED_BY_DEFAULT); - } // namespace void InitializeSkia() { @@ -40,12 +35,13 @@ } const int kMB = 1024 * 1024; + + // Could also reduce the maximum number of cached strikes, but the intent + // being to reduce memory usage, only control cache memory usage. + SkGraphics::SetFontCacheLimit(kMB); + +#if !BUILDFLAG(IS_ANDROID) size_t font_cache_limit; -#if BUILDFLAG(IS_ANDROID) - font_cache_limit = - base::SysInfo::IsLowEndDeviceOrPartialLowEndModeEnabled() ? kMB : 8 * kMB; - SkGraphics::SetFontCacheLimit(font_cache_limit); -#else if (cmd.HasSwitch(switches::kSkiaFontCacheLimitMb)) { if (base::StringToSizeT( cmd.GetSwitchValueASCII(switches::kSkiaFontCacheLimitMb), @@ -64,12 +60,6 @@ } #endif - if (base::FeatureList::IsEnabled(kSmallerFontCache)) { - // Could also reduce the maximum number of cached strikes, but the intent - // being to reduce memory usage, only control cache memory usage. - SkGraphics::SetFontCacheLimit(kMB); - } - InitSkiaEventTracer(); base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 76fd051..c1995d3 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -450,6 +450,11 @@ "FedCmButtonMode", base::FEATURE_ENABLED_BY_DEFAULT); +// Enables usage of the FedCM Delegation API. +BASE_FEATURE(kFedCmDelegation, + "FedCmDelegation", + base::FEATURE_DISABLED_BY_DEFAULT); + // Enables usage of the FedCM IdP Registration API. BASE_FEATURE(kFedCmIdPRegistration, "FedCmIdPregistration", @@ -537,11 +542,6 @@ "NetworkQualityEstimatorWebHoldback", base::FEATURE_DISABLED_BY_DEFAULT); -// Determines if an extra brand version pair containing possibly escaped double -// quotes and escaped backslashed should be added to the Sec-CH-UA header -// (activated by kUserAgentClientHint) -BASE_FEATURE(kGreaseUACH, "GreaseUACH", base::FEATURE_ENABLED_BY_DEFAULT); - // Whether GuestViews (see components/guest_view/README.md) are implemented // using MPArch inner pages. See https://crbug.com/40202416 BASE_FEATURE(kGuestViewMPArch, @@ -1370,12 +1370,6 @@ base::FEATURE_DISABLED_BY_DEFAULT #endif ); - -// Kill switch for allowing webview to suppress tap immediately after fling, -// matching chrome behavior. -BASE_FEATURE(kWebViewSuppressTapDuringFling, - "WebViewSuppressTapDuringFling", - base::FEATURE_ENABLED_BY_DEFAULT); #endif // BUILDFLAG(IS_ANDROID) #if BUILDFLAG(IS_MAC)
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index c257f9f..23c1ed2 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -113,6 +113,7 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCm); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmAuthz); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmButtonMode); +CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmDelegation); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmIdPRegistration); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmIdpSigninStatusEnabled); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmMetricsEndpoint); @@ -130,7 +131,6 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kWebIdentityDigitalCredentials); CONTENT_EXPORT BASE_DECLARE_FEATURE(kWebIdentityDigitalCredentialsCreation); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFractionalScrollOffsets); -CONTENT_EXPORT BASE_DECLARE_FEATURE(kGreaseUACH); CONTENT_EXPORT BASE_DECLARE_FEATURE(kGuestViewMPArch); CONTENT_EXPORT BASE_DECLARE_FEATURE(kIdbPrioritizeForegroundClients); CONTENT_EXPORT BASE_DECLARE_FEATURE(kIgnoreDuplicateNavs); @@ -303,7 +303,6 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kReduceGpuPriorityOnBackground); CONTENT_EXPORT BASE_DECLARE_FEATURE(kSmartZoom); CONTENT_EXPORT BASE_DECLARE_FEATURE(kUserMediaScreenCapturing); -CONTENT_EXPORT BASE_DECLARE_FEATURE(kWebViewSuppressTapDuringFling); #endif // BUILDFLAG(IS_ANDROID) #if BUILDFLAG(IS_MAC)
diff --git a/content/services/auction_worklet/register_ad_beacon_bindings.cc b/content/services/auction_worklet/register_ad_beacon_bindings.cc index df0e711..20b2fb2 100644 --- a/content/services/auction_worklet/register_ad_beacon_bindings.cc +++ b/content/services/auction_worklet/register_ad_beacon_bindings.cc
@@ -14,6 +14,7 @@ #include "base/functional/callback.h" #include "base/strings/strcat.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "content/services/auction_worklet/auction_v8_helper.h" #include "content/services/auction_worklet/auction_v8_logger.h" #include "content/services/auction_worklet/webidl_compat.h"
diff --git a/content/services/auction_worklet/report_bindings.cc b/content/services/auction_worklet/report_bindings.cc index 56630fb..60b1567 100644 --- a/content/services/auction_worklet/report_bindings.cc +++ b/content/services/auction_worklet/report_bindings.cc
@@ -11,6 +11,7 @@ #include "base/format_macros.h" #include "base/functional/bind.h" #include "base/functional/callback.h" +#include "base/strings/stringprintf.h" #include "content/services/auction_worklet/auction_v8_helper.h" #include "content/services/auction_worklet/auction_v8_logger.h" #include "content/services/auction_worklet/webidl_compat.h"
diff --git a/content/services/auction_worklet/trusted_signals_kvv2_manager.cc b/content/services/auction_worklet/trusted_signals_kvv2_manager.cc index 1c91c87..6bca728 100644 --- a/content/services/auction_worklet/trusted_signals_kvv2_manager.cc +++ b/content/services/auction_worklet/trusted_signals_kvv2_manager.cc
@@ -17,6 +17,7 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/notreached.h" +#include "base/strings/stringprintf.h" #include "base/types/expected.h" #include "base/types/optional_ref.h" #include "components/cbor/reader.h"
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index d67b63f..99b4112 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1579,7 +1579,6 @@ "../browser/network/transferable_socket_browsertest.cc", "../browser/network/trust_token_browsertest.cc", "../browser/network/trust_token_browsertest.h", - "../browser/network/trust_token_origin_trial_browsertest.cc", "../browser/network/trust_token_parameters_browsertest.cc", "../browser/network_service_browsertest.cc", "../browser/network_service_restart_browsertest.cc",
diff --git a/docs/website b/docs/website index ffa936b..31a2f43 160000 --- a/docs/website +++ b/docs/website
@@ -1 +1 @@ -Subproject commit ffa936be041b042d683f68b68ec4f141133530e2 +Subproject commit 31a2f432dc14e60054e2a361f4fa16ffff65e01b
diff --git a/extensions/browser/api/user_scripts/user_scripts_api.cc b/extensions/browser/api/user_scripts/user_scripts_api.cc index eeadc02c..3ae798f 100644 --- a/extensions/browser/api/user_scripts/user_scripts_api.cc +++ b/extensions/browser/api/user_scripts/user_scripts_api.cc
@@ -588,9 +588,6 @@ EXTENSION_FUNCTION_VALIDATE(params); EXTENSION_FUNCTION_VALIDATE(extension()); - std::optional<std::string> csp = std::move(params->properties.csp); - bool enable_messaging = params->properties.messaging.value_or(false); - std::optional<std::string> world_id; if (base::FeatureList::IsEnabled( extensions_features::kApiUserScriptsMultipleWorlds)) { @@ -613,8 +610,25 @@ kMaxNumberOfRegisteredWorlds))); } - config_manager->SetUserScriptWorldInfo(*extension(), world_id, csp, - enable_messaging); + mojom::UserScriptWorldInfoPtr world_info = + config_manager->GetUserScriptWorldInfo(extension()->id(), world_id); + bool changed = false; + + std::optional<std::string> csp = std::move(params->properties.csp); + if (csp && csp != world_info->csp) { + changed = true; + world_info->csp = std::move(csp); + } + + std::optional<bool> enable_messaging = params->properties.messaging; + if (enable_messaging && *enable_messaging != world_info->enable_messaging) { + changed = true; + world_info->enable_messaging = *enable_messaging; + } + + if (changed) { + config_manager->SetUserScriptWorldInfo(*extension(), std::move(world_info)); + } return RespondNow(NoArguments()); }
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index d3618efc..8f7f624a 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -431,8 +431,6 @@ if (extensions::kExtensionScheme == request_scheme && ExtensionsBrowserClient::Get()->IsExtensionTelemetryServiceEnabled( browser_context) && - base::FeatureList::IsEnabled( - safe_browsing::kExtensionTelemetryReportContactedHosts) && !base::FeatureList::IsEnabled( safe_browsing:: kExtensionTelemetryInterceptRemoteHostsContactedInRenderer)) { @@ -591,8 +589,6 @@ // launched. return ExtensionsBrowserClient::Get()->IsExtensionTelemetryServiceEnabled( browser_context_) && - base::FeatureList::IsEnabled( - safe_browsing::kExtensionTelemetryReportContactedHosts) && !base::FeatureList::IsEnabled( safe_browsing:: kExtensionTelemetryInterceptRemoteHostsContactedInRenderer);
diff --git a/extensions/browser/extension_protocols.cc b/extensions/browser/extension_protocols.cc index c001e4a..18e3921 100644 --- a/extensions/browser/extension_protocols.cc +++ b/extensions/browser/extension_protocols.cc
@@ -350,10 +350,8 @@ } bool IsFaviconURL(const GURL& url) { - return base::FeatureList::IsEnabled( - extensions_features::kNewExtensionFaviconHandling) && - (IsPathEqualTo(url, kFaviconSourcePath) || - IsPathEqualTo(url, base::StrCat({kFaviconSourcePath, "/"}))); + return IsPathEqualTo(url, kFaviconSourcePath) || + IsPathEqualTo(url, base::StrCat({kFaviconSourcePath, "/"})); } bool IsBackgroundPageURL(const GURL& url) {
diff --git a/extensions/browser/extension_registrar_unittest.cc b/extensions/browser/extension_registrar_unittest.cc index 5ad46315..d3ffec3c 100644 --- a/extensions/browser/extension_registrar_unittest.cc +++ b/extensions/browser/extension_registrar_unittest.cc
@@ -543,26 +543,4 @@ TryDisablingNotAshKeeplistedExtension(/* expect_extension_disabled= */ true); } -#if BUILDFLAG(IS_CHROMEOS) -// Test that a controlled extension that is not on the ash keep-list cannot be -// disabled if ash is still enabled. -TEST_F(ExtensionRegistrarTest, - NotDisableNotAshKeeplistedForceInstalledExtensionIfAshEnabled) { - static_cast<TestingPrefServiceSimple*>(pref_service()) - ->registry() - ->RegisterIntegerPref( - prefs::kLacrosLaunchSwitch, - static_cast<int>( - ash::standalone_browser::LacrosAvailability::kLacrosOnly)); - EXPECT_TRUE(crosapi::browser_util::IsAshWebBrowserEnabled()); - - // Prevent the extension from being disabled (by the user). - ON_CALL(*delegate(), CanDisableExtension(extension().get())) - .WillByDefault(Return(false)); - AddEnabledExtension(); - - TryDisablingNotAshKeeplistedExtension(/* expect_extension_disabled= */ false); -} -#endif // BUILDFLAG(IS_CHROMEOS) - } // namespace extensions
diff --git a/extensions/browser/user_script_world_configuration_manager.cc b/extensions/browser/user_script_world_configuration_manager.cc index 36164f22..d88766d 100644 --- a/extensions/browser/user_script_world_configuration_manager.cc +++ b/extensions/browser/user_script_world_configuration_manager.cc
@@ -103,10 +103,8 @@ void UserScriptWorldConfigurationManager::SetUserScriptWorldInfo( const Extension& extension, - const std::optional<std::string>& world_id, - std::optional<std::string> csp, - bool enable_messaging) { - CHECK(!world_id || !world_id->empty()); + mojom::UserScriptWorldInfoPtr world_info) { + CHECK(!world_info->world_id || !world_info->world_id->empty()); // Persist world configuratation in ExtensionPrefs. ExtensionPrefs::ScopedDictionaryUpdate update( extension_prefs_, extension.id(), kUserScriptsWorldsConfiguration.name); @@ -115,17 +113,21 @@ update_dict = update.Create(); } - base::Value::Dict world_info; - world_info.Set(kUserScriptWorldMessagingKey, enable_messaging); - if (csp.has_value()) { - world_info.Set(kUserScriptWorldCspKey, *csp); + base::Value::Dict world_info_dict; + world_info_dict.Set(kUserScriptWorldMessagingKey, + world_info->enable_messaging); + if (world_info->csp.has_value()) { + world_info_dict.Set(kUserScriptWorldCspKey, *world_info->csp); } - update_dict->SetKey(GetUserScriptWorldKeyForWorldId(world_id), - base::Value(std::move(world_info))); + update_dict->SetKey(GetUserScriptWorldKeyForWorldId(world_info->world_id), + base::Value(std::move(world_info_dict))); - renderer_helper_->SetUserScriptWorldProperties(extension, world_id, csp, - enable_messaging); + // TODO(devlin): Have RendererStartupHelper::SetUserScriptWorldProperties() + // take a mojom::UserScriptWorldInfoPtr. + renderer_helper_->SetUserScriptWorldProperties( + extension, world_info->world_id, world_info->csp, + world_info->enable_messaging); } void UserScriptWorldConfigurationManager::ClearUserScriptWorldInfo(
diff --git a/extensions/browser/user_script_world_configuration_manager.h b/extensions/browser/user_script_world_configuration_manager.h index 3a80c22..8c3bda1 100644 --- a/extensions/browser/user_script_world_configuration_manager.h +++ b/extensions/browser/user_script_world_configuration_manager.h
@@ -48,9 +48,7 @@ // `world_id` is omitted, sets the configuration for the default user script // world. void SetUserScriptWorldInfo(const Extension& extension, - const std::optional<std::string>& world_id, - std::optional<std::string> csp, - bool enable_messaging); + mojom::UserScriptWorldInfoPtr world_info); // Clears any stored configuration for a user script world indicated by // `world_id`. If `world_id` is omitted, removes the configuration for the
diff --git a/extensions/common/api/virtual_keyboard_private.json b/extensions/common/api/virtual_keyboard_private.json index 8a2957ea..b9279c03 100644 --- a/extensions/common/api/virtual_keyboard_private.json +++ b/extensions/common/api/virtual_keyboard_private.json
@@ -225,7 +225,7 @@ { "name": "openSettings", "type": "function", - "description": "Opens chrome://os-settings/osLanguages page.", + "description": "Opens chrome://os-settings/osLanguages/input page.", "parameters": [] }, {
diff --git a/extensions/common/extension_features.cc b/extensions/common/extension_features.cc index 5bb85cd..92eacbb 100644 --- a/extensions/common/extension_features.cc +++ b/extensions/common/extension_features.cc
@@ -134,10 +134,6 @@ "LaunchWindowsNativeHostsDirectly", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kNewExtensionFaviconHandling, - "ExtensionsNewFaviconHandling", - base::FEATURE_ENABLED_BY_DEFAULT); - // To investigate signal beacon loss in crrev.com/c/2262402. BASE_FEATURE(kReportKeepaliveUkm, "ReportKeepaliveUkm",
diff --git a/extensions/common/extension_features.h b/extensions/common/extension_features.h index 30facb3..e6ea6e2 100644 --- a/extensions/common/extension_features.h +++ b/extensions/common/extension_features.h
@@ -160,9 +160,6 @@ // cmd.exe process as a proxy. BASE_DECLARE_FEATURE(kLaunchWindowsNativeHostsDirectly); -// Controls whether extensions can use the new favicon fetching in Manifest V3. -BASE_DECLARE_FEATURE(kNewExtensionFaviconHandling); - // Controls whether omnibox extensions can use the new capability to intercept // input without needing keyword mode. BASE_DECLARE_FEATURE(kExperimentalOmniboxLabs);
diff --git a/gpu/command_buffer/service/shared_memory_region_wrapper.cc b/gpu/command_buffer/service/shared_memory_region_wrapper.cc index 1cd0eef..29c13d55 100644 --- a/gpu/command_buffer/service/shared_memory_region_wrapper.cc +++ b/gpu/command_buffer/service/shared_memory_region_wrapper.cc
@@ -122,9 +122,9 @@ return mapping_.IsValid(); } -uint8_t* SharedMemoryRegionWrapper::GetMemory(int plane_index) const { +const uint8_t* SharedMemoryRegionWrapper::GetMemory(int plane_index) const { DCHECK(IsValid()); - return mapping_.GetMemoryAs<uint8_t>() + planes_[plane_index].offset; + return mapping_.GetMemoryAs<const uint8_t>() + planes_[plane_index].offset; } size_t SharedMemoryRegionWrapper::GetStride(int plane_index) const {
diff --git a/gpu/command_buffer/service/shared_memory_region_wrapper.h b/gpu/command_buffer/service/shared_memory_region_wrapper.h index ae1bcd6..12ef9e0 100644 --- a/gpu/command_buffer/service/shared_memory_region_wrapper.h +++ b/gpu/command_buffer/service/shared_memory_region_wrapper.h
@@ -5,6 +5,9 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_MEMORY_REGION_WRAPPER_H_ #define GPU_COMMAND_BUFFER_SERVICE_SHARED_MEMORY_REGION_WRAPPER_H_ +#include <utility> +#include <vector> + #include "base/containers/span.h" #include "base/memory/shared_memory_mapping.h" #include "base/unguessable_token.h" @@ -36,7 +39,10 @@ gfx::BufferFormat format); bool IsValid() const; - uint8_t* GetMemory(int plane_index) const; + uint8_t* GetMemory(int plane_index) { + return const_cast<uint8_t*>(std::as_const(*this).GetMemory(plane_index)); + } + const uint8_t* GetMemory(int plane_index) const; size_t GetStride(int plane_index) const; // Returns SkPixmap pointing to memory for offset.
diff --git a/gpu/ipc/client/shared_image_interface_proxy.cc b/gpu/ipc/client/shared_image_interface_proxy.cc index e2e1075..beb290d 100644 --- a/gpu/ipc/client/shared_image_interface_proxy.cc +++ b/gpu/ipc/client/shared_image_interface_proxy.cc
@@ -48,7 +48,7 @@ return region.mapping.size() - offset; } -void* GetDataAddress(const base::MappedReadOnlyRegion& region, +void* GetDataAddress(base::MappedReadOnlyRegion& region, size_t offset, size_t size) { base::CheckedNumeric<size_t> safe_end = offset;
diff --git a/headless/lib/browser/headless_browser_impl.cc b/headless/lib/browser/headless_browser_impl.cc index 0bb6ff6..560bdba3 100644 --- a/headless/lib/browser/headless_browser_impl.cc +++ b/headless/lib/browser/headless_browser_impl.cc
@@ -102,12 +102,12 @@ // Rengenerate the brand version lists with kHeadlessProductName. metadata.brand_version_list = embedder_support::GenerateBrandVersionList( - seed, kHeadlessProductName, significant_version, std::nullopt, - std::nullopt, kEnableUpdatedGreaseByPolicy, + seed, kHeadlessProductName, significant_version, + kEnableUpdatedGreaseByPolicy, blink::UserAgentBrandVersionType::kMajorVersion); metadata.brand_full_version_list = embedder_support::GenerateBrandVersionList( - seed, kHeadlessProductName, metadata.full_version, std::nullopt, - std::nullopt, kEnableUpdatedGreaseByPolicy, + seed, kHeadlessProductName, metadata.full_version, + kEnableUpdatedGreaseByPolicy, blink::UserAgentBrandVersionType::kFullVersion); return metadata; }
diff --git a/infra/config/generated/testing/test_suites.pyl b/infra/config/generated/testing/test_suites.pyl index 737459b..c73a0e6 100644 --- a/infra/config/generated/testing/test_suites.pyl +++ b/infra/config/generated/testing/test_suites.pyl
@@ -2578,14 +2578,6 @@ }, 'optimization_guide_android_gtests': { - 'optimization_guide_components_unittests': { - 'test_common': { - 'args': [ - '--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*', - ], - }, - 'test': 'components_unittests', - }, }, 'optimization_guide_cros_gtests': { @@ -2597,14 +2589,6 @@ }, 'test': 'browser_tests', }, - 'optimization_guide_components_unittests': { - 'test_common': { - 'args': [ - '--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*', - ], - }, - 'test': 'components_unittests', - }, }, 'optimization_guide_gpu_gtests': { @@ -2644,17 +2628,6 @@ '--use-xvfb', ], }, - 'optimization_guide_components_unittests': { - 'test_common': { - 'args': [ - '--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*', - ], - }, - 'test': 'components_unittests', - 'linux_args': [ - '--use-xvfb', - ], - }, 'optimization_guide_unittests': { 'linux_args': [ '--use-xvfb',
diff --git a/infra/config/targets/basic_suites.star b/infra/config/targets/basic_suites.star index 3d25d9da..14e5659 100644 --- a/infra/config/targets/basic_suites.star +++ b/infra/config/targets/basic_suites.star
@@ -1911,7 +1911,6 @@ targets.legacy_basic_suite( name = "optimization_guide_android_gtests", tests = { - "optimization_guide_components_unittests": targets.legacy_test_config(), # TODO(mgeorgaklis): Add optimization_guide_unittests when they become Android compatible. }, ) @@ -1920,7 +1919,6 @@ name = "optimization_guide_cros_gtests", tests = { "optimization_guide_browser_tests": targets.legacy_test_config(), - "optimization_guide_components_unittests": targets.legacy_test_config(), }, ) @@ -1949,11 +1947,6 @@ "--use-xvfb", ], ), - "optimization_guide_components_unittests": targets.legacy_test_config( - linux_args = [ - "--use-xvfb", - ], - ), "optimization_guide_unittests": targets.legacy_test_config( linux_args = [ "--use-xvfb",
diff --git a/infra/config/targets/tests.star b/infra/config/targets/tests.star index 672619f..f4008ed 100644 --- a/infra/config/targets/tests.star +++ b/infra/config/targets/tests.star
@@ -1797,14 +1797,6 @@ ) targets.tests.gtest_test( - name = "optimization_guide_components_unittests", - args = [ - "--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*", - ], - binary = "components_unittests", -) - -targets.tests.gtest_test( name = "optimization_guide_gpu_unittests", )
diff --git a/internal b/internal index ef593be..f367c8fb 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit ef593bebcf9e5a9d111c4f12d0732bf1366ca4b7 +Subproject commit f367c8fba0bcc44119ac34aa2e11dd2326780db6
diff --git a/ios/chrome/browser/collaboration/model/messaging/messaging_backend_service_factory.mm b/ios/chrome/browser/collaboration/model/messaging/messaging_backend_service_factory.mm index 989fb61c..6b6a87f2 100644 --- a/ios/chrome/browser/collaboration/model/messaging/messaging_backend_service_factory.mm +++ b/ios/chrome/browser/collaboration/model/messaging/messaging_backend_service_factory.mm
@@ -11,6 +11,7 @@ #import "components/collaboration/internal/messaging/messaging_backend_service_impl.h" #import "components/collaboration/internal/messaging/storage/messaging_backend_store_impl.h" #import "components/collaboration/internal/messaging/tab_group_change_notifier_impl.h" +#import "components/collaboration/public/features.h" #import "components/data_sharing/public/features.h" #import "ios/chrome/browser/collaboration/model/features.h" #import "ios/chrome/browser/data_sharing/model/data_sharing_service_factory.h" @@ -49,7 +50,8 @@ if (!base::FeatureList::IsEnabled( data_sharing::features::kDataSharingFeature) || - !IsSharedTabGroupsJoinEnabled(profile)) { + !IsSharedTabGroupsJoinEnabled(profile) || + !base::FeatureList::IsEnabled(kCollaborationMessaging)) { return std::make_unique<EmptyMessagingBackendService>(); }
diff --git a/ios/chrome/browser/prefs/model/BUILD.gn b/ios/chrome/browser/prefs/model/BUILD.gn index 3e09807a0..2840cdd 100644 --- a/ios/chrome/browser/prefs/model/BUILD.gn +++ b/ios/chrome/browser/prefs/model/BUILD.gn
@@ -23,3 +23,16 @@ "//ios/chrome/browser/sync/model/prefs", ] } + +source_set("unit_tests") { + testonly = true + sources = [ "ios_chrome_pref_service_factory_unittest.cc" ] + deps = [ + ":model", + "//base/test:test_support", + "//components/pref_registry", + "//components/sync/base:features", + "//components/sync_preferences", + "//testing/gtest", + ] +}
diff --git a/ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory.h b/ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory.h index e70526f..01a9ae3 100644 --- a/ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory.h +++ b/ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/files/file_path.h" #include "base/memory/ref_counted.h" class PrefRegistry; @@ -31,6 +32,9 @@ class PrefRegistrySyncable; } +extern const base::FilePath::CharType kPreferencesFilename[]; +extern const base::FilePath::CharType kAccountPreferencesFilename[]; + // Factory methods that create and initialize a new instance of a PrefService // for Chrome on iOS with the applicable PrefStores. The `pref_filename` points // to the user preference file. This is the usual way to create a new
diff --git a/ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory.mm b/ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory.mm index 32a9c86..702b544 100644 --- a/ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory.mm +++ b/ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory.mm
@@ -8,6 +8,7 @@ #import "base/check.h" #import "base/feature_list.h" +#import "base/files/file_util.h" #import "base/functional/bind.h" #import "base/memory/ptr_util.h" #import "base/metrics/histogram_macros.h" @@ -20,6 +21,7 @@ #import "components/prefs/pref_service.h" #import "components/prefs/pref_store.h" #import "components/prefs/pref_value_store.h" +#import "components/prefs/wrap_with_prefix_pref_store.h" #import "components/proxy_config/proxy_config_pref_names.h" #import "components/supervised_user/core/browser/supervised_user_pref_store.h" #import "components/supervised_user/core/common/features.h" @@ -30,12 +32,10 @@ namespace { -const char kPreferencesFilename[] = "Preferences"; -const char kAccountPreferencesFilename[] = "AccountPreferences"; +const char kAccountPreferencesPrefix[] = "account_values"; void PrepareFactory(sync_preferences::PrefServiceSyncableFactory* factory, - const base::FilePath& pref_filename, - base::SequencedTaskRunner* pref_io_task_runner, + scoped_refptr<JsonPrefStore> user_pref_store, policy::PolicyService* policy_service, policy::BrowserPolicyConnector* policy_connector, const scoped_refptr<PrefStore>& supervised_user_prefs) { @@ -49,8 +49,7 @@ factory->set_supervised_user_prefs(supervised_user_prefs); } - factory->set_user_prefs(base::MakeRefCounted<JsonPrefStore>( - pref_filename, std::unique_ptr<PrefFilter>(), pref_io_task_runner)); + factory->set_user_prefs(std::move(user_pref_store)); factory->SetPrefModelAssociatorClient( base::MakeRefCounted<IOSChromePrefModelAssociatorClient>()); @@ -58,6 +57,11 @@ } // namespace +const base::FilePath::CharType kPreferencesFilename[] = + FILE_PATH_LITERAL("Preferences"); +const base::FilePath::CharType kAccountPreferencesFilename[] = + FILE_PATH_LITERAL("AccountPreferences"); + std::unique_ptr<PrefService> CreateLocalState( const base::FilePath& pref_filename, base::SequencedTaskRunner* pref_io_task_runner, @@ -65,8 +69,11 @@ policy::PolicyService* policy_service, policy::BrowserPolicyConnector* policy_connector) { sync_preferences::PrefServiceSyncableFactory factory; - PrepareFactory(&factory, pref_filename, pref_io_task_runner, policy_service, - policy_connector, /*supervised_user_prefs=*/nullptr); + PrepareFactory( + &factory, + base::MakeRefCounted<JsonPrefStore>( + pref_filename, std::unique_ptr<PrefFilter>(), pref_io_task_runner), + policy_service, policy_connector, /*supervised_user_prefs=*/nullptr); return factory.Create(pref_registry.get()); } @@ -83,14 +90,28 @@ // preference modifications (as applications are sand-boxed), it can use a // simple JsonPrefStore to store them (which is what PrefStoreManager uses // on platforms that do not track preference modifications). + scoped_refptr<JsonPrefStore> local_pref_store = + base::MakeRefCounted<JsonPrefStore>( + profile_path.Append(kPreferencesFilename), + std::unique_ptr<PrefFilter>(), pref_io_task_runner); sync_preferences::PrefServiceSyncableFactory factory; - PrepareFactory(&factory, profile_path.Append(kPreferencesFilename), - pref_io_task_runner, policy_service, policy_connector, + PrepareFactory(&factory, local_pref_store, policy_service, policy_connector, supervised_user_prefs); if (base::FeatureList::IsEnabled(syncer::kEnablePreferencesAccountStorage)) { - factory.SetAccountPrefStore(base::MakeRefCounted<JsonPrefStore>( - profile_path.Append(kAccountPreferencesFilename), nullptr, - pref_io_task_runner)); + base::FilePath account_prefs_filepath = + profile_path.Append(kAccountPreferencesFilename); + if (base::FeatureList::IsEnabled(syncer::kMigrateAccountPrefs)) { + // Post task to remove the account preferences file. This is done on the + // IO thread. + pref_io_task_runner->PostTask( + FROM_HERE, base::BindOnce(IgnoreResult(&base::DeleteFile), + account_prefs_filepath)); + factory.SetAccountPrefStore(base::MakeRefCounted<WrapWithPrefixPrefStore>( + local_pref_store, kAccountPreferencesPrefix)); + } else { + factory.SetAccountPrefStore(base::MakeRefCounted<JsonPrefStore>( + account_prefs_filepath, nullptr, pref_io_task_runner)); + } } factory.set_async(async); std::unique_ptr<sync_preferences::PrefServiceSyncable> pref_service =
diff --git a/ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory_unittest.cc b/ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory_unittest.cc new file mode 100644 index 0000000..11e2105 --- /dev/null +++ b/ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory_unittest.cc
@@ -0,0 +1,72 @@ +// 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 "ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory.h" + +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/task/single_thread_task_runner.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/task_environment.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/sync/base/features.h" +#include "components/sync_preferences/pref_service_syncable.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +namespace { + +class CreateProfilePrefsTestBase : public PlatformTest { + public: + CreateProfilePrefsTestBase() + : pref_registry_( + base::MakeRefCounted<user_prefs::PrefRegistrySyncable>()) { + EXPECT_TRUE(data_dir_.CreateUniqueTempDir()); + } + + std::unique_ptr<sync_preferences::PrefServiceSyncable> BuildPrefService() { + return CreateProfilePrefs( + data_dir_.GetPath(), task_environment_.GetMainThreadTaskRunner().get(), + pref_registry_, /*policy_service=*/nullptr, + /*policy_connector=*/nullptr, /*supervised_user_prefs=*/nullptr, + /*async=*/true); + } + + base::FilePath AccountPreferencesFilePath() const { + return data_dir_.GetPath().Append(kAccountPreferencesFilename); + } + + protected: + base::test::SingleThreadTaskEnvironment task_environment_; + base::ScopedTempDir data_dir_; + scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry_; +}; + +class CreateProfilePrefsTestWithMigrateAccountPrefsEnabled + : public CreateProfilePrefsTestBase { + public: + CreateProfilePrefsTestWithMigrateAccountPrefsEnabled() + : feature_list_(syncer::kMigrateAccountPrefs) {} + + private: + base::test::ScopedFeatureList feature_list_; +}; + +TEST_F(CreateProfilePrefsTestWithMigrateAccountPrefsEnabled, + ShouldRemoveAccountPrefsFile) { + // Simulate a pre-existing account preferences file. + ASSERT_TRUE(base::WriteFile(AccountPreferencesFilePath(), "")); + + BuildPrefService(); + // Wait for the posted task to delete the file finish. + base::RunLoop run_loop; + task_environment_.GetMainThreadTaskRunner()->PostTask(FROM_HERE, + run_loop.QuitClosure()); + run_loop.Run(); + + // Account prefs file should have been removed. + EXPECT_FALSE(base::PathExists(AccountPreferencesFilePath())); +} + +} // namespace
diff --git a/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util.h b/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util.h index 3020e911..1c84447b 100644 --- a/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util.h +++ b/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util.h
@@ -85,9 +85,9 @@ TabGroupSyncService* sync_service); // Returns the collabID of the given `tab_group` if it's shared. -// Otherwise returns nil. -NSString* GetTabGroupCollabID(const TabGroup* tab_group, - TabGroupSyncService* sync_service); +// Otherwise returns an empty collabID. +CollaborationId GetTabGroupCollabID(const TabGroup* tab_group, + TabGroupSyncService* sync_service); } // namespace utils } // namespace tab_groups
diff --git a/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util.mm b/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util.mm index 8490c06..90b8c85 100644 --- a/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util.mm +++ b/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util.mm
@@ -301,17 +301,17 @@ return shared; } -NSString* GetTabGroupCollabID(const TabGroup* tab_group, - TabGroupSyncService* sync_service) { +CollaborationId GetTabGroupCollabID(const TabGroup* tab_group, + TabGroupSyncService* sync_service) { if (sync_service && tab_group) { std::optional<tab_groups::SavedTabGroup> saved_group = sync_service->GetGroup(tab_group->tab_group_id()); if (saved_group.has_value() && saved_group->collaboration_id().has_value()) { - return base::SysUTF8ToNSString(saved_group->collaboration_id()->value()); + return saved_group->collaboration_id().value(); } } - return nil; + return CollaborationId(); } } // namespace utils
diff --git a/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util_unittest.mm b/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util_unittest.mm index 1bec4ff3..5870617 100644 --- a/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util_unittest.mm +++ b/ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util_unittest.mm
@@ -546,9 +546,9 @@ EXPECT_CALL(*mock_service_, GetGroup(tab_group_id)) .WillOnce(testing::Return(saved_group)); - EXPECT_NSEQ(GetTabGroupCollabID(local_group, mock_service_), - @"collaboration"); - EXPECT_NSEQ(GetTabGroupCollabID(local_group, nullptr), nil); + EXPECT_EQ(GetTabGroupCollabID(local_group, mock_service_).value(), + "collaboration"); + EXPECT_EQ(GetTabGroupCollabID(local_group, nullptr).value(), ""); } // Tests the `GetTabGroupCollabID` method with a non shared group. @@ -564,9 +564,9 @@ EXPECT_CALL(*mock_service_, GetGroup(tab_group_id)) .WillOnce(testing::Return(saved_group)); - EXPECT_NSNE(GetTabGroupCollabID(local_group, mock_service_), - @"collaboration"); - EXPECT_NSEQ(GetTabGroupCollabID(local_group, nullptr), nil); + EXPECT_NE(GetTabGroupCollabID(local_group, mock_service_).value(), + "collaboration"); + EXPECT_EQ(GetTabGroupCollabID(local_group, nullptr).value(), ""); } } // namespace utils
diff --git a/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_egtest.mm b/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_egtest.mm index 5a0df05a..b5877c1 100644 --- a/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_egtest.mm +++ b/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_egtest.mm
@@ -1569,7 +1569,13 @@ // Tests the custom passphrase is remembered per account, kept across signout, // and cleared when account is removed from device. -- (void)testRememberCustomPassphraseAfterSignout { +// TODO(crbug.com/384646508): This test is flaky on the iPad simulator. +#if TARGET_IPHONE_SIMULATOR +#define MAYBE_testRememberCustomPassphraseAfterSignout FLAKY_testRememberCustomPassphraseAfterSignout +#else +#define MAYBE_testRememberCustomPassphraseAfterSignout testRememberCustomPassphraseAfterSignout +#endif // TARGET_IPHONE_SIMULATOR +- (void)MAYBE_testRememberCustomPassphraseAfterSignout { // Enable custom passphrase. [ChromeEarlGrey addSyncPassphrase:kPassphrase]; FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
diff --git a/ios/chrome/browser/settings/ui_bundled/settings_egtest.mm b/ios/chrome/browser/settings/ui_bundled/settings_egtest.mm index 0dbff5f..57f0548 100644 --- a/ios/chrome/browser/settings/ui_bundled/settings_egtest.mm +++ b/ios/chrome/browser/settings/ui_bundled/settings_egtest.mm
@@ -340,14 +340,26 @@ // Verifies that metrics reporting works properly under possible settings of the // preference kMetricsReportingEnabled. -- (void)testMetricsReporting { +// TODO(crbug.com/382632442): This test is failing on official builds. +#if defined(OFFICIAL_BUILD) +#define MAYBE_testMetricsReporting DISABLED_testMetricsReporting +#else +#define MAYBE_testMetricsReporting testMetricsReporting +#endif +- (void)MAYBE_testMetricsReporting { [self assertsMetricsPrefsForService:kMetrics]; } // Verifies that crashpad reporting works properly under possible settings of // the preference `kMetricsReportingEnabled`. // NOTE: crashpad only allows uploading for non-first-launch runs. -- (void)testCrashpadReporting { +// TODO(crbug.com/382632442): This test is failing on official builds. +#if defined(OFFICIAL_BUILD) +#define MAYBE_testCrashpadReporting DISABLED_testCrashpadReporting +#else +#define MAYBE_testCrashpadReporting testCrashpadReporting +#endif +- (void)MAYBE_testCrashpadReporting { [self assertsMetricsPrefsForService:kCrashpad]; }
diff --git a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm index 29a1689..83ce6240 100644 --- a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm +++ b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm
@@ -129,10 +129,6 @@ namespace { -// Deprecated 12/2023. -const char kSigninLastAccounts[] = "ios.signin.last_accounts"; -const char kSigninLastAccountsMigrated[] = "ios.signin.last_accounts_migrated"; - // Deprecated 01/2024. const char kAppStoreRatingTotalDaysOnChromeKey[] = "AppStoreRatingTotalDaysOnChrome"; @@ -195,6 +191,10 @@ // Deprecated 11/2024 constexpr char kEnableDoNotTrackIos[] = "enable_do_not_track"; +// Deprecated 12/2024. +inline constexpr char kPageContentCollectionEnabled[] = + "page_content_collection.enabled"; + // Helper function migrating the preference `pref_name` of type "int" from // `defaults` to `pref_service`. void MigrateIntegerPreferenceFromUserDefaults(std::string_view pref_name, @@ -967,8 +967,6 @@ registry->RegisterBooleanPref(prefs::kDetectUnitsEnabled, true); registry->RegisterTimePref(prefs::kLastSigninTimestamp, base::Time()); - registry->RegisterListPref(kSigninLastAccounts); - registry->RegisterBooleanPref(kSigninLastAccountsMigrated, false); // Preferences related to Content Notifications. registry->RegisterTimePref(prefs::kNotificationsPromoLastDismissed, @@ -1087,6 +1085,9 @@ registry->RegisterBooleanPref(kEnableDoNotTrackIos, false); registry->RegisterIntegerPref(prefs::kChromeDataRegionSetting, 0); + + // Deprecated 12/2024. + registry->RegisterBooleanPref(kPageContentCollectionEnabled, false); } // This method should be periodically pruned of year+ old migrations. @@ -1151,10 +1152,6 @@ NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; // Added 12/2023. - prefs->ClearPref(kSigninLastAccounts); - prefs->ClearPref(kSigninLastAccountsMigrated); - - // Added 12/2023. MigrateIntegerToTimePreferenceFromUserDefaults(kLastCookieDeletionDate, prefs, defaults); @@ -1280,6 +1277,9 @@ // Added 11/2024 prefs->ClearPref(kEnableDoNotTrackIos); + + // Added 12/2024. + prefs->ClearPref(kPageContentCollectionEnabled); } void MigrateObsoleteUserDefault() {
diff --git a/ios/chrome/browser/snapshots/model/BUILD.gn b/ios/chrome/browser/snapshots/model/BUILD.gn index cec46c9..19857376 100644 --- a/ios/chrome/browser/snapshots/model/BUILD.gn +++ b/ios/chrome/browser/snapshots/model/BUILD.gn
@@ -154,4 +154,5 @@ "features.mm", ] public_deps = [ "//base" ] + deps = [ "//ios/chrome/browser/shared/public/features" ] }
diff --git a/ios/chrome/browser/snapshots/model/features.h b/ios/chrome/browser/snapshots/model/features.h index fde9c8d8..e2fe6a7 100644 --- a/ios/chrome/browser/snapshots/model/features.h +++ b/ios/chrome/browser/snapshots/model/features.h
@@ -5,9 +5,24 @@ #ifndef IOS_CHROME_BROWSER_SNAPSHOTS_MODEL_FEATURES_H_ #define IOS_CHROME_BROWSER_SNAPSHOTS_MODEL_FEATURES_H_ +#ifdef __cplusplus #import "base/feature_list.h" // Feature flag to enable new snapshot system written in Swift. BASE_DECLARE_FEATURE(kSnapshotInSwift); +// Feature flag to allow more elements that the LRU cache can hold. +BASE_DECLARE_FEATURE(kLargeCapacityInSnapshotLRUCache); + +extern "C" { +#endif // extern "C" + +// Returns true if the kLargeCapacityInSnapshotLRUCache feature and the tab +// group feature are enabled. +bool IsLargeCapacityInSnapshotLRUCacheEnabled(); + +#ifdef __cplusplus +} // extern "C" +#endif + #endif // IOS_CHROME_BROWSER_SNAPSHOTS_MODEL_FEATURES_H_
diff --git a/ios/chrome/browser/snapshots/model/features.mm b/ios/chrome/browser/snapshots/model/features.mm index 10908159..545e527c 100644 --- a/ios/chrome/browser/snapshots/model/features.mm +++ b/ios/chrome/browser/snapshots/model/features.mm
@@ -4,6 +4,17 @@ #import "ios/chrome/browser/snapshots/model/features.h" +#import "ios/chrome/browser/shared/public/features/features.h" + BASE_FEATURE(kSnapshotInSwift, "SnapshotInSwift", base::FEATURE_DISABLED_BY_DEFAULT); + +BASE_FEATURE(kLargeCapacityInSnapshotLRUCache, + "LargeCapacityInSnapshotLRUCache", + base::FEATURE_DISABLED_BY_DEFAULT); + +bool IsLargeCapacityInSnapshotLRUCacheEnabled() { + return IsTabGroupInGridEnabled() && + base::FeatureList::IsEnabled(kLargeCapacityInSnapshotLRUCache); +}
diff --git a/ios/chrome/browser/snapshots/model/legacy_snapshot_storage.mm b/ios/chrome/browser/snapshots/model/legacy_snapshot_storage.mm index e60939e..1944b51 100644 --- a/ios/chrome/browser/snapshots/model/legacy_snapshot_storage.mm +++ b/ios/chrome/browser/snapshots/model/legacy_snapshot_storage.mm
@@ -27,12 +27,12 @@ namespace { -// Maximum size in number of elements that the LRU cache can hold before +// Base size in number of elements that the LRU cache can hold before // starting to evict elements. -const NSUInteger kLRUCacheMaxCapacity = 6; +const NSUInteger kLRUCacheBaseCapacity = 6; -// Maximum size in number of elements that the LRU cache can hold before -// starting to evict elements when PinnedTabs feature is enabled. +// Additional capacity of elements that the LRU cache can hold before starting +// to evict elements when PinnedTabs feature is enabled. // // To calculate the cache size number we'll start with the assumption that // currently snapshot preloading feature "works fine". In the reality it might @@ -41,7 +41,13 @@ // used. Based on that kLRUCacheMaxCapacityForPinnedTabsEnabled is // kLRUCacheMaxCapacity which "works fine" + on average 4 more snapshots needed // for pinned tabs feature. -const NSUInteger kLRUCacheMaxCapacityForPinnedTabsEnabled = 10; +const NSUInteger kLRUCacheAdditionalCapacityForPinnedTabsEnabled = 4; + +// Additional capacity of elements that the LRU cache can hold before starting +// to evict elements when the Tab Group feature is enabled. +// +// A tab group cell requests up to 7 snapshots from the first item. +const NSUInteger kLRUCacheAdditionalCapacityForTabGroupEnabled = 7; } // namespace @@ -75,9 +81,13 @@ - (instancetype)initWithStoragePath:(const base::FilePath&)storagePath legacyPath:(const base::FilePath&)legacyPath { if ((self = [super init])) { - NSUInteger cacheSize = IsPinnedTabsEnabled() - ? kLRUCacheMaxCapacityForPinnedTabsEnabled - : kLRUCacheMaxCapacity; + NSUInteger cacheSize = kLRUCacheBaseCapacity; + if (IsPinnedTabsEnabled()) { + cacheSize += kLRUCacheAdditionalCapacityForPinnedTabsEnabled; + } + if (IsLargeCapacityInSnapshotLRUCacheEnabled()) { + cacheSize += kLRUCacheAdditionalCapacityForTabGroupEnabled; + } _lruCache = [[LegacySnapshotLRUCache alloc] initWithCacheSize:cacheSize]; _fileManager =
diff --git a/ios/chrome/browser/snapshots/model/snapshot_storage.swift b/ios/chrome/browser/snapshots/model/snapshot_storage.swift index 5efe829..3f35268 100644 --- a/ios/chrome/browser/snapshots/model/snapshot_storage.swift +++ b/ios/chrome/browser/snapshots/model/snapshot_storage.swift
@@ -4,10 +4,10 @@ import UIKit -// Maximum size in number of elements that the LRU cache can hold before starting to evict elements. -let kLRUCacheMaxCapacity = 6 +// Base size in number of elements that the LRU cache can hold before starting to evict elements. +let kLRUCacheBaseCapacity = 6 -// Maximum size in number of elements that the LRU cache can hold before starting to evict elements +// Additional capacity of elements that the LRU cache can hold before starting to evict elements // when PinnedTabs feature is enabled. // // To calculate the cache size number we'll start with the assumption that currently snapshot @@ -16,7 +16,13 @@ // snapshots to be used. Based on that kLRUCacheMaxCapacityForPinnedTabsEnabled is // kLRUCacheMaxCapacity which "works fine" + on average 4 more snapshots needed for pinned tabs // feature. -let kLRUCacheMaxCapacityForPinnedTabsEnabled = 10 +let kLRUCacheAdditionalCapacityForPinnedTabsEnabled = 4 + +// Additional capacity of elements that the LRU cache can hold before starting to evict elements +// when the Tab Group feature is enabled. +// +// A tab group cell requests up to 7 snapshots from the first item. +let kLRUCacheAdditionalCapacityForTabGroupEnabled = 7 // A class providing an in-memory and on-disk storage of tab snapshots. // A snapshot is a full-screen image of the contents of the page at the current scroll offset and @@ -48,13 +54,19 @@ // TODO(crbug.com/40942167): Remove `legacyDirectoryUrl` when the storage for all users has been // migrated. init(storageDirectoryUrl: URL, legacyDirectoryUrl: URL?) { - // Use the different size of LRUCache when the pinned tabs feature is enabled. - // The pinned tabs feature is fully enabled on iPhone and disabled on iPad. The condition to - // determine the cache size should sync with IsPinnedTabsEnabled() in - // ios/chrome/browser/tabs/model/features.h. - self.lruCache = SnapshotLRUCache( - size: UIDevice.current.userInterfaceIdiom != .pad - ? kLRUCacheMaxCapacityForPinnedTabsEnabled : kLRUCacheMaxCapacity) + var cacheSize = kLRUCacheBaseCapacity + if UIDevice.current.userInterfaceIdiom != .pad { + // Add more capacity to LRUCache when the pinned tabs feature is enabled. + // The pinned tabs feature is fully enabled on iPhone and disabled on iPad. The condition to + // determine the cache size should sync with IsPinnedTabsEnabled() in + // ios/chrome/browser/tabs/model/features.h. + cacheSize += kLRUCacheAdditionalCapacityForPinnedTabsEnabled + } + if IsLargeCapacityInSnapshotLRUCacheEnabled() { + // Add more capacity to LRUCache when the feature flag is enabled. The feature depends on the tab group feature. + cacheSize += kLRUCacheAdditionalCapacityForTabGroupEnabled + } + self.lruCache = SnapshotLRUCache(size: cacheSize) self.fileManager = ImageFileManager( storageDirectoryUrl: storageDirectoryUrl, legacyDirectoryUrl: legacyDirectoryUrl) self.observers = []
diff --git a/ios/chrome/browser/snapshots/model/snapshot_swift_bridge.h b/ios/chrome/browser/snapshots/model/snapshot_swift_bridge.h index 822bf717..2408506 100644 --- a/ios/chrome/browser/snapshots/model/snapshot_swift_bridge.h +++ b/ios/chrome/browser/snapshots/model/snapshot_swift_bridge.h
@@ -10,6 +10,7 @@ #import "ios/chrome/browser/shared/public/metrics/histogram_functions_bridge.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util_bridge.h" +#import "ios/chrome/browser/snapshots/model/features.h" #import "ios/chrome/browser/snapshots/model/snapshot_id_wrapper.h" #import "ios/chrome/browser/snapshots/model/snapshot_scale.h" #import "ios/chrome/browser/snapshots/model/web_state_snapshot_info.h"
diff --git a/ios/chrome/browser/sync/model/prefs/BUILD.gn b/ios/chrome/browser/sync/model/prefs/BUILD.gn index fdb9bc27..73cde767 100644 --- a/ios/chrome/browser/sync/model/prefs/BUILD.gn +++ b/ios/chrome/browser/sync/model/prefs/BUILD.gn
@@ -31,6 +31,7 @@ "//ios/chrome/browser/signin/model:fake_system_identity", "//ios/chrome/browser/ui/authentication:eg_test_support+eg2", "//ios/chrome/test/earl_grey:eg_test_support+eg2", + "//ios/chrome/test/earl_grey:switches", "//ios/testing/earl_grey:eg_test_support+eg2", "//ios/web/public/test/http_server", "//net:test_support",
diff --git a/ios/chrome/browser/sync/model/prefs/sync_preferences_egtest.mm b/ios/chrome/browser/sync/model/prefs/sync_preferences_egtest.mm index dd78166e..745ab0e 100644 --- a/ios/chrome/browser/sync/model/prefs/sync_preferences_egtest.mm +++ b/ios/chrome/browser/sync/model/prefs/sync_preferences_egtest.mm
@@ -4,6 +4,7 @@ #import <XCTest/XCTest.h> +#import "base/files/file_util.h" #import "base/ios/ios_util.h" #import "base/strings/sys_string_conversions.h" #import "base/test/ios/wait_util.h" @@ -17,7 +18,9 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/chrome/test/earl_grey/test_switches.h" #import "ios/chrome/test/earl_grey/web_http_server_chrome_test_case.h" +#import "ios/testing/earl_grey/app_launch_manager.h" #import "ios/testing/earl_grey/earl_grey_test.h" #import "net/test/embedded_test_server/embedded_test_server.h" @@ -171,3 +174,202 @@ } @end + +@interface SyncPreferencesWithMigrateAccountPrefsBaseTestCase + : WebHttpServerChromeTestCase +@end + +@implementation SyncPreferencesWithMigrateAccountPrefsBaseTestCase + +- (void)setUp { + [super setUp]; + GREYAssertTrue(self.testServer->Start(), @"Server did not start."); + [ChromeEarlGrey clearFakeSyncServerData]; +} + +- (void)tearDownHelper { + [ChromeEarlGrey clearUserPrefWithName:kTestSyncablePref]; + [ChromeEarlGrey clearFakeSyncServerData]; + [super tearDownHelper]; +} + +- (void)restartWithMigrateAccountPrefsEnabled:(FakeSystemIdentity*)identity { + // Before restarting, ensure that the FakeServer has written all its pending + // state to disk. + [ChromeEarlGrey flushFakeSyncServerToDisk]; + // Also make sure any pending prefs changes are written to disk. + [ChromeEarlGrey commitPendingUserPrefsWrite]; + + AppLaunchConfiguration config = [self appConfigurationForTestCase]; + config.relaunch_policy = ForceRelaunchByCleanShutdown; + config.features_enabled.push_back(syncer::kMigrateAccountPrefs); + config.additional_args.push_back(base::StrCat({ + "-", test_switches::kAddFakeIdentitiesAtStartup, "=", + [FakeSystemIdentity encodeIdentitiesToBase64:@[ identity ]] + })); + [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config]; +} + +- (void)restartWithMigrateAccountPrefsDisabled:(FakeSystemIdentity*)identity { + // Before restarting, ensure that the FakeServer has written all its pending + // state to disk. + [ChromeEarlGrey flushFakeSyncServerToDisk]; + // Also make sure any pending prefs changes are written to disk. + [ChromeEarlGrey commitPendingUserPrefsWrite]; + + AppLaunchConfiguration config = [self appConfigurationForTestCase]; + config.relaunch_policy = ForceRelaunchByCleanShutdown; + config.features_disabled.push_back(syncer::kMigrateAccountPrefs); + config.additional_args.push_back(base::StrCat({ + "-", test_switches::kAddFakeIdentitiesAtStartup, "=", + [FakeSystemIdentity encodeIdentitiesToBase64:@[ identity ]] + })); + [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config]; +} + +- (void)setTestSyncablePrefValueTo:(int)pref_value + forFakeIdentity:(FakeSystemIdentity*)fakeIdentity { + // Sign in and set the pref value. + [SigninEarlGrey signinWithFakeIdentity:fakeIdentity]; + [ChromeEarlGrey + waitForSyncTransportStateActiveWithTimeout:kSyncOperationTimeout]; + [ChromeEarlGrey setIntegerValue:pref_value forUserPref:kTestSyncablePref]; + WaitForTestPreferenceOnFakeServer(true); + [SigninEarlGrey signOut]; + + // Remove from local store. + [ChromeEarlGrey clearUserPrefWithName:kTestSyncablePref]; +} + +@end + +@interface SyncPreferencesWithMigrateAccountPrefsEnabledTestCase + : SyncPreferencesWithMigrateAccountPrefsBaseTestCase +@end + +@implementation SyncPreferencesWithMigrateAccountPrefsEnabledTestCase + +- (AppLaunchConfiguration)appConfigurationForTestCase { + AppLaunchConfiguration config = [super appConfigurationForTestCase]; + config.features_enabled.push_back(syncer::kMigrateAccountPrefs); + return config; +} + +#pragma mark - SyncPreferencesWithMigrateAccountPrefsEnabledTestCase Tests + +- (void)testAccountPrefsDownloadedWithInitialSync { + FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1]; + // Set a pref value of `kTestPrefValue1` in account. + [self setTestSyncablePrefValueTo:kTestPrefValue1 + forFakeIdentity:fakeIdentity]; + + [self restartWithMigrateAccountPrefsEnabled:fakeIdentity]; + + // Sign in and sync. + WaitForTestPreferenceOnFakeServer(true); + [SigninEarlGrey signinWithFakeIdentity:fakeIdentity]; + WaitForPreferenceValue(kTestPrefValue1); + + // Sign out and validate that the pref is not set locally. + [SigninEarlGrey signOut]; + GREYAssertNotEqual([ChromeEarlGrey userIntegerPref:kTestSyncablePref], + kTestPrefValue1, @"Incorrect local pref value."); +} + +- (void)testAccountPrefsPersisted { + FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1]; + // Set a pref value of `kTestPrefValue1` in account. + [self setTestSyncablePrefValueTo:kTestPrefValue1 + forFakeIdentity:fakeIdentity]; + + // Sign in and sync. + [SigninEarlGrey signinWithFakeIdentity:fakeIdentity]; + WaitForPreferenceValue(kTestPrefValue1); + + // Restart. + [self restartWithMigrateAccountPrefsEnabled:fakeIdentity]; + GREYAssertEqual([ChromeEarlGrey userIntegerPref:kTestSyncablePref], + kTestPrefValue1, @"Incorrect local pref value."); +} + +- (void)testDisablingFlag { + FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1]; + + // Set a pref value of `kTestPrefValue1` in account. + [self setTestSyncablePrefValueTo:kTestPrefValue1 + forFakeIdentity:fakeIdentity]; + + // Sign in and sync. + [SigninEarlGrey signinWithFakeIdentity:fakeIdentity]; + WaitForPreferenceValue(kTestPrefValue1); + + // Restart with MigrateAccountPrefs flag disabled. + [self restartWithMigrateAccountPrefsDisabled:fakeIdentity]; + GREYAssertEqual([ChromeEarlGrey userIntegerPref:kTestSyncablePref], + kTestPrefValue1, @"Incorrect local pref value."); + + // Sign out and validate that the pref is not set locally. + [SigninEarlGrey signOut]; + GREYAssertNotEqual([ChromeEarlGrey userIntegerPref:kTestSyncablePref], + kTestPrefValue1, @"Incorrect local pref value."); +} + +@end + +@interface SyncPreferencesWithMigrateAccountPrefsDisabledTestCase + : SyncPreferencesWithMigrateAccountPrefsBaseTestCase +@end + +@implementation SyncPreferencesWithMigrateAccountPrefsDisabledTestCase + +- (AppLaunchConfiguration)appConfigurationForTestCase { + AppLaunchConfiguration config = [super appConfigurationForTestCase]; + config.features_disabled.push_back(syncer::kMigrateAccountPrefs); + return config; +} + +#pragma mark - SyncPreferencesWithMigrateAccountPrefsDisabledTestCase Tests + +- (void)testEnablingFlag { + FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1]; + // Set a pref value of `kTestPrefValue1` in account. + [self setTestSyncablePrefValueTo:kTestPrefValue1 + forFakeIdentity:fakeIdentity]; + + // Sign in and sync. + [SigninEarlGrey signinWithFakeIdentity:fakeIdentity]; + WaitForPreferenceValue(kTestPrefValue1); + + // Restart with MigrateAccountPrefs flag enabled. + [self restartWithMigrateAccountPrefsEnabled:fakeIdentity]; + GREYAssertEqual([ChromeEarlGrey userIntegerPref:kTestSyncablePref], + kTestPrefValue1, @"Incorrect local pref value."); + + // Sign out and validate that the pref is not set locally. + [SigninEarlGrey signOut]; + GREYAssertNotEqual([ChromeEarlGrey userIntegerPref:kTestSyncablePref], + kTestPrefValue1, @"Incorrect local pref value."); +} + +- (void)testAccountPrefsDownloadedFromSyncMetadataIfFlagEnabled { + FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1]; + // Set a pref value of `kTestPrefValue1` in account. + [self setTestSyncablePrefValueTo:kTestPrefValue1 + forFakeIdentity:fakeIdentity]; + + // Sign in and sync. + [SigninEarlGrey signinWithFakeIdentity:fakeIdentity]; + WaitForPreferenceValue(kTestPrefValue1); + + // Restart with MigrateAccountPrefs flag enabled. + [self restartWithMigrateAccountPrefsEnabled:fakeIdentity]; + GREYAssertEqual([ChromeEarlGrey userIntegerPref:kTestSyncablePref], + kTestPrefValue1, @"Incorrect local pref value."); + + // Sign out and validate that the pref is not set locally. + [SigninEarlGrey signOut]; + GREYAssertNotEqual([ChromeEarlGrey userIntegerPref:kTestSyncablePref], + kTestPrefValue1, @"Incorrect local pref value."); +} + +@end
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_grid_coordinator.mm index 9570b7c0d..f336cb9 100644 --- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_grid_coordinator.mm +++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_grid_coordinator.mm
@@ -1572,15 +1572,15 @@ tab_groups::TabGroupSyncServiceFactory::GetForProfile(profile); ShareKitService* shareKitService = ShareKitServiceFactory::GetForProfile(profile); - NSString* collabID = + tab_groups::CollaborationId collabID = tab_groups::utils::GetTabGroupCollabID(group.get(), syncService); - if (!shareKitService || !collabID) { + if (!shareKitService || collabID.value().empty()) { return; } ShareKitManageConfiguration* config = [[ShareKitManageConfiguration alloc] init]; config.baseViewController = self.baseViewController; - config.collabID = collabID; + config.collabID = base::SysUTF8ToNSString(collabID.value()); config.applicationHandler = HandlerForProtocol( self.regularBrowser->GetCommandDispatcher(), ApplicationCommands); shareKitService->ManageTabGroup(config);
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/BUILD.gn b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/BUILD.gn index 6a67ab1..74b06e0 100644 --- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/BUILD.gn +++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/BUILD.gn
@@ -62,6 +62,7 @@ "//ios/chrome/browser/tab_switcher/ui_bundled/tab_grid:tab_grid_activity_observer", "//ios/chrome/browser/tab_switcher/ui_bundled/tab_grid:tab_grid_idle_status_handler", "//ios/chrome/browser/tab_switcher/ui_bundled/tab_grid:tab_grid_page_mutator", + "//ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/grid:activity_label_view", "//ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/grid:grid_item_identifier", "//ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/grid:grid_mediator", "//ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/grid:grid_toolbars_mutator",
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/recent_activity_mediator.mm b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/recent_activity_mediator.mm index 6066d340..8f1ebc57 100644 --- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/recent_activity_mediator.mm +++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/recent_activity_mediator.mm
@@ -93,10 +93,9 @@ // Creates recent activity logs and passes them to the consumer. - (void)populateItemsFromService { collaboration::messaging::ActivityLogQueryParams params; - NSString* collabID = + tab_groups::CollaborationId collabID = tab_groups::utils::GetTabGroupCollabID(_tabGroup.get(), _syncService); - params.collaboration_id = - data_sharing::GroupId(base::SysNSStringToUTF8(collabID)); + params.collaboration_id = data_sharing::GroupId(collabID.value()); NSMutableArray<RecentActivityLogItem*>* items = [[NSMutableArray alloc] init];
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_coordinator.mm b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_coordinator.mm index 8ebfe16..1858cce2 100644 --- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_coordinator.mm +++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_coordinator.mm
@@ -11,6 +11,7 @@ #import "components/collaboration/public/collaboration_service.h" #import "components/saved_tab_groups/public/saved_tab_group.h" #import "ios/chrome/browser/collaboration/model/collaboration_service_factory.h" +#import "ios/chrome/browser/collaboration/model/messaging/messaging_backend_service_factory.h" #import "ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util.h" #import "ios/chrome/browser/saved_tab_groups/model/tab_group_sync_service_factory.h" #import "ios/chrome/browser/share_kit/model/share_kit_face_pile_configuration.h" @@ -100,6 +101,9 @@ ShareKitServiceFactory::GetForProfile(profile); collaboration::CollaborationService* collaborationService = collaboration::CollaborationServiceFactory::GetForProfile(profile); + collaboration::messaging::MessagingBackendService* messagingService = + collaboration::messaging::MessagingBackendServiceFactory::GetForProfile( + profile); _mediator = [[TabGroupMediator alloc] initWithWebStateList:browser->GetWebStateList() @@ -109,7 +113,8 @@ tabGroup:_tabGroup->GetWeakPtr() consumer:_viewController gridConsumer:_viewController.gridViewController - modeHolder:self.modeHolder]; + modeHolder:self.modeHolder + messagingService:messagingService]; _mediator.browser = browser; _mediator.tabGroupsHandler = HandlerForProtocol( self.browser->GetCommandDispatcher(), TabGroupsCommands); @@ -360,9 +365,9 @@ tab_groups::TabGroupSyncServiceFactory::GetForProfile( self.browser->GetProfile()); - NSString* savedCollabID = + tab_groups::CollaborationId savedCollabID = tab_groups::utils::GetTabGroupCollabID(_tabGroup, syncService); - if (savedCollabID) { + if (!savedCollabID.value().empty()) { [self manageGroup:savedCollabID]; } [self shareGroup]; @@ -395,16 +400,19 @@ } // Manage the group with `collabID`. -- (void)manageGroup:(NSString*)collabID { +- (void)manageGroup:(tab_groups::CollaborationId)collabID { ShareKitService* shareKitService = ShareKitServiceFactory::GetForProfile(self.browser->GetProfile()); - if (!collabID || !shareKitService) { + if (collabID.value().empty() || !shareKitService) { return; } + + NSString* collabIDString = base::SysUTF8ToNSString(collabID.value()); + ShareKitManageConfiguration* config = [[ShareKitManageConfiguration alloc] init]; config.baseViewController = self.baseViewController; - config.collabID = collabID; + config.collabID = collabIDString; config.applicationHandler = HandlerForProtocol( self.browser->GetCommandDispatcher(), ApplicationCommands); shareKitService->ManageTabGroup(config);
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator.h b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator.h index f50e717e..d4adf58 100644 --- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator.h +++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator.h
@@ -13,6 +13,9 @@ namespace collaboration { class CollaborationService; +namespace messaging { +class MessagingBackendService; +} // namespace messaging } // namespace collaboration namespace tab_groups { @@ -30,16 +33,18 @@ // Tab group mediator in charge to handle model update for one group. @interface TabGroupMediator : BaseGridMediator <TabGroupMutator> -- (instancetype)initWithWebStateList:(WebStateList*)webStateList - tabGroupSyncService: - (tab_groups::TabGroupSyncService*)tabGroupSyncService - shareKitService:(ShareKitService*)shareKitService - collaborationService: - (collaboration::CollaborationService*)collaborationService - tabGroup:(base::WeakPtr<const TabGroup>)tabGroup - consumer:(id<TabGroupConsumer>)consumer - gridConsumer:(id<TabCollectionConsumer>)gridConsumer - modeHolder:(TabGridModeHolder*)modeHolder; +- (instancetype) + initWithWebStateList:(WebStateList*)webStateList + tabGroupSyncService:(tab_groups::TabGroupSyncService*)tabGroupSyncService + shareKitService:(ShareKitService*)shareKitService + collaborationService: + (collaboration::CollaborationService*)collaborationService + tabGroup:(base::WeakPtr<const TabGroup>)tabGroup + consumer:(id<TabGroupConsumer>)consumer + gridConsumer:(id<TabCollectionConsumer>)gridConsumer + modeHolder:(TabGridModeHolder*)modeHolder + messagingService:(collaboration::messaging::MessagingBackendService*) + messagingService; @end
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator.mm b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator.mm index 32e6f81..5be5de2 100644 --- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator.mm +++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator.mm
@@ -12,10 +12,14 @@ #import "base/scoped_observation.h" #import "base/strings/sys_string_conversions.h" #import "components/collaboration/public/collaboration_service.h" +#import "components/collaboration/public/messaging/message.h" +#import "components/collaboration/public/messaging/messaging_backend_service.h" +#import "components/data_sharing/public/group_data.h" #import "ios/chrome/browser/collaboration/model/features.h" #import "ios/chrome/browser/drag_and_drop/model/drag_item_util.h" #import "ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util.h" #import "ios/chrome/browser/saved_tab_groups/model/tab_group_sync_service_factory.h" +#import "ios/chrome/browser/share_kit/model/share_kit_avatar_configuration.h" #import "ios/chrome/browser/share_kit/model/share_kit_face_pile_configuration.h" #import "ios/chrome/browser/share_kit/model/share_kit_service.h" #import "ios/chrome/browser/shared/model/browser/browser.h" @@ -29,6 +33,7 @@ #import "ios/chrome/browser/shared/public/features/features.h" #import "ios/chrome/browser/tab_switcher/ui_bundled/tab_collection_consumer.h" #import "ios/chrome/browser/tab_switcher/ui_bundled/tab_collection_drag_drop_metrics.h" +#import "ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/grid/activity_label_data.h" #import "ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/grid/grid_item_identifier.h" #import "ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/grid/grid_utils.h" #import "ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_grid_idle_status_handler.h" @@ -48,6 +53,8 @@ namespace { // The preferred size in points for the avatar icons. constexpr CGFloat kFacePileAvatarSize = 24; +// The preferred size in points for the avatar icon in the activity label. +constexpr CGFloat kActivityLabelAvatarSize = 16; } // namespace @interface TabGroupMediator () <TabGroupSyncServiceObserverDelegate> @@ -67,18 +74,26 @@ __weak id<TabGroupConsumer> _groupConsumer; // Current group. base::WeakPtr<const TabGroup> _tabGroup; + // A service to get activity messages for a shared tab group. + raw_ptr<collaboration::messaging::MessagingBackendService> _messagingService; + // A map of a tab ID and a message to indicate that a tab should display a + // chip on its cell. + std::map<tab_groups::LocalTabID, collaboration::messaging::PersistentMessage> + _dirtyTabs; } -- (instancetype)initWithWebStateList:(WebStateList*)webStateList - tabGroupSyncService: - (tab_groups::TabGroupSyncService*)tabGroupSyncService - shareKitService:(ShareKitService*)shareKitService - collaborationService: - (collaboration::CollaborationService*)collaborationService - tabGroup:(base::WeakPtr<const TabGroup>)tabGroup - consumer:(id<TabGroupConsumer>)groupConsumer - gridConsumer:(id<TabCollectionConsumer>)gridConsumer - modeHolder:(TabGridModeHolder*)modeHolder { +- (instancetype) + initWithWebStateList:(WebStateList*)webStateList + tabGroupSyncService:(tab_groups::TabGroupSyncService*)tabGroupSyncService + shareKitService:(ShareKitService*)shareKitService + collaborationService: + (collaboration::CollaborationService*)collaborationService + tabGroup:(base::WeakPtr<const TabGroup>)tabGroup + consumer:(id<TabGroupConsumer>)groupConsumer + gridConsumer:(id<TabCollectionConsumer>)gridConsumer + modeHolder:(TabGridModeHolder*)modeHolder + messagingService:(collaboration::messaging::MessagingBackendService*) + messagingService { CHECK(IsTabGroupInGridEnabled()) << "You should not be able to create a tab group mediator outside the " "Tab Groups experiment."; @@ -109,6 +124,11 @@ [_groupConsumer setGroupTitle:tabGroup->GetTitle()]; [_groupConsumer setGroupColor:tabGroup->GetColor()]; + // TODO(crbug.com/375594684): Start observing the messaging backend service + // and update _dirtyTabs. + _messagingService = messagingService; + [self fetchMessagesForChip]; + [self updateFacePileUI]; [self populateConsumerItems]; } @@ -295,9 +315,47 @@ // Overrides the parent to return the data if there is a new message for a tab // in a group. - (ActivityLabelData*)activityLabelDataForTab:(web::WebStateID)webStateID { - // TODO(crbug.com/375594458): return ActivityLabelData with the string "Added" - // or "Changed" and the user icon view. - return nil; + if (!_dirtyTabs.contains(webStateID.identifier())) { + return nil; + } + + ActivityLabelData* data = [[ActivityLabelData alloc] init]; + + collaboration::messaging::PersistentMessage message = + _dirtyTabs[webStateID.identifier()]; + switch (message.collaboration_event) { + case collaboration::messaging::CollaborationEvent::TAB_ADDED: + // TODO(crbug.com/371113934): Set the string "Added" to the + // data.labelString. + break; + case collaboration::messaging::CollaborationEvent::TAB_UPDATED: + // TODO(crbug.com/371113934): Set the string "Changed" to the + // data.labelString. + break; + default: + // Do not show any labels for other activities. + return nil; + } + + if (!_shareKitService->IsSupported() || + !message.attribution.triggering_user.has_value()) { + return nil; + } + + ShareKitAvatarConfiguration* config = + [[ShareKitAvatarConfiguration alloc] init]; + data_sharing::GroupMember user = message.attribution.triggering_user.value(); + config.avatarUrl = + [NSURL URLWithString:base::SysUTF8ToNSString(user.avatar_url.spec())]; + // Use email intead when the display name is empty. + config.displayName = user.display_name.empty() + ? base::SysUTF8ToNSString(user.email) + : base::SysUTF8ToNSString(user.display_name); + config.avatarSize = + CGSizeMake(kActivityLabelAvatarSize, kActivityLabelAvatarSize); + data.avatarPrimitive = _shareKitService->AvatarImage(config); + + return data; } #pragma mark - TabCollectionDragDropHandler override @@ -530,9 +588,10 @@ return; } - NSString* savedCollabID = tab_groups::utils::GetTabGroupCollabID( - _tabGroup.get(), _tabGroupSyncService); - BOOL isShared = savedCollabID != nil; + tab_groups::CollaborationId savedCollabID = + tab_groups::utils::GetTabGroupCollabID(_tabGroup.get(), + _tabGroupSyncService); + BOOL isShared = !savedCollabID.value().empty(); [_groupConsumer setGroupShared:isShared]; // Prevent the face pile from being set up for tab groups that are not shared @@ -545,7 +604,7 @@ // Configure the face pile. ShareKitFacePileConfiguration* config = [[ShareKitFacePileConfiguration alloc] init]; - config.collabID = savedCollabID; + config.collabID = base::SysUTF8ToNSString(savedCollabID.value()); config.showsEmptyState = YES; config.avatarSize = kFacePileAvatarSize; [_groupConsumer setFacePileViewController:_shareKitService->FacePile(config)]; @@ -567,4 +626,27 @@ selectedItemIdentifier:[self activeIdentifier]]; } +// Gets messages to indicate that a tab should display a chip on its cell. +- (void)fetchMessagesForChip { + if (!_tabGroup || !_messagingService || !_messagingService->IsInitialized()) { + return; + } + + std::vector<collaboration::messaging::PersistentMessage> messages = + _messagingService->GetMessagesForGroup( + _tabGroup->tab_group_id(), + collaboration::messaging::PersistentNotificationType::CHIP); + + for (auto& message : messages) { + if (!message.attribution.tab_metadata.has_value()) { + continue; + } + auto tab_data = message.attribution.tab_metadata.value(); + if (!tab_data.local_tab_id.has_value()) { + continue; + } + _dirtyTabs[tab_data.local_tab_id.value()] = message; + } +} + @end
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator_unittest.mm b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator_unittest.mm index b9c5204..55e81a4 100644 --- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator_unittest.mm +++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_groups/tab_group_mediator_unittest.mm
@@ -107,7 +107,8 @@ tabGroup:tab_group_->GetWeakPtr() consumer:tab_group_consumer_ gridConsumer:consumer_ - modeHolder:mode_holder_]; + modeHolder:mode_holder_ + messagingService:nil]; mediator_.browser = browser_.get(); }
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_strip/coordinator/tab_strip_coordinator.mm b/ios/chrome/browser/tab_switcher/ui_bundled/tab_strip/coordinator/tab_strip_coordinator.mm index 7d473b52..383838e3 100644 --- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_strip/coordinator/tab_strip_coordinator.mm +++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_strip/coordinator/tab_strip_coordinator.mm
@@ -314,15 +314,15 @@ tab_groups::TabGroupSyncServiceFactory::GetForProfile(profile); ShareKitService* shareKitService = ShareKitServiceFactory::GetForProfile(profile); - NSString* collabID = + tab_groups::CollaborationId collabID = tab_groups::utils::GetTabGroupCollabID(group.get(), syncService); - if (!shareKitService || !collabID) { + if (!shareKitService || collabID.value().empty()) { return; } ShareKitManageConfiguration* config = [[ShareKitManageConfiguration alloc] init]; config.baseViewController = self.baseViewController; - config.collabID = collabID; + config.collabID = base::SysUTF8ToNSString(collabID.value()); config.applicationHandler = HandlerForProtocol( self.browser->GetCommandDispatcher(), ApplicationCommands); shareKitService->ManageTabGroup(config);
diff --git a/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.h b/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.h index e1b68d45..b648772 100644 --- a/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.h +++ b/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.h
@@ -12,11 +12,11 @@ #include "base/memory/raw_ptr.h" #include "components/sync/model/syncable_service.h" #include "components/sync_sessions/local_session_event_router.h" -#include "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer.h" -#include "ios/web/public/web_state_observer.h" -class AllWebStateListObservationRegistrar; class BrowserList; +namespace web { +class WebState; +} namespace sync_sessions { class SyncSessionsClient; @@ -45,36 +45,8 @@ void Stop() override; private: - // Observer implementation for each profile. - class Observer : public WebStateListObserver, public web::WebStateObserver { - public: - explicit Observer(IOSChromeLocalSessionEventRouter* session_router); - Observer(const Observer&) = delete; - Observer& operator=(const Observer&) = delete; - ~Observer() override; - - private: - // WebStateListObserver: - void WebStateListDidChange(WebStateList* web_state_list, - const WebStateListChange& change, - const WebStateListStatus& status) override; - void WillBeginBatchOperation(WebStateList* web_state_list) override; - void BatchOperationEnded(WebStateList* web_state_list) override; - - // web::WebStateObserver: - void TitleWasSet(web::WebState* web_state) override; - void DidFinishNavigation( - web::WebState* web_state, - web::NavigationContext* navigation_context) override; - void PageLoaded( - web::WebState* web_state, - web::PageLoadCompletionStatus load_completion_status) override; - void WasShown(web::WebState* web_state) override; - void DidChangeBackForwardState(web::WebState* web_state) override; - void WebStateDestroyed(web::WebState* web_state) override; - - raw_ptr<IOSChromeLocalSessionEventRouter> router_; - }; + // Observer implementation for all Browsers. + class Observer; // Called before the Batch operation starts for a web state list. void OnSessionEventStarting(); @@ -88,9 +60,8 @@ // Called when a `web_state` is closed. void OnWebStateClosed(); - // Observation registrar for the associated browser list; owns an instance - // of IOSChromeLocalSessionEventRouter::Observer. - std::unique_ptr<AllWebStateListObservationRegistrar> const registrar_; + // Observer. + std::unique_ptr<Observer> const observer_; raw_ptr<sync_sessions::LocalSessionEventHandler> handler_ = nullptr; const raw_ptr<sync_sessions::SyncSessionsClient> sessions_client_;
diff --git a/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.mm b/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.mm index b85d1f5..d270f65 100644 --- a/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.mm +++ b/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.mm
@@ -8,17 +8,22 @@ #import "base/check.h" #import "base/functional/bind.h" +#import "base/scoped_multi_source_observation.h" +#import "base/scoped_observation.h" #import "components/history/core/browser/history_service.h" #import "components/keyed_service/core/service_access_type.h" #import "components/sync/base/features.h" #import "components/sync_sessions/sync_sessions_client.h" #import "components/sync_sessions/synced_tab_delegate.h" #import "ios/chrome/browser/history/model/history_service_factory.h" -#import "ios/chrome/browser/shared/model/browser/all_web_state_list_observation_registrar.h" +#import "ios/chrome/browser/shared/model/browser/browser.h" #import "ios/chrome/browser/shared/model/browser/browser_list.h" +#import "ios/chrome/browser/shared/model/browser/browser_list_observer.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" +#import "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer.h" #import "ios/chrome/browser/sync/model/glue/sync_start_util.h" #import "ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h" +#import "ios/web/public/web_state_observer.h" namespace { @@ -31,28 +36,126 @@ } // namespace -IOSChromeLocalSessionEventRouter::IOSChromeLocalSessionEventRouter( - BrowserList* browser_list, - sync_sessions::SyncSessionsClient* sessions_client, - const syncer::SyncableService::StartSyncFlare& flare) - : registrar_(std::make_unique<AllWebStateListObservationRegistrar>( - browser_list, - std::make_unique<Observer>(this), - AllWebStateListObservationRegistrar::Mode::REGULAR)), - sessions_client_(sessions_client), - flare_(flare) { - DCHECK(sessions_client_); -} +#pragma mark - IOSChromeLocalSessionEventRouter::Observer -IOSChromeLocalSessionEventRouter::~IOSChromeLocalSessionEventRouter() {} +class IOSChromeLocalSessionEventRouter::Observer + : public BrowserListObserver, + public WebStateListObserver, + public web::WebStateObserver { + public: + explicit Observer(IOSChromeLocalSessionEventRouter* session_router); + ~Observer() override = default; + + void Start(BrowserList* browser_list); + + private: + // BrowserListObserver: + void OnBrowserAdded(const BrowserList* browser_list, + Browser* browser) override; + void OnBrowserRemoved(const BrowserList* browser_list, + Browser* browser) override; + void OnBrowserListShutdown(BrowserList* browser_list) override; + + // WebStateListObserver: + void WebStateListDidChange(WebStateList* web_state_list, + const WebStateListChange& change, + const WebStateListStatus& status) override; + void WillBeginBatchOperation(WebStateList* web_state_list) override; + void BatchOperationEnded(WebStateList* web_state_list) override; + + // web::WebStateObserver: + void TitleWasSet(web::WebState* web_state) override; + void DidFinishNavigation(web::WebState* web_state, + web::NavigationContext* navigation_context) override; + void PageLoaded( + web::WebState* web_state, + web::PageLoadCompletionStatus load_completion_status) override; + void WasShown(web::WebState* web_state) override; + void DidChangeBackForwardState(web::WebState* web_state) override; + void WebStateDestroyed(web::WebState* web_state) override; + + raw_ptr<IOSChromeLocalSessionEventRouter> router_; + + // Scoped observations. + base::ScopedObservation<BrowserList, BrowserListObserver> + browser_list_observation_{this}; + base::ScopedMultiSourceObservation<WebStateList, WebStateListObserver> + web_state_list_observations_{this}; + base::ScopedMultiSourceObservation<web::WebState, web::WebStateObserver> + web_state_observations_{this}; +}; IOSChromeLocalSessionEventRouter::Observer::Observer( IOSChromeLocalSessionEventRouter* session_router) : router_(session_router) {} -IOSChromeLocalSessionEventRouter::Observer::~Observer() {} +void IOSChromeLocalSessionEventRouter::Observer::Start( + BrowserList* browser_list) { + browser_list_observation_.Observe(browser_list); -#pragma mark - WebStateListObserver + // The WebStateList may not be empty when the Observer is created, so + // start observing any pre-existing Browsers. + for (Browser* browser : + browser_list->BrowsersOfType(BrowserList::BrowserType::kRegular)) { + OnBrowserAdded(browser_list, browser); + } +} + +#pragma mark - IOSChromeLocalSessionEventRouter::Observer (BrowserListObserver) + +void IOSChromeLocalSessionEventRouter::Observer::OnBrowserAdded( + const BrowserList* browser_list, + Browser* browser) { + if (browser->type() != Browser::Type::kRegular) { + return; + } + + WebStateList* web_state_list = browser->GetWebStateList(); + web_state_list_observations_.AddObservation(web_state_list); + + // In the unlikely event that the WebStateList is not empty, observe + // all existing WebStates (pretend this is a batch operation). + if (const int count = web_state_list->count(); count != 0) { + router_->OnSessionEventStarting(); + for (int index = 0; index < count; ++index) { + web::WebState* web_state = web_state_list->GetWebStateAt(index); + web_state_observations_.AddObservation(web_state); + } + router_->OnSessionEventEnded(); + } +} + +void IOSChromeLocalSessionEventRouter::Observer::OnBrowserRemoved( + const BrowserList* browser_list, + Browser* browser) { + if (browser->type() != Browser::Type::kRegular) { + return; + } + + WebStateList* web_state_list = browser->GetWebStateList(); + web_state_list_observations_.RemoveObservation(web_state_list); + + // The Browser are closed before the WebStateList itself, so it is + // possible for the list to be non-empty. Ensure that we stop the + // observation of the WebState if this is the case. + if (const int count = web_state_list->count(); count != 0) { + router_->OnSessionEventStarting(); + for (int index = 0; index < count; ++index) { + web::WebState* web_state = web_state_list->GetWebStateAt(index); + web_state_observations_.RemoveObservation(web_state); + } + router_->OnSessionEventEnded(); + } +} + +void IOSChromeLocalSessionEventRouter::Observer::OnBrowserListShutdown( + BrowserList* browser_list) { + browser_list_observation_.Reset(); + web_state_list_observations_.RemoveAllObservations(); + web_state_observations_.RemoveAllObservations(); +} + +#pragma mark - IOSChromeLocalSessionEventRouter::Observer (WebStateListObserver) void IOSChromeLocalSessionEventRouter::Observer::WebStateListDidChange( WebStateList* web_state_list, @@ -66,12 +169,12 @@ const WebStateListChangeDetach& detach_change = change.As<WebStateListChangeDetach>(); web::WebState* detached_web_state = detach_change.detached_web_state(); + web_state_observations_.RemoveObservation(detached_web_state); if (detach_change.is_closing()) { router_->OnWebStateClosed(); } else { router_->OnWebStateChange(detached_web_state); } - detached_web_state->RemoveObserver(this); break; } case WebStateListChange::Type::kMove: @@ -81,20 +184,20 @@ const WebStateListChangeReplace& replace_change = change.As<WebStateListChangeReplace>(); web::WebState* replaced_web_state = replace_change.replaced_web_state(); + web_state_observations_.RemoveObservation(replaced_web_state); router_->OnWebStateChange(replaced_web_state); - replaced_web_state->RemoveObserver(this); web::WebState* inserted_web_state = replace_change.inserted_web_state(); + web_state_observations_.AddObservation(inserted_web_state); router_->OnWebStateChange(inserted_web_state); - inserted_web_state->AddObserver(this); break; } case WebStateListChange::Type::kInsert: { const WebStateListChangeInsert& insert_change = change.As<WebStateListChangeInsert>(); web::WebState* inserted_web_state = insert_change.inserted_web_state(); + web_state_observations_.AddObservation(inserted_web_state); router_->OnWebStateChange(inserted_web_state); - inserted_web_state->AddObserver(this); break; } case WebStateListChange::Type::kGroupCreate: @@ -113,7 +216,7 @@ } } -#pragma mark - WebStateObserver +#pragma mark - IOSChromeLocalSessionEventRouter::Observer (WebStateObserver) void IOSChromeLocalSessionEventRouter::Observer::TitleWasSet( web::WebState* web_state) { @@ -144,8 +247,7 @@ void IOSChromeLocalSessionEventRouter::Observer::WebStateDestroyed( web::WebState* web_state) { - router_->OnWebStateClosed(); - web_state->RemoveObserver(this); + NOTREACHED(); } void IOSChromeLocalSessionEventRouter::Observer::WillBeginBatchOperation( @@ -158,6 +260,23 @@ router_->OnSessionEventEnded(); } +#pragma mark - IOSChromeLocalSessionEventRouter + +IOSChromeLocalSessionEventRouter::IOSChromeLocalSessionEventRouter( + BrowserList* browser_list, + sync_sessions::SyncSessionsClient* sessions_client, + const syncer::SyncableService::StartSyncFlare& flare) + : observer_(std::make_unique<Observer>(this)), + sessions_client_(sessions_client), + flare_(flare) { + DCHECK(sessions_client_); + // Start the observer now that the object is fully initialized. This may + // call methods on the current instance if the BrowserList is not empty. + observer_->Start(browser_list); +} + +IOSChromeLocalSessionEventRouter::~IOSChromeLocalSessionEventRouter() = default; + void IOSChromeLocalSessionEventRouter::OnSessionEventStarting() { batch_in_progress_++; }
diff --git a/ios/chrome/browser/toolbar/ui_bundled/tab_groups/coordinator/tab_group_indicator_mediator.mm b/ios/chrome/browser/toolbar/ui_bundled/tab_groups/coordinator/tab_group_indicator_mediator.mm index 868579f..dc2e581 100644 --- a/ios/chrome/browser/toolbar/ui_bundled/tab_groups/coordinator/tab_group_indicator_mediator.mm +++ b/ios/chrome/browser/toolbar/ui_bundled/tab_groups/coordinator/tab_group_indicator_mediator.mm
@@ -7,6 +7,7 @@ #import "base/memory/raw_ptr.h" #import "base/memory/weak_ptr.h" #import "base/scoped_observation.h" +#import "base/strings/sys_string_conversions.h" #import "components/collaboration/public/collaboration_service.h" #import "components/feature_engagement/public/feature_constants.h" #import "components/feature_engagement/public/tracker.h" @@ -173,16 +174,16 @@ - (void)manageGroup { const TabGroup* tabGroup = [self currentTabGroup]; - NSString* collabID = + tab_groups::CollaborationId collabID = tab_groups::utils::GetTabGroupCollabID(tabGroup, _tabGroupSyncService); - if (!_shareKitService || !collabID) { + if (!_shareKitService || collabID.value().empty()) { return; } ShareKitManageConfiguration* config = [[ShareKitManageConfiguration alloc] init]; config.baseViewController = self.baseViewController; - config.collabID = collabID; + config.collabID = base::SysUTF8ToNSString(collabID.value()); config.applicationHandler = self.applicationHandler; _shareKitService->ManageTabGroup(config); } @@ -299,9 +300,9 @@ const TabGroup* tabGroup = [self currentTabGroup]; - NSString* savedCollabID = + tab_groups::CollaborationId savedCollabID = tab_groups::utils::GetTabGroupCollabID(tabGroup, _tabGroupSyncService); - BOOL isShared = savedCollabID != nil; + BOOL isShared = !savedCollabID.value().empty(); [_consumer setShared:isShared]; // Prevent the face pile from being set up for tab groups that are not shared. @@ -312,7 +313,7 @@ // Configure the face pile. ShareKitFacePileConfiguration* config = [[ShareKitFacePileConfiguration alloc] init]; - config.collabID = savedCollabID; + config.collabID = base::SysUTF8ToNSString(savedCollabID.value()); config.showsEmptyState = NO; config.avatarSize = kFacePileAvatarSize;
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow.mm b/ios/chrome/browser/ui/authentication/authentication_flow.mm index 378c0e48..fc8a9ff 100644 --- a/ios/chrome/browser/ui/authentication/authentication_flow.mm +++ b/ios/chrome/browser/ui/authentication/authentication_flow.mm
@@ -389,11 +389,13 @@ } case SIGN_OUT_IF_NEEDED: + // TODO(crbug.com/375605482): skip sign out if there is a profile + // switching. [_performer signOutProfile:profile]; return; case SIGN_IN: - [self signInIdentity:_identityToSignIn]; + [self multiProfileSignIn]; return; case REGISTER_FOR_USER_POLICY: @@ -461,7 +463,7 @@ [currentIdentity isEqual:_identityToSignIn]; } -- (void)signInIdentity:(id<SystemIdentity>)identity { +- (void)multiProfileSignIn { if (self.userDecisionCompletion) { self.userDecisionCompletion(); } @@ -475,30 +477,29 @@ BOOL isValidIdentityOnDevice = NO; if (AreSeparateProfilesForManagedAccountsEnabled()) { isValidIdentityOnDevice = IsIdentityInAccountInfos( - identity, identityManager->GetAccountsOnDevice()); + _identityToSignIn, identityManager->GetAccountsOnDevice()); isValidIdentityInProfile = IsIdentityInCoreAccountInfos( - identity, identityManager->GetAccountsWithRefreshTokens()); + _identityToSignIn, identityManager->GetAccountsWithRefreshTokens()); } else { isValidIdentityOnDevice = isValidIdentityInProfile = - accountManagerService->IsValidIdentity(identity); + accountManagerService->IsValidIdentity(_identityToSignIn); } if (isValidIdentityInProfile) { - [_performer signInIdentity:identity - atAccessPoint:self.accessPoint - currentProfile:profile]; - _didSignIn = YES; - [self continueSignin]; + [self signInInCurrentProfile]; } else if (isValidIdentityOnDevice) { CHECK(AreSeparateProfilesForManagedAccountsEnabled()); NSString* sceneIdentifier = _browser->GetSceneState().sceneSessionID; __weak __typeof(self) weakSelf = self; OnProfileSwitchCompletion completion = base::BindOnce( - [](__typeof(self) strongSelf, bool success) { - [strongSelf onSwitchToProfileWithSuccess:success]; + [](__typeof(self) strong_self, bool success, + Browser* new_profile_browser, UIViewController* view_controller) { + [strong_self onSwitchToProfileWithSuccess:success + newProfileBrowser:new_profile_browser + viewController:view_controller]; }, weakSelf); - [_performer switchToProfileWithIdentity:identity + [_performer switchToProfileWithIdentity:_identityToSignIn sceneIdentifier:sceneIdentifier completion:std::move(completion)]; } else { @@ -708,27 +709,39 @@ // Called when the profile switching succeeded or failed (according to // `success`). -- (void)onSwitchToProfileWithSuccess:(BOOL)success { +- (void)onSwitchToProfileWithSuccess:(BOOL)success + newProfileBrowser:(Browser*)newProfileBrowser + viewController:(UIViewController*)viewController { + CHECK(AreSeparateProfilesForManagedAccountsEnabled()); if (success) { - // TODO(crbug.com/375604649): Need to define how to finish the - // authentication flow after the profile switching. - // * What happens for the steps after SIGN_IN? - // REGISTER_FOR_USER_POLICY - // FETCH_USER_POLICY - // FETCH_CAPABILITIES - // COMPLETE_WITH_SUCCESS - // * Is there metrics to record before to the flow is finished? - // It is important to reach the last step otherwise AuthenticationFlow is - // leaked since `_selfRetainer` returns itself. - - // The _browser doesn't exist anymore, since the profile has been switched. - _browser = nil; + _browser = newProfileBrowser; + _presentingViewController = viewController; + // TODO(crbug.com/375605482): Need to sign-out if the new profile is not + // signed in with the right identity (useful for the personal profile). + // TODO(crbug.com/375605482): Need to block user until AuthenticationFlow + // is done? Probably with a blur animation. + [self signInInCurrentProfile]; } else { - // TODO(crbug.com/375604649): Generate an error and call: + // TODO(crbug.com/375605482): Generate an error and call: // `[self handleAuthenticationError:error];`. } } +// Signs in the user using `_identityToSignIn`. The identity must be assigned +// to the current profile. +- (void)signInInCurrentProfile { + ProfileIOS* profile = [self originalProfile]; + signin::IdentityManager* identityManager = + IdentityManagerFactory::GetForProfile(profile); + CHECK(IsIdentityInCoreAccountInfos( + _identityToSignIn, identityManager->GetAccountsWithRefreshTokens())); + [_performer signInIdentity:_identityToSignIn + atAccessPoint:self.accessPoint + currentProfile:profile]; + _didSignIn = YES; + [self continueSignin]; +} + #pragma mark - Used for testing - (void)setPerformerForTesting:(AuthenticationFlowPerformer*)performer {
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_performer.h b/ios/chrome/browser/ui/authentication/authentication_flow_performer.h index 9b9f4d97..9b1923d5 100644 --- a/ios/chrome/browser/ui/authentication/authentication_flow_performer.h +++ b/ios/chrome/browser/ui/authentication/authentication_flow_performer.h
@@ -18,7 +18,13 @@ class ProfileIOS; @protocol SystemIdentity; -using OnProfileSwitchCompletion = base::OnceCallback<void(bool success)>; +// Callback called the profile switching succeded (`success` is true) or failed +// (`success` is false). +// If `success is true: +// `browser` and `view_controller` are the browser and the view controller of +// the new profile. +using OnProfileSwitchCompletion = base::OnceCallback< + void(bool success, Browser* browser, UIViewController* view_controller)>; // Performs the sign-in steps and user interactions as part of the sign-in flow. @interface AuthenticationFlowPerformer : NSObject
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm index 2d9ca3b..5291e15 100644 --- a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm +++ b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
@@ -30,8 +30,11 @@ #import "ios/chrome/browser/policy/model/cloud/user_policy_signin_service_factory.h" #import "ios/chrome/browser/policy/model/cloud/user_policy_switch.h" #import "ios/chrome/browser/shared/coordinator/alert/alert_coordinator.h" +#import "ios/chrome/browser/shared/coordinator/scene/scene_state.h" #import "ios/chrome/browser/shared/model/application_context/application_context.h" #import "ios/chrome/browser/shared/model/browser/browser.h" +#import "ios/chrome/browser/shared/model/browser/browser_provider.h" +#import "ios/chrome/browser/shared/model/browser/browser_provider_interface.h" #import "ios/chrome/browser/shared/model/profile/profile_ios.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" @@ -148,8 +151,8 @@ ->FindProfileNameForGaiaID(base::SysNSStringToUTF8(identity.gaiaID)); if (!profileName.has_value()) { base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, - base::BindOnce(std::move(_onProfileSwitchCompletion), false)); + FROM_HERE, base::BindOnce(std::move(_onProfileSwitchCompletion), false, + nullptr, nil)); return; } [_changeProfileHandler changeProfile:base::SysUTF8ToNSString(*profileName) @@ -397,7 +400,7 @@ #pragma mark - ChangeProfileObserving - (void)operationFailed:(ChangeProfileFailure)failure { - std::move(_onProfileSwitchCompletion).Run(false); + std::move(_onProfileSwitchCompletion).Run(false, nullptr, nil); } - (void)willStartOperation:(UIViewController*)viewController { @@ -406,7 +409,13 @@ - (void)operationDidComplete:(UIViewController*)viewController withSceneState:(SceneState*)sceneState { - std::move(_onProfileSwitchCompletion).Run(true); + Browser* newProfileBrowser = + sceneState.browserProviderInterface.currentBrowserProvider.browser; + // TODO(crbug.com/375605482): `viewController` is nil. This is not expected. + // `sceneState.rootViewController` is used until the bug is fixed. + viewController = sceneState.rootViewController; + std::move(_onProfileSwitchCompletion) + .Run(true, newProfileBrowser, viewController); } #pragma mark - Private
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index ad283da..5e815f7d 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -345,6 +345,7 @@ "//ios/chrome/browser/policy/model:unit_tests", "//ios/chrome/browser/policy/ui_bundled/idle:unit_tests", "//ios/chrome/browser/post_restore_signin/ui_bundled:unit_tests", + "//ios/chrome/browser/prefs/model:unit_tests", "//ios/chrome/browser/prerender/model:unit_tests", "//ios/chrome/browser/presenters/ui_bundled:unit_tests", "//ios/chrome/browser/price_insights/coordinator:unit_tests",
diff --git a/ios/third_party/earl_grey2/src b/ios/third_party/earl_grey2/src index 598d8e8..2add385 160000 --- a/ios/third_party/earl_grey2/src +++ b/ios/third_party/earl_grey2/src
@@ -1 +1 @@ -Subproject commit 598d8e856bc259d9632cd26e944d46d721c43071 +Subproject commit 2add385c1c502920dd753dfb1fbd830b194f7809
diff --git a/ios_internal b/ios_internal index 0d766f3..a712b78 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit 0d766f3e5bd6d0a896a35d4e398d455f7888b805 +Subproject commit a712b786ea4b03defe96cc34b36f4dbff9f91634
diff --git a/media/base/android/java/src/org/chromium/media/VideoAcceleratorUtil.java b/media/base/android/java/src/org/chromium/media/VideoAcceleratorUtil.java index 0e7a9c77a..4b03fcc 100644 --- a/media/base/android/java/src/org/chromium/media/VideoAcceleratorUtil.java +++ b/media/base/android/java/src/org/chromium/media/VideoAcceleratorUtil.java
@@ -189,11 +189,16 @@ return false; } - // Chromium doesn't bundle a software encoder or decoder for H.264 or H.265 so allow - // usage of software codecs through MediaCodec for those codecs. - private static boolean requiresHardware(String type) { - return !type.equalsIgnoreCase(MediaCodecUtil.MimeTypes.VIDEO_H264) - && !type.equalsIgnoreCase(MediaCodecUtil.MimeTypes.VIDEO_HEVC); + // Chromium doesn't bundle a software encoder for H.264. Since `c2.android.avc.encoder` can + // support up to `2048x2048 & 30fps`, we allow the usage of software codecs through + // MediaCodec for H.264. + // + // However, it should be noted that Chromium also doesn't bundle a software encoder for HEVC. + // And since `c2.android.hevc.encoder` only supports up to `512x512 & 30fps`, which normal + // users can't use as it is a pretty low resolution framerate combination, we explicitly + // choose not to report it as supported. + private static boolean requiresHardwareEncoder(String type) { + return !type.equalsIgnoreCase(MediaCodecUtil.MimeTypes.VIDEO_H264); } // H.264 high profile isn't required by Android platform, so we can only add support if @@ -250,7 +255,7 @@ for (MediaCodecInfo info : codecList) { if (info.isAlias()) continue; // Skip duplicates. if (!info.isEncoder()) continue; - if (!info.isHardwareAccelerated() && requiresHardware(type)) continue; + if (!info.isHardwareAccelerated() && requiresHardwareEncoder(type)) continue; MediaCodecInfo.CodecCapabilities capabilities = null; try {
diff --git a/media/capture/video/shared_memory_buffer_tracker.cc b/media/capture/video/shared_memory_buffer_tracker.cc index cc2b15a8..83fa38a 100644 --- a/media/capture/video/shared_memory_buffer_tracker.cc +++ b/media/capture/video/shared_memory_buffer_tracker.cc
@@ -19,7 +19,7 @@ class SharedMemoryBufferTrackerHandle : public media::VideoCaptureBufferHandle { public: explicit SharedMemoryBufferTrackerHandle( - const base::WritableSharedMemoryMapping& mapping) + base::WritableSharedMemoryMapping& mapping) : mapped_size_(mapping.size()), data_(mapping.GetMemoryAsSpan<uint8_t>().data()) {}
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index d331321b..3bc9975 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -262,6 +262,12 @@ "windows/media_foundation_video_encode_accelerator_win.h", "windows/mf_audio_encoder.cc", "windows/mf_audio_encoder.h", + "windows/mf_video_encoder_shared_state.cc", + "windows/mf_video_encoder_shared_state.h", + "windows/mf_video_encoder_switches.cc", + "windows/mf_video_encoder_switches.h", + "windows/mf_video_encoder_util.cc", + "windows/mf_video_encoder_util.h", "windows/mf_video_processor_accelerator.cc", "windows/mf_video_processor_accelerator.h", "windows/scoped_d3d_buffers.cc",
diff --git a/media/gpu/android/ndk_video_encode_accelerator.cc b/media/gpu/android/ndk_video_encode_accelerator.cc index 074658d..631bd90d 100644 --- a/media/gpu/android/ndk_video_encode_accelerator.cc +++ b/media/gpu/android/ndk_video_encode_accelerator.cc
@@ -21,8 +21,6 @@ #include "media/base/bitstream_buffer.h" #include "media/base/encoder_status.h" #include "media/base/media_serializers_base.h" -#include "media/base/media_switches.h" -#include "media/base/video_codecs.h" #include "media/base/video_frame.h" #include "media/gpu/android/video_accelerator_util.h" #include "media/parsers/h264_level_limits.h" @@ -486,26 +484,7 @@ SupportedProfiles profiles; for (auto& info : GetEncoderInfoCache()) { - const auto codec = VideoCodecProfileToVideoCodec(info.profile.profile); - switch (codec) { - case VideoCodec::kHEVC: -#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER) - if (base::FeatureList::IsEnabled(kPlatformHEVCEncoderSupport) && - // Currently only 8bit NV12 and I420 encoding is supported, so limit - // this to main profile only just like other platforms. - info.profile.profile == VideoCodecProfile::HEVCPROFILE_MAIN && - // Some devices may report to have a software HEVC encoder, - // however based on tests, they are not always working well, - // so limit the support to HW only for now. - !info.profile.is_software_codec) { - profiles.push_back(info.profile); - } -#endif - break; - default: - profiles.push_back(info.profile); - break; - } + profiles.push_back(info.profile); } return profiles; } @@ -576,14 +555,6 @@ for (const auto& info : GetEncoderInfoCache()) { if (info.name == codec_name) { - // Skip software HEVC encoders, as it only supports the maximum 512x512 - // resolution at 30fps, and it is also filtered out by - // GetSupportedProfiles(). - if (info.profile.profile == VideoCodecProfile::HEVCPROFILE_MAIN && - info.profile.is_software_codec) { - continue; - } - // TODO(crbug.com/382015342): Set the bitrate limits when we can get them // through MediaCodec API. encoder_info_.resolution_rate_limits.emplace_back(
diff --git a/media/gpu/android/video_accelerator_util.cc b/media/gpu/android/video_accelerator_util.cc index 9baec5d..4c94e75f 100644 --- a/media/gpu/android/video_accelerator_util.cc +++ b/media/gpu/android/video_accelerator_util.cc
@@ -7,10 +7,29 @@ #include "base/android/build_info.h" #include "base/android/jni_string.h" #include "base/no_destructor.h" +#include "media/base/media_switches.h" +#include "media/base/video_codecs.h" // Must come after all headers that specialize FromJniType() / ToJniType(). #include "media/base/android/media_jni_headers/VideoAcceleratorUtil_jni.h" +namespace { +bool isEncoderSupportedProfile(media::VideoCodecProfile profile) { + media::VideoCodec codec = media::VideoCodecProfileToVideoCodec(profile); + if (codec == media::VideoCodec::kHEVC) { +#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER) + // Currently only 8bit NV12 and I420 encoding is supported, so limit + // this to main profile only just like other platforms. + return base::FeatureList::IsEnabled(media::kPlatformHEVCEncoderSupport) && + profile == media::VideoCodecProfile::HEVCPROFILE_MAIN; +#else + return false; +#endif + } + return true; +} +} // namespace + namespace media { const std::vector<MediaCodecEncoderInfo>& GetEncoderInfoCache() { @@ -32,6 +51,9 @@ MediaCodecEncoderInfo info; info.profile.profile = static_cast<VideoCodecProfile>( Java_SupportedProfileAdapter_getProfile(env, java_profile)); + if (!isEncoderSupportedProfile(info.profile.profile)) { + continue; + } info.profile.min_resolution = gfx::Size( Java_SupportedProfileAdapter_getMinWidth(env, java_profile), Java_SupportedProfileAdapter_getMinHeight(env, java_profile));
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc index 0a9e322f..aaaf4d6 100644 --- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc +++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -52,6 +52,8 @@ #include "media/gpu/h264_rate_controller.h" #include "media/gpu/h264_ratectrl_rtc.h" #include "media/gpu/windows/h264_video_rate_control_wrapper.h" +#include "media/gpu/windows/mf_video_encoder_shared_state.h" +#include "media/gpu/windows/mf_video_encoder_switches.h" #include "media/gpu/windows/vp9_video_rate_control_wrapper.h" #include "media/parsers/temporal_scalability_id_extractor.h" #include "third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.h" @@ -68,258 +70,13 @@ namespace media { -BASE_FEATURE(kExpandMediaFoundationEncodingResolutions, - "ExpandMediaFoundationEncodingResolutions", - base::FEATURE_ENABLED_BY_DEFAULT); - namespace { constexpr uint32_t kDefaultGOPLength = 3000; constexpr uint32_t kDefaultTargetBitrate = 5000000u; -constexpr size_t kDefaultFrameRateNumerator = 30; -constexpr size_t kDefaultFrameRateDenominator = 1; constexpr size_t kNumInputBuffers = 3; // Media Foundation uses 100 nanosecond units for time, see // https://msdn.microsoft.com/en-us/library/windows/desktop/ms697282(v=vs.85).aspx. constexpr size_t kOneMicrosecondInMFSampleTimeUnits = 10; -constexpr int kH26xMaxQp = 51; -constexpr uint64_t kVP9MaxQIndex = 255; -constexpr uint64_t kAV1MaxQIndex = 255; - -// Quantizer parameter used in libvpx vp9 rate control, whose range is 0-63. -// These are based on WebRTC's defaults, cite from -// third_party/webrtc/media/engine/webrtc_video_engine.h. -constexpr uint8_t kVP9MinQuantizer = 2; -constexpr uint8_t kVP9MaxQuantizer = 56; -// Default value from -// //third_party/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc, -constexpr uint8_t kAV1MinQuantizer = 10; -// //third_party/webrtc/media/engine/webrtc_video_engine.h. -constexpr uint8_t kAV1MaxQuantizer = 56; - -// The range for the quantization parameter is determined by examining the -// estimated QP values from the SW bitrate controller in various encoding -// scenarios. -constexpr uint8_t kH264MinQuantizer = 16; -constexpr uint8_t kH264MaxQuantizer = 51; - -#if BUILDFLAG(ENABLE_PLATFORM_HEVC) -// For H.265, ideally we may reuse Min/MaxQp for H.264 from -// media/gpu/vaapi/h264_vaapi_video_encoder_delegate.cc. However -// test shows most of the drivers require a min QP of 10 to reach -// target bitrate especially at low resolution. -constexpr uint8_t kH265MinQuantizer = 10; -constexpr uint8_t kH265MaxQuantizer = 42; -#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC) - -// NV12 is supported natively by all hardware encoders. Other -// formats can be converted by MediaFoundationVideoProcessorAccelerator. -// In the future, specific encoders may also be queried for support -// for additional formats. For example, ARGB may be accepted by -// some encoders directly, or AV1 encoders may accept some 4:4:4 -// formats. -constexpr auto kSupportedPixelFormats = - base::MakeFixedFlatSet<VideoPixelFormat>( - {PIXEL_FORMAT_I420, PIXEL_FORMAT_NV12}); -constexpr auto kSupportedPixelFormatsD3DVideoProcessing = - base::MakeFixedFlatSet<VideoPixelFormat>( - {PIXEL_FORMAT_I420, PIXEL_FORMAT_NV12, PIXEL_FORMAT_YV12, - PIXEL_FORMAT_NV21, PIXEL_FORMAT_ARGB, PIXEL_FORMAT_XRGB, - PIXEL_FORMAT_ABGR, PIXEL_FORMAT_XBGR}); - -// The default supported max framerate and resolution. -constexpr FramerateAndResolution kDefaultMaxFramerateAndResolution = { - kDefaultFrameRateNumerator / kDefaultFrameRateDenominator, - gfx::Size(1920, 1080)}; - -// The default supported min resolution. -constexpr gfx::Size kDefaultMinResolution(32, 32); - -// For H.264, some NVIDIA GPUs may report `MF_VIDEO_MAX_MB_PER_SEC` value equals -// to `6799902`, resulting chromium think 8K & 30fps is supported, and some -// Intel GPUs only support level 5.2. Since most devices only support up to 4K, -// so we set level 5.2 as the max allowed level here to limit max resolution and -// framerate combination can only go up to 2K & 172fps, or 4K & 64fps. -constexpr FramerateAndResolution kLegacy2KMaxFramerateAndResolution = { - 172, gfx::Size(1920, 1080)}; -constexpr FramerateAndResolution kLegacy4KMaxFramerateAndResolution = { - 64, gfx::Size(3840, 2160)}; - -// For H.265/AV1, some NVIDIA GPUs may report `MF_VIDEO_MAX_MB_PER_SEC` value -// equals to `7255273`, resulting chromium think 2K & 880fps is supported. Since -// the max level of H.265/AV1 (6.2/6.3) do not allow framerate >= 300fps, so we -// set level 6.2/6.3 as the max allowed level here and limit max resolution and -// framerate combination can only go up to 2K/4K & 300fps, 8K & 128fps. -constexpr FramerateAndResolution kModern2KMaxFramerateAndResolution = { - 300, gfx::Size(1920, 1080)}; -constexpr FramerateAndResolution kModern4KMaxFramerateAndResolution = { - 300, gfx::Size(3840, 2160)}; -constexpr FramerateAndResolution kModern8KMaxFramerateAndResolution = { - 128, gfx::Size(7680, 4320)}; - -constexpr CLSID kIntelAV1HybridEncoderCLSID = { - 0x62c053ce, - 0x5357, - 0x4794, - {0x8c, 0x5a, 0xfb, 0xef, 0xfe, 0xff, 0xb8, 0x2d}}; - -#ifndef ARCH_CPU_X86 -// Temporal layers are reported to be supported by the Intel driver, but are -// only considered supported by MediaFoundation depending on these flags. This -// support is reported in MediaCapabilities' powerEfficient as well as deciding -// if Initialize() is allowed to succeed. -BASE_FEATURE(kMediaFoundationVP9L1T2Support, - "MediaFoundationVP9L1T2Support", - base::FEATURE_DISABLED_BY_DEFAULT); -// Up to 3 temporal layers, i.e. this enables both L1T2 and L1T3. -BASE_FEATURE(kMediaFoundationVP9L1T3Support, - "MediaFoundationVP9L1T3Support", - base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kMediaFoundationAV1L1T2Support, - "MediaFoundationAV1L1T2Support", - base::FEATURE_DISABLED_BY_DEFAULT); -// Up to 3 temporal layers, i.e. this enables both L1T2 and L1T3. -BASE_FEATURE(kMediaFoundationAV1L1T3Support, - "MediaFoundationAV1L1T3Support", - base::FEATURE_DISABLED_BY_DEFAULT); -#endif // !defined(ARCH_CPU_X86) - -BASE_FEATURE(kMediaFoundationUseSWBRCForH264Camera, - "MediaFoundationUseSWBRCForH264Camera", - base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kMediaFoundationUseSWBRCForH264Desktop, - "MediaFoundationUseSWBRCForH264Desktop", - base::FEATURE_DISABLED_BY_DEFAULT); - -// H.264 SW Bitrate Controller works in fixed delta QP mode by default. The QP -// difference between base and enhancement layer can be controlled using a -// feature parameter. -BASE_FEATURE(kMediaFoundationSWBRCUseFixedDeltaQP, - "MediaFoundationSWBRCUseFixedDeltaQP", - base::FEATURE_ENABLED_BY_DEFAULT); -BASE_FEATURE_PARAM(int, - kMediaFoundationSWBRCFixedDeltaQPValue, - &kMediaFoundationSWBRCUseFixedDeltaQP, - "MediaFoundationSWBRCFixedDeltaQPValue", - 0); - -#if BUILDFLAG(ENABLE_PLATFORM_HEVC) -// For H.265 encoding at L1T1/L1T2 we may use SW bitrate controller when -// constant bitrate encoding is requested. -BASE_FEATURE(kMediaFoundationUseSWBRCForH265, - "MediaFoundationUseSWBRCForH265", - base::FEATURE_DISABLED_BY_DEFAULT); -#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC) - -eAVEncH264VProfile GetH264VProfile(VideoCodecProfile profile, - bool is_constrained_h264) { - switch (profile) { - case H264PROFILE_BASELINE: - return is_constrained_h264 ? eAVEncH264VProfile_ConstrainedBase - : eAVEncH264VProfile_Base; - case H264PROFILE_MAIN: - return eAVEncH264VProfile_Main; - case H264PROFILE_HIGH: - return eAVEncH264VProfile_High; - default: - return eAVEncH264VProfile_unknown; - } -} - -// Convert AV1/VP9 qindex (0-255) to the quantizer parameter input in MF -// AVEncVideoEncodeQP. AVEncVideoEncodeQP maps it to libvpx qp tuning parameter -// and thus the range is 0-63. -uint8_t QindextoAVEncQP(VideoCodec codec, uint8_t q_index) { - if (codec == VideoCodec::kAV1 || codec == VideoCodec::kVP9) { - // The following computation is based on the table in - // //third_party/libvpx/source/libvpx/vp9/encoder/vp9_quantize.c. - // //third_party/libaom/source/libaom/av1/encoder/av1_quantize.c - // { - // 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, - // 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, - // 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, - // 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, - // 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255, - // }; - if (q_index <= 244) { - return (q_index + 3) / 4; - } - if (q_index <= 249) { - return 62; - } - return 63; - } - return q_index; -} - -// Convert AV1/VP9 AVEncVideoEncodeQP values to qindex (0-255) range. -// This is the inverse of QindextoAVEncQP() function above. -uint8_t AVEncQPtoQindex(VideoCodec codec, uint8_t avenc_qp) { - if (codec == VideoCodec::kAV1 || codec == VideoCodec::kVP9) { - uint8_t q_index = avenc_qp * 4; - if (q_index == 248) { - q_index = 249; - } else if (q_index == 252) { - q_index = 255; - } - return q_index; - } - return avenc_qp; -} - -// According to AV1/VP9's bitstream specification, the valid range of qp -// value (defined as base_q_idx) should be 0-255. -bool IsValidQp(VideoCodec codec, uint64_t qp) { - switch (codec) { - case VideoCodec::kH264: -#if BUILDFLAG(ENABLE_PLATFORM_HEVC) - case VideoCodec::kHEVC: -#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC) - return qp <= kH26xMaxQp; - case VideoCodec::kVP9: - return qp <= kVP9MaxQIndex; - case VideoCodec::kAV1: - return qp <= kAV1MaxQIndex; - default: - return false; - } -} - -uint8_t GetMaxQuantizer(VideoCodec codec) { - switch (codec) { - case VideoCodec::kH264: - return kH264MaxQuantizer; -#if BUILDFLAG(ENABLE_PLATFORM_HEVC) - case VideoCodec::kHEVC: - return kH265MaxQuantizer; -#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC) - case VideoCodec::kVP9: - return kVP9MaxQuantizer; - case VideoCodec::kAV1: - return kAV1MaxQuantizer; - default: - return 0; // Return invalid value for unsupported codec. - } -} - -// Only eAVEncVP9VProfile_420_8 is supported on Intel graphics. -eAVEncVP9VProfile GetVP9VProfile(VideoCodecProfile profile) { - switch (profile) { - case VP9PROFILE_PROFILE0: - return eAVEncVP9VProfile_420_8; - default: - return eAVEncVP9VProfile_unknown; - } -} - -// Only eAVEncH265Vprofile_Main_420_8 is supported. -eAVEncH265VProfile GetHEVCProfile(VideoCodecProfile profile) { - switch (profile) { - case HEVCPROFILE_MAIN: - return eAVEncH265VProfile_Main_420_8; - default: - return eAVEncH265VProfile_unknown; - } -} // Get distance from current frame to next temporal base layer frame. uint32_t GetDistanceToNextTemporalBaseLayer(uint32_t frame_number, @@ -331,579 +88,6 @@ : pattern_count - (frame_number % pattern_count); } -MediaFoundationVideoEncodeAccelerator::DriverVendor GetDriverVendor( - IMFActivate* encoder) { - using DriverVendor = MediaFoundationVideoEncodeAccelerator::DriverVendor; - base::win::ScopedCoMem<WCHAR> vendor_id; - UINT32 id_length; - encoder->GetAllocatedString(MFT_ENUM_HARDWARE_VENDOR_ID_Attribute, &vendor_id, - &id_length); - if (id_length != 8) { // Normal vendor ids have length 8. - return DriverVendor::kOther; - } - if (!_wcsnicmp(vendor_id.get(), L"VEN_10DE", id_length)) { - return DriverVendor::kNvidia; - } - if (!_wcsnicmp(vendor_id.get(), L"VEN_1002", id_length)) { - return DriverVendor::kAMD; - } - if (!_wcsnicmp(vendor_id.get(), L"VEN_8086 ", id_length)) { - return DriverVendor::kIntel; - } - if (!_wcsnicmp(vendor_id.get(), L"VEN_QCOM", id_length)) { - return DriverVendor::kQualcomm; - } - return DriverVendor::kOther; -} - -// The driver tells us how many temporal layers it supports, but we may need to -// reduce this limit to avoid bad or untested drivers. -int GetMaxTemporalLayerVendorLimit( - MediaFoundationVideoEncodeAccelerator::DriverVendor vendor, - VideoCodec codec, - const gpu::GpuDriverBugWorkarounds& workarounds) { -#if defined(ARCH_CPU_X86) - // x86 systems sometimes crash in video drivers here. - // More info: https://crbug.com/1253748 - return 1; -#else - using DriverVendor = MediaFoundationVideoEncodeAccelerator::DriverVendor; - // crbug.com/1373780: Nvidia HEVC encoder reports supporting 3 temporal - // layers, but will fail initialization if configured to encoded with - // more than one temporal layers, thus we block Nvidia HEVC encoder for - // temporal SVC encoding. - if (codec == VideoCodec::kHEVC && vendor == DriverVendor::kNvidia) { - return 1; - } - - // Qualcomm HEVC and AV1 encoders report temporal layer support, but will - // fail the tests currently, so block from temporal SVC encoding. - if ((codec == VideoCodec::kHEVC || codec == VideoCodec::kAV1) && - vendor == DriverVendor::kQualcomm) { - return 1; - } - - // Intel drivers with issues of dynamically changing bitrate at CBR mode for - // HEVC should be blocked from L1T3 encoding, as there is no SW BRC support - // for that at present. - if (codec == VideoCodec::kHEVC && vendor == DriverVendor::kIntel && - workarounds.disable_hevc_hmft_cbr_encoding) { - return 2; - } - - // Temporal layer encoding is disabled for VP9 unless a flag is enabled. - // - // For example, the Intel VP9 HW encoder reports supporting 3 temporal layers - // but the number of temporal layers we allow depends on feature flags. At the - // time of writing, Intel L1T3 may not be spec-compliant. - // - See https://crbug.com/1425117 for temporal layer foundation (L1T2/L1T3). - // - See https://crbug.com/1501767 for L1T2 rollout (not L1T3). - if (codec == VideoCodec::kVP9) { - if (vendor == DriverVendor::kIntel && - workarounds.disable_vp9_hmft_temporal_encoding) { - return 1; - } - - if (base::FeatureList::IsEnabled(kMediaFoundationVP9L1T3Support)) { - return 3; - } - if (base::FeatureList::IsEnabled(kMediaFoundationVP9L1T2Support)) { - return 2; - } - return 1; - } - - if (codec == VideoCodec::kAV1) { - // Whenever you add to the allow-list a new temporal layer limit, make sure - // you update output bitstream metadata to indicate whether the encoded AV1 - // bitstream follows WebRTC SVC spec. - if (vendor != DriverVendor::kIntel) { - return 1; - } - if (base::FeatureList::IsEnabled(kMediaFoundationAV1L1T3Support)) { - return 3; - } - if (base::FeatureList::IsEnabled(kMediaFoundationAV1L1T2Support)) { - return 2; - } - return 1; - } - - // No driver/codec specific limit to enforce. - return 3; -#endif -} - -int GetNumSupportedTemporalLayers( - IMFActivate* activate, - VideoCodec codec, - const gpu::GpuDriverBugWorkarounds& workarounds) { - auto vendor = GetDriverVendor(activate); - int max_temporal_layer_vendor_limit = - GetMaxTemporalLayerVendorLimit(vendor, codec, workarounds); - if (max_temporal_layer_vendor_limit == 1) { - return 1; - } - - ComMFTransform encoder; - ComCodecAPI codec_api; - HRESULT hr = activate->ActivateObject(IID_PPV_ARGS(&encoder)); - if (FAILED(hr)) { - // Log to VLOG since errors are expected as part of GetSupportedProfiles(). - DVLOG(2) << "Failed to activate encoder: " << PrintHr(hr); - return 1; - } - - hr = encoder.As(&codec_api); - if (FAILED(hr)) { - // Log to VLOG since errors are expected as part of GetSupportedProfiles(). - DVLOG(2) << "Failed to get encoder as CodecAPI: " << PrintHr(hr); - return 1; - } - - if (codec_api->IsSupported(&CODECAPI_AVEncVideoTemporalLayerCount) != S_OK) { - return 1; - } - - base::win::ScopedVariant min, max, step; - if (FAILED(codec_api->GetParameterRange( - &CODECAPI_AVEncVideoTemporalLayerCount, min.AsInput(), max.AsInput(), - step.AsInput()))) { - return 1; - } - - // Temporal encoding is only considered supported if the driver reports at - // least a span of 1-3 temporal layers. - if (V_UI4(min.ptr()) > 1u || V_UI4(max.ptr()) < 3u) { - return 1; - } - return max_temporal_layer_vendor_limit; -} - -bool IsIntelHybridAV1Encoder(IMFActivate* activate) { - if (GetDriverVendor(activate) == - MediaFoundationVideoEncodeAccelerator::DriverVendor::kIntel) { - // Get the CLSID GUID of the HMFT. - GUID mft_guid = {0}; - activate->GetGUID(MFT_TRANSFORM_CLSID_Attribute, &mft_guid); - if (mft_guid == kIntelAV1HybridEncoderCLSID) { - return true; - } - } - return false; -} - -using MFTEnum2Type = decltype(&MFTEnum2); -MFTEnum2Type GetMFTEnum2Function() { - static const MFTEnum2Type kMFTEnum2Func = []() { - auto mf_dll = base::LoadSystemLibrary(L"mfplat.dll"); - return mf_dll ? reinterpret_cast<MFTEnum2Type>( - base::GetFunctionPointerFromNativeLibrary(mf_dll, - "MFTEnum2")) - : nullptr; - }(); - return kMFTEnum2Func; -} - -// If MFTEnum2 is unavailable, this uses MFTEnumEx and doesn't fill any -// adapter information if there are more than one adapters. -std::vector<ComPtr<IMFActivate>> EnumerateHardwareEncodersLegacy( - VideoCodec codec) { - std::vector<ComPtr<IMFActivate>> encoders; - - uint32_t flags = MFT_ENUM_FLAG_HARDWARE | MFT_ENUM_FLAG_SORTANDFILTER; - MFT_REGISTER_TYPE_INFO input_info; - input_info.guidMajorType = MFMediaType_Video; - input_info.guidSubtype = MFVideoFormat_NV12; - MFT_REGISTER_TYPE_INFO output_info; - output_info.guidMajorType = MFMediaType_Video; - output_info.guidSubtype = VideoCodecToMFSubtype(codec); - - Microsoft::WRL::ComPtr<IDXGIFactory1> factory; - auto hr = CreateDXGIFactory1(IID_PPV_ARGS(&factory)); - if (FAILED(hr)) { - DVLOG(2) << "Failed to create DXGI Factory"; - return encoders; - } - - LUID single_adapter_luid{0, 0}; - int num_adapters = 0; - - Microsoft::WRL::ComPtr<IDXGIAdapter> temp_adapter; - for (UINT adapter_idx = 0; - SUCCEEDED(factory->EnumAdapters(adapter_idx, &temp_adapter)); - adapter_idx++) { - ++num_adapters; - - DXGI_ADAPTER_DESC desc; - hr = temp_adapter->GetDesc(&desc); - if (FAILED(hr)) { - continue; - } - - if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c) { - // Skip MS software adapters. - --num_adapters; - } else { - single_adapter_luid = desc.AdapterLuid; - } - } - - IMFActivate** pp_activates = nullptr; - uint32_t count = 0; - hr = MFTEnumEx(MFT_CATEGORY_VIDEO_ENCODER, flags, &input_info, &output_info, - &pp_activates, &count); - - if (FAILED(hr)) { - // Log to VLOG since errors are expected as part of - // GetSupportedProfiles(). - DVLOG(2) << "Failed to enumerate hardware encoders for " - << GetCodecName(codec) << " : " << PrintHr(hr); - return encoders; - } - - for (UINT32 i = 0; i < count; i++) { - if (codec == VideoCodec::kAV1 && IsIntelHybridAV1Encoder(pp_activates[i])) { - continue; - } - - // We can still infer the MFT's adapter LUID if there's only one adapter - // in the system. - if (num_adapters == 1) { - pp_activates[i]->SetBlob(MFT_ENUM_ADAPTER_LUID, - reinterpret_cast<BYTE*>(&single_adapter_luid), - sizeof(LUID)); - } - encoders.push_back(pp_activates[i]); - } - - if (pp_activates) { - CoTaskMemFree(pp_activates); - } - - return encoders; -} - -std::vector<ComPtr<IMFActivate>> EnumerateHardwareEncoders(VideoCodec codec) { - std::vector<ComPtr<IMFActivate>> encoders; - - if (!InitializeMediaFoundation()) { - return encoders; - } -#if defined(ARCH_CPU_ARM64) - // TODO (crbug.com/1509117): Temporarily disable video encoding on arm64 - // until we figure out what OS reports all codecs as supported. - if (!base::FeatureList::IsEnabled( - kMediaFoundationAcceleratedEncodeOnArm64)) { - return encoders; - } -#endif - - MFTEnum2Type mftenum2_func = GetMFTEnum2Function(); - if (!mftenum2_func) { - return EnumerateHardwareEncodersLegacy(codec); - } - - uint32_t flags = MFT_ENUM_FLAG_HARDWARE | MFT_ENUM_FLAG_SORTANDFILTER; - MFT_REGISTER_TYPE_INFO input_info; - input_info.guidMajorType = MFMediaType_Video; - input_info.guidSubtype = MFVideoFormat_NV12; - MFT_REGISTER_TYPE_INFO output_info; - output_info.guidMajorType = MFMediaType_Video; - output_info.guidSubtype = VideoCodecToMFSubtype(codec); - - Microsoft::WRL::ComPtr<IDXGIFactory1> factory; - auto hr = CreateDXGIFactory1(IID_PPV_ARGS(&factory)); - if (FAILED(hr)) { - DVLOG(2) << "Failed to create DXGI Factory"; - return encoders; - } - - Microsoft::WRL::ComPtr<IDXGIAdapter> temp_adapter; - for (UINT adapter_idx = 0; - SUCCEEDED(factory->EnumAdapters(adapter_idx, &temp_adapter)); - adapter_idx++) { - DXGI_ADAPTER_DESC desc; - hr = temp_adapter->GetDesc(&desc); - if (FAILED(hr)) { - DVLOG(2) << "Failed to get description for adapter " << adapter_idx; - continue; - } - - Microsoft::WRL::ComPtr<IMFAttributes> attributes; - hr = MFCreateAttributes(&attributes, 1); - if (FAILED(hr = attributes->SetBlob( - MFT_ENUM_ADAPTER_LUID, - reinterpret_cast<BYTE*>(&desc.AdapterLuid), sizeof(LUID)))) { - continue; - } - - IMFActivate** pp_activates = nullptr; - uint32_t count = 0; - // MFTEnum2() function call. - hr = mftenum2_func(MFT_CATEGORY_VIDEO_ENCODER, flags, &input_info, - &output_info, attributes.Get(), &pp_activates, &count); - - if (FAILED(hr)) { - // Log to VLOG since errors are expected as part of - // GetSupportedProfiles(). - DVLOG(2) << "Failed to enumerate hardware encoders for " - << GetCodecName(codec) << " at a adapter #" << adapter_idx - << " : " << PrintHr(hr); - continue; - } - - for (UINT32 i = 0; i < count; i++) { - if (codec == VideoCodec::kAV1 && - IsIntelHybridAV1Encoder(pp_activates[i])) { - continue; - } - // It's safe to ignore return value here. - // if SetBlob fails, the IMFActivate won't have a valid adapter LUID - // which will fail the check for preferred adapter LUID, so the - // MFDXGIDeviceManager will not be set for MFT, which is a safe option. - pp_activates[i]->SetBlob(MFT_ENUM_ADAPTER_LUID, - reinterpret_cast<BYTE*>(&desc.AdapterLuid), - sizeof(LUID)); - encoders.push_back(pp_activates[i]); - } - - if (pp_activates) { - CoTaskMemFree(pp_activates); - } - } - - return encoders; -} - -uint32_t CalculateMaxFramerateFromMacroBlocksPerSecond( - const FramerateAndResolution& max_framerate_and_resolution, - uint32_t max_macroblocks_per_second) { - constexpr uint64_t kMacroBlockWidth = 16u; - constexpr uint64_t kMacroBlockHeight = 16u; - - uint64_t max_possible_framerate = std::floor( - (max_macroblocks_per_second * kMacroBlockWidth * kMacroBlockHeight) / - max_framerate_and_resolution.resolution.Area64()); - - return std::clamp(static_cast<uint32_t>(max_possible_framerate), 1u, - max_framerate_and_resolution.frame_rate); -} - -std::vector<FramerateAndResolution> GetMaxFramerateAndResolutionsFromMFT( - VideoCodec codec, - IMFTransform* encoder, - bool allow_set_output_type) { - std::vector<FramerateAndResolution> framerate_and_resolutions; - if (allow_set_output_type) { - ComPtr<IMFMediaType> media_type; - - RETURN_ON_HR_FAILURE(MFCreateMediaType(&media_type), - "Create media type failed", framerate_and_resolutions); - RETURN_ON_HR_FAILURE( - media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), - "Set major type failed", framerate_and_resolutions); - RETURN_ON_HR_FAILURE( - media_type->SetGUID(MF_MT_SUBTYPE, VideoCodecToMFSubtype(codec)), - "Set guid for sub type failed", framerate_and_resolutions); - RETURN_ON_HR_FAILURE( - MFSetAttributeSize( - media_type.Get(), MF_MT_FRAME_SIZE, - kDefaultMaxFramerateAndResolution.resolution.width(), - kDefaultMaxFramerateAndResolution.resolution.height()), - "Set attribute size failed", framerate_and_resolutions); - // Frame rate,30, is dummy value for pass through. - RETURN_ON_HR_FAILURE( - MFSetAttributeRatio( - media_type.Get(), MF_MT_FRAME_RATE, - /*unNumerator=*/kDefaultMaxFramerateAndResolution.frame_rate, - /*unDenominator=*/1), - "Set attribute ratio failed", framerate_and_resolutions); - RETURN_ON_HR_FAILURE(media_type->SetUINT32(MF_MT_AVG_BITRATE, 9000000), - "Set avg bitrate failed", framerate_and_resolutions); - RETURN_ON_HR_FAILURE(media_type->SetUINT32(MF_MT_INTERLACE_MODE, - MFVideoInterlace_Progressive), - "Set interlace mode failed", - framerate_and_resolutions); - - if (codec != VideoCodec::kVP9) { - UINT32 max_level; - switch (codec) { - case VideoCodec::kH264: - max_level = eAVEncH264VLevel5_2; - break; - case VideoCodec::kAV1: - max_level = eAVEncAV1VLevel6_3; - break; - case VideoCodec::kHEVC: - max_level = eAVEncH265VLevel6_2; - break; - default: - NOTREACHED(); - } - RETURN_ON_HR_FAILURE(media_type->SetUINT32(MF_MT_VIDEO_LEVEL, max_level), - "Set video level failed", framerate_and_resolutions); - } - - RETURN_ON_HR_FAILURE( - encoder->SetOutputType(/*stream_id=*/0, media_type.Get(), 0), - "Set output type failed", framerate_and_resolutions); - } - - ComPtr<IMFAttributes> attributes; - RETURN_ON_HR_FAILURE(encoder->GetAttributes(&attributes), - "Get attributes failed", framerate_and_resolutions); - uint32_t max_macroblocks_per_second = - MFGetAttributeUINT32(attributes.Get(), MF_VIDEO_MAX_MB_PER_SEC, 0); - max_macroblocks_per_second &= - 0x0fffffff; // Only lower 28 bits are supported. - - std::vector<FramerateAndResolution> max_framerate_and_resolutions; - if (codec == VideoCodec::kH264) { - max_framerate_and_resolutions.push_back(kLegacy2KMaxFramerateAndResolution); - max_framerate_and_resolutions.push_back(kLegacy4KMaxFramerateAndResolution); - } else { - max_framerate_and_resolutions.push_back(kModern2KMaxFramerateAndResolution); - max_framerate_and_resolutions.push_back(kModern4KMaxFramerateAndResolution); - max_framerate_and_resolutions.push_back(kModern8KMaxFramerateAndResolution); - } - - for (auto& max_framerate_and_resolution : max_framerate_and_resolutions) { - FramerateAndResolution framerate_and_resolution = { - CalculateMaxFramerateFromMacroBlocksPerSecond( - max_framerate_and_resolution, max_macroblocks_per_second), - max_framerate_and_resolution.resolution}; - - // Only if the calculated framerate >= the default framerate, we then - // consider this resolution & framerate combination is supported. - if (framerate_and_resolution.frame_rate >= - (kDefaultFrameRateNumerator / kDefaultFrameRateDenominator)) { - framerate_and_resolutions.push_back(framerate_and_resolution); - } - } - - // If the received value of `max_macroblocks_per_second` equals to zero, - // assign a default value here. - if (framerate_and_resolutions.empty()) { - framerate_and_resolutions.push_back(kDefaultMaxFramerateAndResolution); - } - - return framerate_and_resolutions; -} - -// Ideally, we should query the API to get the minimum resolution of each codec -// under each vendor. However, since there is no such API available, based on -// the actual results, although the minimum resolutions of different codecs for -// each vendor vary, but the results always remain consistent among different -// GPU models. Therefore, we can just hardcode these values within the function. -gfx::Size GetMinResolution( - VideoCodec codec, - MediaFoundationVideoEncodeAccelerator::DriverVendor vendor) { - using DriverVendor = MediaFoundationVideoEncodeAccelerator::DriverVendor; - switch (codec) { - case VideoCodec::kH264: - switch (vendor) { - case DriverVendor::kAMD: - // Below result based on: AMD Radeon(TM) Graphics (Ryzen 7 Pro 4750U), - // AMD Radeon(TM) Graphics (Ryzen 9 9950X), AMD Radeon(TM) RX 6600. - return gfx::Size(128, 128); - case DriverVendor::kIntel: - // Below result based on: Intel UHD Graphics 750, Intel Arc(TM) A380, - // Intel Arc(TM) Graphic (Ultra5 125H), Intel(R) Iris(R) Xe MAX - // Graphics. - return gfx::Size(18, 18); - case DriverVendor::kNvidia: - // Below result based on: NVIDIA RTX 3050, NVIDIA RTX 3070, NVIDIA RTX - // 4080. - return gfx::Size(146, 50); - case DriverVendor::kQualcomm: - // Below result based on: Qualcomm(R) Adreno(TM) 690, Qualcomm(R) - // Adreno(TM) X1-85. - return gfx::Size(96, 96); - case DriverVendor::kOther: - return kDefaultMinResolution; - } - case VideoCodec::kHEVC: - switch (vendor) { - case DriverVendor::kAMD: - // Below result based on: AMD Radeon(TM) Graphics (Ryzen 7 Pro 4750U), - // AMD Radeon(TM) Graphics (Ryzen 9 9950X), AMD Radeon(TM) RX 6600. - return gfx::Size(130, 128); - case DriverVendor::kIntel: - // Below result based on: Intel UHD Graphics 750, Intel Arc(TM) A380, - // Intel Arc(TM) Graphic (Ultra5 125H), Intel(R) Iris(R) Xe MAX - // Graphics. - return gfx::Size(66, 114); - case DriverVendor::kNvidia: - // Below result based on: NVIDIA RTX 3050, NVIDIA RTX 3070, NVIDIA RTX - // 4080. - return gfx::Size(130, 34); - case DriverVendor::kQualcomm: - // Below result based on: Qualcomm(R) Adreno(TM) 690, Qualcomm(R) - // Adreno(TM) X1-85. - return gfx::Size(96, 96); - case DriverVendor::kOther: - return kDefaultMinResolution; - } - case VideoCodec::kVP9: - switch (vendor) { - case DriverVendor::kAMD: - // Below result based on: AMD Radeon(TM) Graphics (Ryzen 9 9950X). - return gfx::Size(66, 66); - case DriverVendor::kIntel: - // Below result based on: Intel UHD Graphics 750, Intel Arc(TM) A380, - // Intel Arc(TM) Graphic (Ultra5 125H), Intel(R) Iris(R) Xe MAX - // Graphics. - // - // NOTE: Intel UHD Graphics 750, Intel Arc(TM) A380, Intel(R) Iris(R) - // Xe MAX Graphics actually only requires >= 66x66, but Intel Arc(TM) - // Graphic (Ultra5 125H) requires >= 66x120. - return gfx::Size(66, 120); - case DriverVendor::kNvidia: - // Below result based on: NVIDIA RTX 4080. - return gfx::Size(66, 66); - // As of the testing date, no Qualcomm hardware supports VP9 encoding. - case DriverVendor::kQualcomm: - case DriverVendor::kOther: - return kDefaultMinResolution; - } - case VideoCodec::kAV1: - switch (vendor) { - case DriverVendor::kAMD: - // Below result based on: AMD Radeon(TM) Graphics (Ryzen 9 9950X). - return gfx::Size(114, 82); - case DriverVendor::kIntel: - // Below result based on: Intel Arc(TM) A380, Intel Arc(TM) Graphic - // (Ultra5 125H). - return gfx::Size(114, 82); - case DriverVendor::kNvidia: - // Below result based on: NVIDIA RTX 4080. - return gfx::Size(130, 66); - case DriverVendor::kQualcomm: - // Below result based on: Qualcomm(R) Adreno(TM) X1-85. - return gfx::Size(256, 128); - case DriverVendor::kOther: - return kDefaultMinResolution; - } - default: - NOTREACHED(); - } -} - -int GetMaxTemporalLayer(VideoCodec codec, - std::vector<ComPtr<IMFActivate>>& activates, - const gpu::GpuDriverBugWorkarounds& workarounds) { - int num_temporal_layers = 1; - - for (size_t i = 0; i < activates.size(); i++) { - num_temporal_layers = std::max( - GetNumSupportedTemporalLayers(activates[i].Get(), codec, workarounds), - num_temporal_layers); - } - - return num_temporal_layers; -} - // Per // https://learn.microsoft.com/en-us/windows/win32/medfound/handling-stream-changes, // encoders should only accept an input type that matches the currently @@ -1088,117 +272,10 @@ DVLOG(3) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::vector<VideoCodec> supported_codecs( - {VideoCodec::kH264, VideoCodec::kVP9, VideoCodec::kAV1}); + MediaFoundationVideoEncoderSharedState* mf_shared_state = + MediaFoundationVideoEncoderSharedState::GetInstance(workarounds_); -#if BUILDFLAG(ENABLE_PLATFORM_HEVC) - if (base::FeatureList::IsEnabled(kPlatformHEVCEncoderSupport)) { - supported_codecs.emplace_back(VideoCodec::kHEVC); - } -#endif - - SupportedProfiles profiles; - for (auto codec : supported_codecs) { - auto activates = EnumerateHardwareEncoders(codec); - if (activates.empty()) { - DVLOG(1) << "Hardware encode acceleration is not available for " - << GetCodecName(codec); - continue; - } - - int num_temporal_layers = - GetMaxTemporalLayer(codec, activates, workarounds_); - auto bitrate_mode = VideoEncodeAccelerator::kConstantMode | - VideoEncodeAccelerator::kVariableMode; - if (codec == VideoCodec::kH264) { - bitrate_mode |= VideoEncodeAccelerator::kExternalMode; - } - - std::vector<FramerateAndResolution> max_framerate_and_resolutions = { - kDefaultMaxFramerateAndResolution}; - gfx::Size min_resolution = kDefaultMinResolution; - - if (base::FeatureList::IsEnabled( - kExpandMediaFoundationEncodingResolutions)) { - // https://crbug.com/40233328, Ideally we'd want supported profiles to - // return the max supported resolution and then during configure() to - // find the encoder which can support the right resolution. - // For now checking only the first encoder seems okay, but we probably - // still need the configure() part: ensure that selected one supports the - // given resolution of the first encoder. - IMFActivate* activate = activates[0].Get(); - ComPtr<IMFTransform> encoder; - if (FAILED(activate->ActivateObject(IID_PPV_ARGS(&encoder)))) { - continue; - } - - CHECK(encoder); - max_framerate_and_resolutions = GetMaxFramerateAndResolutionsFromMFT( - codec, encoder.Get(), /*allow_set_output_type=*/true); - min_resolution = GetMinResolution(codec, GetDriverVendor(activate)); - activate->ShutdownObject(); - } - - for (auto& max_framerate_and_resolution : max_framerate_and_resolutions) { - DVLOG(3) << __func__ << ": " << codec << " codec, max resolution width: " - << max_framerate_and_resolution.resolution.width() - << ", height: " - << max_framerate_and_resolution.resolution.height() - << ", min resolution width: " << min_resolution.width() - << ", height: " << min_resolution.height() - << ", framerate: " << max_framerate_and_resolution.frame_rate; - - SupportedProfile profile(VIDEO_CODEC_PROFILE_UNKNOWN, - max_framerate_and_resolution.resolution, - max_framerate_and_resolution.frame_rate * - kDefaultFrameRateDenominator, - kDefaultFrameRateDenominator, bitrate_mode, - {SVCScalabilityMode::kL1T1}); - profile.min_resolution = min_resolution; - - if (!workarounds_.disable_svc_encoding) { - if (num_temporal_layers >= 2) { - profile.scalability_modes.push_back(SVCScalabilityMode::kL1T2); - } - if (num_temporal_layers >= 3) { - profile.scalability_modes.push_back(SVCScalabilityMode::kL1T3); - } - } - - if (base::FeatureList::IsEnabled(kMediaFoundationD3DVideoProcessing)) { - base::ranges::copy( - kSupportedPixelFormatsD3DVideoProcessing, - std::back_inserter(profile.gpu_supported_pixel_formats)); - } - - SupportedProfile portrait_profile(profile); - portrait_profile.max_resolution.Transpose(); - - if (base::FeatureList::IsEnabled(kMediaFoundationSharedImageEncode)) { - profile.supports_gpu_shared_images = true; - } - - std::vector<VideoCodecProfile> codec_profiles; - if (codec == VideoCodec::kH264) { - codec_profiles = {H264PROFILE_BASELINE, H264PROFILE_MAIN, - H264PROFILE_HIGH}; - } else if (codec == VideoCodec::kVP9) { - codec_profiles = {VP9PROFILE_PROFILE0}; - } else if (codec == VideoCodec::kAV1) { - codec_profiles = {AV1PROFILE_PROFILE_MAIN}; - } else if (codec == VideoCodec::kHEVC) { - codec_profiles = {HEVCPROFILE_MAIN}; - } - - for (const auto codec_profile : codec_profiles) { - profile.profile = portrait_profile.profile = codec_profile; - profiles.push_back(profile); - profiles.push_back(portrait_profile); - } - } - } - - return profiles; + return mf_shared_state->GetSupportedProfiles(); } bool MediaFoundationVideoEncodeAccelerator::Initialize( @@ -1337,22 +414,33 @@ // Get the max framerate and max/min resolutions of the given codec. // // NOTE: - // We use the actual encoder to retrieve max framerate and max/min - // resolutions. The property `MF_VIDEO_MAX_MB_PER_SEC`, which we use to - // calculate the resolution, is a static value stored in the encoder provided - // by the GPU driver. It doesn't change regardless of the parameters we set - // for `SetOutputType()` except for `MF_MT_MAJOR_TYPE` and `MF_MT_SUBTYPE`. - // So, as long as the actual encoder remains the same, the result should be - // unchanged. - // - // On a dual GPU system, the actual encoder selected might be different from - // the one used by "GetSupportedProfile". If that's the case, and if the - // actual encoder can't handle the incoming resolution, we can simply reject - // it without hesitation. + // We first attempt to retrieve max framerate and max/min resolutions from + // cached data. If there is a cache miss, that implies the current encoder is + // not on the same adapter as that used by "GetSupportedProfiles". If so we + // use the actual encoder to retrieve max framerate and max/min resolutions. + // The property `MF_VIDEO_MAX_MB_PER_SEC`, which we use to calculate the + // resolution, is a static value stored in the encoder provided by the GPU + // driver. It doesn't change regardless of the parameters we set for + // `SetOutputType()` except for `MF_MT_MAJOR_TYPE` and `MF_MT_SUBTYPE`. So, as + // long as the actual encoder remains the same, the result should be + // unchanged. If the actual encoder can't handle the incoming resolution, we + // can simply reject it without hesitation. if (base::FeatureList::IsEnabled(kExpandMediaFoundationEncodingResolutions)) { - max_framerate_and_resolutions_ = GetMaxFramerateAndResolutionsFromMFT( - codec_, encoder_.Get(), /*allow_set_output_type=*/false); - min_resolution_ = GetMinResolution(codec_, vendor_); + size_t activate_hash = GetMFTGuidHash(activate_.Get()); + MediaFoundationVideoEncoderSharedState* shared_state = + MediaFoundationVideoEncoderSharedState::GetInstance(workarounds_); + DCHECK(shared_state); + const auto& max_framerate_and_resolutions = + shared_state->GetMaxFramerateAndResolutions(activate_hash); + const auto& min_resolution = shared_state->GetMinResolution(activate_hash); + max_framerate_and_resolutions_ = + !max_framerate_and_resolutions.empty() + ? max_framerate_and_resolutions + : GetMaxFramerateAndResolutionsFromMFT( + codec_, encoder_.Get(), /*allow_set_output_type=*/false); + min_resolution_ = !min_resolution.IsEmpty() + ? min_resolution + : GetMinResolution(codec_, vendor_); } else { max_framerate_and_resolutions_ = {kDefaultMaxFramerateAndResolution}; min_resolution_ = kDefaultMinResolution;
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.h b/media/gpu/windows/media_foundation_video_encode_accelerator_win.h index 4712f70..61bb8fe1 100644 --- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.h +++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.h
@@ -34,16 +34,12 @@ #include "media/gpu/command_buffer_helper.h" #include "media/gpu/media_gpu_export.h" #include "media/gpu/windows/d3d_com_defs.h" +#include "media/gpu/windows/mf_video_encoder_util.h" #include "media/gpu/windows/mf_video_processor_accelerator.h" #include "media/video/video_encode_accelerator.h" namespace media { -struct FramerateAndResolution { - uint32_t frame_rate; - gfx::Size resolution; -}; - class VideoRateControlWrapper; class TemporalScalabilityIdExtractor; @@ -104,8 +100,6 @@ IFACEMETHODIMP_(ULONG) Release() override; IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) override; - enum class DriverVendor { kOther, kNvidia, kIntel, kAMD, kQualcomm }; - struct GetCommandBufferHelperResult { GetCommandBufferHelperResult(); GetCommandBufferHelperResult(const GetCommandBufferHelperResult& other);
diff --git a/media/gpu/windows/mf_video_encoder_shared_state.cc b/media/gpu/windows/mf_video_encoder_shared_state.cc new file mode 100644 index 0000000..69fa3b9e --- /dev/null +++ b/media/gpu/windows/mf_video_encoder_shared_state.cc
@@ -0,0 +1,250 @@ +// 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 "media/gpu/windows/mf_video_encoder_shared_state.h" + +#include <objbase.h> + +#include <codecapi.h> +#include <mfapi.h> +#include <mferror.h> +#include <mftransform.h> +#include <wrl/client.h> + +#include <utility> + +#include "base/features.h" +#include "base/logging.h" +#include "base/win/scoped_co_mem.h" +#include "base/win/scoped_variant.h" +#include "base/win/win_util.h" +#include "build/build_config.h" +#include "media/base/media_switches.h" +#include "media/base/win/mf_helpers.h" +#include "media/gpu/windows/d3d_com_defs.h" +#include "media/gpu/windows/mf_video_encoder_switches.h" + +namespace media { + +namespace { + +int GetNumSupportedTemporalLayers( + IMFActivate* activate, + VideoCodec codec, + const gpu::GpuDriverBugWorkarounds& workarounds) { + auto vendor = GetDriverVendor(activate); + int max_temporal_layer_vendor_limit = + GetMaxTemporalLayerVendorLimit(vendor, codec, workarounds); + if (max_temporal_layer_vendor_limit == 1) { + return 1; + } + + ComMFTransform encoder; + ComCodecAPI codec_api; + HRESULT hr = activate->ActivateObject(IID_PPV_ARGS(&encoder)); + if (FAILED(hr)) { + // Log to VLOG since errors are expected as part of GetSupportedProfiles(). + DVLOG(2) << "Failed to activate encoder: " << PrintHr(hr); + return 1; + } + + hr = encoder.As(&codec_api); + if (FAILED(hr)) { + // Log to VLOG since errors are expected as part of GetSupportedProfiles(). + DVLOG(2) << "Failed to get encoder as CodecAPI: " << PrintHr(hr); + return 1; + } + + if (codec_api->IsSupported(&CODECAPI_AVEncVideoTemporalLayerCount) != S_OK) { + return 1; + } + + base::win::ScopedVariant min, max, step; + if (FAILED(codec_api->GetParameterRange( + &CODECAPI_AVEncVideoTemporalLayerCount, min.AsInput(), max.AsInput(), + step.AsInput()))) { + return 1; + } + + // Temporal encoding is only considered supported if the driver reports at + // least a span of 1-3 temporal layers. + if (V_UI4(min.ptr()) > 1u || V_UI4(max.ptr()) < 3u) { + return 1; + } + return max_temporal_layer_vendor_limit; +} + +int GetMaxTemporalLayer( + VideoCodec codec, + std::vector<Microsoft::WRL::ComPtr<IMFActivate>>& activates, + const gpu::GpuDriverBugWorkarounds& workarounds) { + int num_temporal_layers = 1; + + for (size_t i = 0; i < activates.size(); i++) { + num_temporal_layers = std::max( + GetNumSupportedTemporalLayers(activates[i].Get(), codec, workarounds), + num_temporal_layers); + } + + return num_temporal_layers; +} + +} // namespace + +// static +MediaFoundationVideoEncoderSharedState* +MediaFoundationVideoEncoderSharedState::GetInstance( + const gpu::GpuDriverBugWorkarounds& workarounds) { + static MediaFoundationVideoEncoderSharedState* instance = + new MediaFoundationVideoEncoderSharedState(workarounds); + return instance; +} + +MediaFoundationVideoEncoderSharedState:: + ~MediaFoundationVideoEncoderSharedState() = default; + +MediaFoundationVideoEncoderSharedState::MediaFoundationVideoEncoderSharedState( + const gpu::GpuDriverBugWorkarounds& workarounds) + : workarounds_(workarounds) { + GetSupportedProfilesInternal(); +} + +const std::vector<FramerateAndResolution> +MediaFoundationVideoEncoderSharedState::GetMaxFramerateAndResolutions( + size_t activate_hash) const { + auto it = max_framerate_and_resolutions_.find(activate_hash); + if (it != max_framerate_and_resolutions_.end()) { + return it->second; + } + return {}; +} + +const gfx::Size MediaFoundationVideoEncoderSharedState::GetMinResolution( + size_t activate_hash) const { + auto it = min_resolutions_.find(activate_hash); + if (it != min_resolutions_.end()) { + return it->second; + } + return {}; +} + +void MediaFoundationVideoEncoderSharedState::GetSupportedProfilesInternal() { + std::vector<VideoCodec> supported_codecs( + {VideoCodec::kH264, VideoCodec::kVP9, VideoCodec::kAV1}); + +#if BUILDFLAG(ENABLE_PLATFORM_HEVC) + if (base::FeatureList::IsEnabled(kPlatformHEVCEncoderSupport)) { + supported_codecs.emplace_back(VideoCodec::kHEVC); + } +#endif + + for (auto codec : supported_codecs) { + auto activates = EnumerateHardwareEncoders(codec); + if (activates.empty()) { + DVLOG(1) << "Hardware encode acceleration is not available for " + << GetCodecName(codec); + continue; + } + + int num_temporal_layers = + GetMaxTemporalLayer(codec, activates, workarounds_); + auto bitrate_mode = VideoEncodeAccelerator::kConstantMode | + VideoEncodeAccelerator::kVariableMode; + if (codec == VideoCodec::kH264) { + bitrate_mode |= VideoEncodeAccelerator::kExternalMode; + } + + std::vector<FramerateAndResolution> max_framerate_and_resolutions = { + kDefaultMaxFramerateAndResolution}; + gfx::Size min_resolution = kDefaultMinResolution; + + size_t activate_hash = 0; + if (base::FeatureList::IsEnabled( + kExpandMediaFoundationEncodingResolutions)) { + // https://crbug.com/40233328, Ideally we'd want supported profiles to + // return the max supported resolution and then during configure() to + // find the encoder which can support the right resolution. + // For now checking only the first encoder seems okay, but we probably + // still need the configure() part: ensure that selected one supports the + // given resolution of the first encoder. + IMFActivate* activate = activates[0].Get(); + Microsoft::WRL::ComPtr<IMFTransform> encoder; + if (FAILED(activate->ActivateObject(IID_PPV_ARGS(&encoder)))) { + continue; + } + + activate_hash = GetMFTGuidHash(activate); + CHECK(encoder); + max_framerate_and_resolutions = GetMaxFramerateAndResolutionsFromMFT( + codec, encoder.Get(), /*allow_set_output_type=*/true); + min_resolution = + ::media::GetMinResolution(codec, GetDriverVendor(activate)); + activate->ShutdownObject(); + } + + for (auto& max_framerate_and_resolution : max_framerate_and_resolutions) { + DVLOG(3) << __func__ << ": " << codec << " codec, max resolution width: " + << max_framerate_and_resolution.resolution.width() + << ", height: " + << max_framerate_and_resolution.resolution.height() + << ", min resolution width: " << min_resolution.width() + << ", height: " << min_resolution.height() + << ", framerate: " << max_framerate_and_resolution.frame_rate; + + VideoEncodeAccelerator::SupportedProfile profile( + VIDEO_CODEC_PROFILE_UNKNOWN, max_framerate_and_resolution.resolution, + max_framerate_and_resolution.frame_rate * + kDefaultFrameRateDenominator, + kDefaultFrameRateDenominator, bitrate_mode, + {SVCScalabilityMode::kL1T1}); + profile.min_resolution = min_resolution; + + if (!workarounds_.disable_svc_encoding) { + if (num_temporal_layers >= 2) { + profile.scalability_modes.push_back(SVCScalabilityMode::kL1T2); + } + if (num_temporal_layers >= 3) { + profile.scalability_modes.push_back(SVCScalabilityMode::kL1T3); + } + } + + if (base::FeatureList::IsEnabled(kMediaFoundationD3DVideoProcessing)) { + base::ranges::copy( + kSupportedPixelFormatsD3DVideoProcessing, + std::back_inserter(profile.gpu_supported_pixel_formats)); + } + + VideoEncodeAccelerator::SupportedProfile portrait_profile(profile); + portrait_profile.max_resolution.Transpose(); + + if (base::FeatureList::IsEnabled(kMediaFoundationSharedImageEncode)) { + profile.supports_gpu_shared_images = true; + } + + std::vector<VideoCodecProfile> codec_profiles; + if (codec == VideoCodec::kH264) { + codec_profiles = {H264PROFILE_BASELINE, H264PROFILE_MAIN, + H264PROFILE_HIGH}; + } else if (codec == VideoCodec::kVP9) { + codec_profiles = {VP9PROFILE_PROFILE0}; + } else if (codec == VideoCodec::kAV1) { + codec_profiles = {AV1PROFILE_PROFILE_MAIN}; + } else if (codec == VideoCodec::kHEVC) { + codec_profiles = {HEVCPROFILE_MAIN}; + } + + for (const auto codec_profile : codec_profiles) { + profile.profile = portrait_profile.profile = codec_profile; + supported_profiles_.push_back(profile); + supported_profiles_.push_back(portrait_profile); + } + } + + max_framerate_and_resolutions_[activate_hash] = + std::move(max_framerate_and_resolutions); + min_resolutions_[activate_hash] = std::move(min_resolution); + } +} + +} // namespace media
diff --git a/media/gpu/windows/mf_video_encoder_shared_state.h b/media/gpu/windows/mf_video_encoder_shared_state.h new file mode 100644 index 0000000..c3614f2b --- /dev/null +++ b/media/gpu/windows/mf_video_encoder_shared_state.h
@@ -0,0 +1,63 @@ +// 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 MEDIA_GPU_WINDOWS_MF_VIDEO_ENCODER_SHARED_STATE_H_ +#define MEDIA_GPU_WINDOWS_MF_VIDEO_ENCODER_SHARED_STATE_H_ + +#include <vector> + +#include "base/containers/flat_map.h" +#include "gpu/config/gpu_driver_bug_workarounds.h" +#include "media/gpu/media_gpu_export.h" +#include "media/gpu/windows/mf_video_encoder_util.h" +#include "media/video/video_encode_accelerator.h" +#include "ui/gfx/geometry/size.h" + +namespace media { + +// This class is used to share some common states among multiple instances of +// MediaFoundationVideoEncodeAccelerator, such as supported profiles, max +// supported resolutions and framerates, as well as minimum supported resolution +// of HMFTs enumerated on the platform. +class MEDIA_GPU_EXPORT MediaFoundationVideoEncoderSharedState { + public: + static MediaFoundationVideoEncoderSharedState* GetInstance( + const gpu::GpuDriverBugWorkarounds& workarounds); + + MediaFoundationVideoEncoderSharedState( + const MediaFoundationVideoEncoderSharedState&) = delete; + MediaFoundationVideoEncoderSharedState& operator=( + const MediaFoundationVideoEncoderSharedState&) = delete; + + const VideoEncodeAccelerator::SupportedProfiles& GetSupportedProfiles() + const { + return supported_profiles_; + } + + // Returns the maximum framerate and resolution combinations supported by the + // activate whose CLSID hash is |activate_hash|. + const std::vector<FramerateAndResolution> GetMaxFramerateAndResolutions( + size_t activate_hash) const; + + // Returns the minimum resolution supported by the activate whose CLSID hash + // is |activate_hash|. + const gfx::Size GetMinResolution(size_t activate_hash) const; + + private: + MediaFoundationVideoEncoderSharedState( + const gpu::GpuDriverBugWorkarounds& workarounds); + virtual ~MediaFoundationVideoEncoderSharedState(); + + void GetSupportedProfilesInternal(); + + gpu::GpuDriverBugWorkarounds workarounds_; + VideoEncodeAccelerator::SupportedProfiles supported_profiles_; + base::flat_map<size_t, std::vector<FramerateAndResolution>> + max_framerate_and_resolutions_; + base::flat_map<size_t, gfx::Size> min_resolutions_; +}; + +} // namespace media + +#endif // MEDIA_GPU_WINDOWS_MF_VIDEO_ENCODER_SHARED_STATE_H_
diff --git a/media/gpu/windows/mf_video_encoder_switches.cc b/media/gpu/windows/mf_video_encoder_switches.cc new file mode 100644 index 0000000..b4a7a84 --- /dev/null +++ b/media/gpu/windows/mf_video_encoder_switches.cc
@@ -0,0 +1,61 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/gpu/windows/mf_video_encoder_switches.h" + +namespace media { + +BASE_FEATURE(kExpandMediaFoundationEncodingResolutions, + "ExpandMediaFoundationEncodingResolutions", + base::FEATURE_ENABLED_BY_DEFAULT); + +#ifndef ARCH_CPU_X86 +// Temporal layers are reported to be supported by the Intel driver, but are +// only considered supported by MediaFoundation depending on these flags. This +// support is reported in MediaCapabilities' powerEfficient as well as deciding +// if Initialize() is allowed to succeed. +BASE_FEATURE(kMediaFoundationVP9L1T2Support, + "MediaFoundationVP9L1T2Support", + base::FEATURE_DISABLED_BY_DEFAULT); +// Up to 3 temporal layers, i.e. this enables both L1T2 and L1T3. +BASE_FEATURE(kMediaFoundationVP9L1T3Support, + "MediaFoundationVP9L1T3Support", + base::FEATURE_DISABLED_BY_DEFAULT); + +BASE_FEATURE(kMediaFoundationAV1L1T2Support, + "MediaFoundationAV1L1T2Support", + base::FEATURE_DISABLED_BY_DEFAULT); +// Up to 3 temporal layers, i.e. this enables both L1T2 and L1T3. +BASE_FEATURE(kMediaFoundationAV1L1T3Support, + "MediaFoundationAV1L1T3Support", + base::FEATURE_DISABLED_BY_DEFAULT); +#endif // !defined(ARCH_CPU_X86) + +BASE_FEATURE(kMediaFoundationUseSWBRCForH264Camera, + "MediaFoundationUseSWBRCForH264Camera", + base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kMediaFoundationUseSWBRCForH264Desktop, + "MediaFoundationUseSWBRCForH264Desktop", + base::FEATURE_DISABLED_BY_DEFAULT); + +// H.264 SW Bitrate Controller works in fixed delta QP mode by default. The QP +// difference between base and enhancement layer can be controlled using a +// feature parameter. +BASE_FEATURE(kMediaFoundationSWBRCUseFixedDeltaQP, + "MediaFoundationSWBRCUseFixedDeltaQP", + base::FEATURE_ENABLED_BY_DEFAULT); +const base::FeatureParam<int> kMediaFoundationSWBRCFixedDeltaQPValue( + &kMediaFoundationSWBRCUseFixedDeltaQP, + "MediaFoundationSWBRCFixedDeltaQPValue", + 0); + +#if BUILDFLAG(ENABLE_PLATFORM_HEVC) +// For H.265 encoding at L1T1/L1T2 we may use SW bitrate controller when +// constant bitrate encoding is requested. +BASE_FEATURE(kMediaFoundationUseSWBRCForH265, + "MediaFoundationUseSWBRCForH265", + base::FEATURE_DISABLED_BY_DEFAULT); +#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC) + +} // namespace media
diff --git a/media/gpu/windows/mf_video_encoder_switches.h b/media/gpu/windows/mf_video_encoder_switches.h new file mode 100644 index 0000000..9a92052 --- /dev/null +++ b/media/gpu/windows/mf_video_encoder_switches.h
@@ -0,0 +1,40 @@ +// 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 MEDIA_GPU_WINDOWS_MF_VIDEO_ENCODER_SWITCHES_H_ +#define MEDIA_GPU_WINDOWS_MF_VIDEO_ENCODER_SWITCHES_H_ + +#include <stdint.h> + +#include "base/feature_list.h" +#include "base/metrics/field_trial_params.h" +#include "build/build_config.h" +#include "build/buildflag.h" +#include "media/gpu/buildflags.h" +#include "media/media_buildflags.h" + +namespace media { + +BASE_DECLARE_FEATURE(kExpandMediaFoundationEncodingResolutions); + +#ifndef ARCH_CPU_X86 +BASE_DECLARE_FEATURE(kMediaFoundationVP9L1T2Support); +BASE_DECLARE_FEATURE(kMediaFoundationVP9L1T3Support); +BASE_DECLARE_FEATURE(kMediaFoundationAV1L1T2Support); +BASE_DECLARE_FEATURE(kMediaFoundationAV1L1T3Support); +#endif // !defined(ARCH_CPU_X86) + +BASE_DECLARE_FEATURE(kMediaFoundationUseSWBRCForH264Camera); +BASE_DECLARE_FEATURE(kMediaFoundationUseSWBRCForH264Desktop); + +BASE_DECLARE_FEATURE(kMediaFoundationSWBRCUseFixedDeltaQP); +extern const base::FeatureParam<int> kMediaFoundationSWBRCFixedDeltaQPValue; + +#if BUILDFLAG(ENABLE_PLATFORM_HEVC) +BASE_DECLARE_FEATURE(kMediaFoundationUseSWBRCForH265); +#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC) + +} // namespace media + +#endif // MEDIA_GPU_WINDOWS_MF_VIDEO_ENCODER_SWITCHES_H_
diff --git a/media/gpu/windows/mf_video_encoder_util.cc b/media/gpu/windows/mf_video_encoder_util.cc new file mode 100644 index 0000000..adb35ea --- /dev/null +++ b/media/gpu/windows/mf_video_encoder_util.cc
@@ -0,0 +1,701 @@ +// 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. + +#ifdef UNSAFE_BUFFERS_BUILD +// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. +#pragma allow_unsafe_buffers +#endif + +#include "media/gpu/windows/mf_video_encoder_util.h" + +#include "base/check.h" +#include "base/containers/span.h" +#include "base/hash/hash.h" +#include "base/native_library.h" +#include "base/win/scoped_co_mem.h" +#include "base/win/scoped_variant.h" +#include "base/win/win_util.h" +#include "build/build_config.h" +#include "media/base/media_switches.h" +#include "media/base/win/mf_helpers.h" +#include "media/base/win/mf_initializer.h" +#include "media/gpu/windows/mf_video_encoder_switches.h" + +namespace media { + +// AVEncVideoEncodeQP maps QP to libvpx qp tuning parameter +// and thus the range is 0-63. +uint8_t QindextoAVEncQP(VideoCodec codec, uint8_t q_index) { + if (codec == VideoCodec::kAV1 || codec == VideoCodec::kVP9) { + // The following computation is based on the table in + // //third_party/libvpx/source/libvpx/vp9/encoder/vp9_quantize.c. + // //third_party/libaom/source/libaom/av1/encoder/av1_quantize.c + // { + // 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, + // 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, + // 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, + // 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, + // 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255, + // }; + if (q_index <= 244) { + return (q_index + 3) / 4; + } + if (q_index <= 249) { + return 62; + } + return 63; + } + return q_index; +} + +// This is the inverse of QindextoAVEncQP() function. +uint8_t AVEncQPtoQindex(VideoCodec codec, uint8_t avenc_qp) { + if (codec == VideoCodec::kAV1 || codec == VideoCodec::kVP9) { + uint8_t q_index = avenc_qp * 4; + if (q_index == 248) { + q_index = 249; + } else if (q_index == 252) { + q_index = 255; + } + return q_index; + } + return avenc_qp; +} + +// According to AV1/VP9's bitstream specification, the valid range of qp +// value (defined as base_q_idx) should be 0-255. +bool IsValidQp(VideoCodec codec, uint64_t qp) { + switch (codec) { + case VideoCodec::kH264: +#if BUILDFLAG(ENABLE_PLATFORM_HEVC) + case VideoCodec::kHEVC: +#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC) + return qp <= kH26xMaxQp; + case VideoCodec::kVP9: + return qp <= kVP9MaxQIndex; + case VideoCodec::kAV1: + return qp <= kAV1MaxQIndex; + default: + return false; + } +} + +uint8_t GetMaxQuantizer(VideoCodec codec) { + switch (codec) { + case VideoCodec::kH264: + return kH264MaxQuantizer; +#if BUILDFLAG(ENABLE_PLATFORM_HEVC) + case VideoCodec::kHEVC: + return kH265MaxQuantizer; +#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC) + case VideoCodec::kVP9: + return kVP9MaxQuantizer; + case VideoCodec::kAV1: + return kAV1MaxQuantizer; + default: + return 0; // Return invalid value for unsupported codec. + } +} + +eAVEncH264VProfile GetH264VProfile(VideoCodecProfile profile, + bool is_constrained_h264) { + switch (profile) { + case H264PROFILE_BASELINE: + return is_constrained_h264 ? eAVEncH264VProfile_ConstrainedBase + : eAVEncH264VProfile_Base; + case H264PROFILE_MAIN: + return eAVEncH264VProfile_Main; + case H264PROFILE_HIGH: + return eAVEncH264VProfile_High; + default: + return eAVEncH264VProfile_unknown; + } +} + +// Only eAVEncVP9VProfile_420_8 is supported on Intel graphics. +eAVEncVP9VProfile GetVP9VProfile(VideoCodecProfile profile) { + switch (profile) { + case VP9PROFILE_PROFILE0: + return eAVEncVP9VProfile_420_8; + default: + return eAVEncVP9VProfile_unknown; + } +} + +// Only eAVEncH265Vprofile_Main_420_8 is supported. +eAVEncH265VProfile GetHEVCProfile(VideoCodecProfile profile) { + switch (profile) { + case HEVCPROFILE_MAIN: + return eAVEncH265VProfile_Main_420_8; + default: + return eAVEncH265VProfile_unknown; + } +} + +DriverVendor GetDriverVendor(IMFActivate* encoder) { + DCHECK(encoder); + base::win::ScopedCoMem<WCHAR> vendor_id; + UINT32 id_length; + encoder->GetAllocatedString(MFT_ENUM_HARDWARE_VENDOR_ID_Attribute, &vendor_id, + &id_length); + if (id_length != 8) { // Normal vendor ids have length 8. + return DriverVendor::kOther; + } + if (!_wcsnicmp(vendor_id.get(), L"VEN_10DE", id_length)) { + return DriverVendor::kNvidia; + } + if (!_wcsnicmp(vendor_id.get(), L"VEN_1002", id_length)) { + return DriverVendor::kAMD; + } + if (!_wcsnicmp(vendor_id.get(), L"VEN_8086 ", id_length)) { + return DriverVendor::kIntel; + } + if (!_wcsnicmp(vendor_id.get(), L"VEN_QCOM", id_length)) { + return DriverVendor::kQualcomm; + } + return DriverVendor::kOther; +} + +// The driver tells us how many temporal layers it supports, but we may need to +// reduce this limit to avoid bad or untested drivers. +int GetMaxTemporalLayerVendorLimit( + DriverVendor vendor, + VideoCodec codec, + const gpu::GpuDriverBugWorkarounds& workarounds) { +#if defined(ARCH_CPU_X86) + // x86 systems sometimes crash in video drivers here. + // More info: https://crbug.com/1253748 + return 1; +#else + // crbug.com/1373780: Nvidia HEVC encoder reports supporting 3 temporal + // layers, but will fail initialization if configured to encoded with + // more than one temporal layers, thus we block Nvidia HEVC encoder for + // temporal SVC encoding. + if (codec == VideoCodec::kHEVC && vendor == DriverVendor::kNvidia) { + return 1; + } + + // Qualcomm HEVC and AV1 encoders report temporal layer support, but will + // fail the tests currently, so block from temporal SVC encoding. + if ((codec == VideoCodec::kHEVC || codec == VideoCodec::kAV1) && + vendor == DriverVendor::kQualcomm) { + return 1; + } + + // Intel drivers with issues of dynamically changing bitrate at CBR mode for + // HEVC should be blocked from L1T3 encoding, as there is no SW BRC support + // for that at present. + if (codec == VideoCodec::kHEVC && vendor == DriverVendor::kIntel && + workarounds.disable_hevc_hmft_cbr_encoding) { + return 2; + } + + // Temporal layer encoding is disabled for VP9 unless a flag is enabled. + // + // For example, the Intel VP9 HW encoder reports supporting 3 temporal layers + // but the number of temporal layers we allow depends on feature flags. At the + // time of writing, Intel L1T3 may not be spec-compliant. + // - See https://crbug.com/1425117 for temporal layer foundation (L1T2/L1T3). + // - See https://crbug.com/1501767 for L1T2 rollout (not L1T3). + if (codec == VideoCodec::kVP9) { + if (vendor == DriverVendor::kIntel && + workarounds.disable_vp9_hmft_temporal_encoding) { + return 1; + } + + if (base::FeatureList::IsEnabled(kMediaFoundationVP9L1T3Support)) { + return 3; + } + if (base::FeatureList::IsEnabled(kMediaFoundationVP9L1T2Support)) { + return 2; + } + return 1; + } + + if (codec == VideoCodec::kAV1) { + // Whenever you add to the allow-list a new temporal layer limit, make sure + // you update output bitstream metadata to indicate whether the encoded AV1 + // bitstream follows WebRTC SVC spec. + if (vendor != DriverVendor::kIntel) { + return 1; + } + if (base::FeatureList::IsEnabled(kMediaFoundationAV1L1T3Support)) { + return 3; + } + if (base::FeatureList::IsEnabled(kMediaFoundationAV1L1T2Support)) { + return 2; + } + return 1; + } + + // No driver/codec specific limit to enforce. + return 3; +#endif +} + +int GetNumSupportedTemporalLayers( + IMFActivate* activate, + VideoCodec codec, + const gpu::GpuDriverBugWorkarounds& workarounds) { + DCHECK(activate); + auto vendor = GetDriverVendor(activate); + int max_temporal_layer_vendor_limit = + GetMaxTemporalLayerVendorLimit(vendor, codec, workarounds); + if (max_temporal_layer_vendor_limit == 1) { + return 1; + } + + ComMFTransform encoder; + ComCodecAPI codec_api; + HRESULT hr = activate->ActivateObject(IID_PPV_ARGS(&encoder)); + if (FAILED(hr)) { + // Log to VLOG since errors are expected as part of GetSupportedProfiles(). + DVLOG(2) << "Failed to activate encoder: " << PrintHr(hr); + return 1; + } + + hr = encoder.As(&codec_api); + if (FAILED(hr)) { + // Log to VLOG since errors are expected as part of GetSupportedProfiles(). + DVLOG(2) << "Failed to get encoder as CodecAPI: " << PrintHr(hr); + return 1; + } + + if (codec_api->IsSupported(&CODECAPI_AVEncVideoTemporalLayerCount) != S_OK) { + return 1; + } + + base::win::ScopedVariant min, max, step; + if (FAILED(codec_api->GetParameterRange( + &CODECAPI_AVEncVideoTemporalLayerCount, min.AsInput(), max.AsInput(), + step.AsInput()))) { + return 1; + } + + // Temporal encoding is only considered supported if the driver reports at + // least a span of 1-3 temporal layers. + if (V_UI4(min.ptr()) > 1u || V_UI4(max.ptr()) < 3u) { + return 1; + } + return max_temporal_layer_vendor_limit; +} + +bool IsIntelHybridAV1Encoder(IMFActivate* activate) { + DCHECK(activate); + if (GetDriverVendor(activate) == DriverVendor::kIntel) { + // Get the CLSID GUID of the HMFT. + GUID mft_guid = {0}; + activate->GetGUID(MFT_TRANSFORM_CLSID_Attribute, &mft_guid); + if (mft_guid == kIntelAV1HybridEncoderCLSID) { + return true; + } + } + return false; +} + +using MFTEnum2Type = decltype(&MFTEnum2); +MFTEnum2Type GetMFTEnum2Function() { + static const MFTEnum2Type kMFTEnum2Func = []() { + auto mf_dll = base::LoadSystemLibrary(L"mfplat.dll"); + return mf_dll ? reinterpret_cast<MFTEnum2Type>( + base::GetFunctionPointerFromNativeLibrary(mf_dll, + "MFTEnum2")) + : nullptr; + }(); + return kMFTEnum2Func; +} + +// If MFTEnum2 is unavailable, this uses MFTEnumEx and doesn't fill any +// adapter information if there are more than one adapters. +std::vector<Microsoft::WRL::ComPtr<IMFActivate>> +EnumerateHardwareEncodersLegacy(VideoCodec codec) { + std::vector<Microsoft::WRL::ComPtr<IMFActivate>> encoders; + + uint32_t flags = MFT_ENUM_FLAG_HARDWARE | MFT_ENUM_FLAG_SORTANDFILTER; + MFT_REGISTER_TYPE_INFO input_info; + input_info.guidMajorType = MFMediaType_Video; + input_info.guidSubtype = MFVideoFormat_NV12; + MFT_REGISTER_TYPE_INFO output_info; + output_info.guidMajorType = MFMediaType_Video; + output_info.guidSubtype = VideoCodecToMFSubtype(codec); + + Microsoft::WRL::ComPtr<IDXGIFactory1> factory; + auto hr = CreateDXGIFactory1(IID_PPV_ARGS(&factory)); + if (FAILED(hr)) { + DVLOG(2) << "Failed to create DXGI Factory"; + return encoders; + } + + LUID single_adapter_luid{0, 0}; + int num_adapters = 0; + + Microsoft::WRL::ComPtr<IDXGIAdapter> temp_adapter; + for (UINT adapter_idx = 0; + SUCCEEDED(factory->EnumAdapters(adapter_idx, &temp_adapter)); + adapter_idx++) { + ++num_adapters; + + DXGI_ADAPTER_DESC desc; + hr = temp_adapter->GetDesc(&desc); + if (FAILED(hr)) { + continue; + } + + if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c) { + // Skip MS software adapters. + --num_adapters; + } else { + single_adapter_luid = desc.AdapterLuid; + } + } + + IMFActivate** pp_activates = nullptr; + uint32_t count = 0; + hr = MFTEnumEx(MFT_CATEGORY_VIDEO_ENCODER, flags, &input_info, &output_info, + &pp_activates, &count); + + if (FAILED(hr)) { + // Log to VLOG since errors are expected as part of + // GetSupportedProfiles(). + DVLOG(2) << "Failed to enumerate hardware encoders for " + << GetCodecName(codec) << " : " << PrintHr(hr); + return encoders; + } + + for (UINT32 i = 0; i < count; i++) { + if (codec == VideoCodec::kAV1 && IsIntelHybridAV1Encoder(pp_activates[i])) { + continue; + } + + // We can still infer the MFT's adapter LUID if there's only one adapter + // in the system. + if (num_adapters == 1) { + pp_activates[i]->SetBlob(MFT_ENUM_ADAPTER_LUID, + reinterpret_cast<BYTE*>(&single_adapter_luid), + sizeof(LUID)); + } + encoders.push_back(pp_activates[i]); + } + + if (pp_activates) { + CoTaskMemFree(pp_activates); + } + + return encoders; +} + +std::vector<Microsoft::WRL::ComPtr<IMFActivate>> EnumerateHardwareEncoders( + VideoCodec codec) { + std::vector<Microsoft::WRL::ComPtr<IMFActivate>> encoders; + + if (!InitializeMediaFoundation()) { + return encoders; + } +#if defined(ARCH_CPU_ARM64) + // TODO (crbug.com/1509117): Temporarily disable video encoding on arm64 + // until we figure out what OS reports all codecs as supported. + if (!base::FeatureList::IsEnabled(kMediaFoundationAcceleratedEncodeOnArm64)) { + return encoders; + } +#endif + + MFTEnum2Type mftenum2_func = GetMFTEnum2Function(); + if (!mftenum2_func) { + return EnumerateHardwareEncodersLegacy(codec); + } + + uint32_t flags = MFT_ENUM_FLAG_HARDWARE | MFT_ENUM_FLAG_SORTANDFILTER; + MFT_REGISTER_TYPE_INFO input_info; + input_info.guidMajorType = MFMediaType_Video; + input_info.guidSubtype = MFVideoFormat_NV12; + MFT_REGISTER_TYPE_INFO output_info; + output_info.guidMajorType = MFMediaType_Video; + output_info.guidSubtype = VideoCodecToMFSubtype(codec); + + Microsoft::WRL::ComPtr<IDXGIFactory1> factory; + auto hr = CreateDXGIFactory1(IID_PPV_ARGS(&factory)); + if (FAILED(hr)) { + DVLOG(2) << "Failed to create DXGI Factory"; + return encoders; + } + + Microsoft::WRL::ComPtr<IDXGIAdapter> temp_adapter; + for (UINT adapter_idx = 0; + SUCCEEDED(factory->EnumAdapters(adapter_idx, &temp_adapter)); + adapter_idx++) { + DXGI_ADAPTER_DESC desc; + hr = temp_adapter->GetDesc(&desc); + if (FAILED(hr)) { + DVLOG(2) << "Failed to get description for adapter " << adapter_idx; + continue; + } + + Microsoft::WRL::ComPtr<IMFAttributes> attributes; + hr = MFCreateAttributes(&attributes, 1); + if (FAILED(hr = attributes->SetBlob( + MFT_ENUM_ADAPTER_LUID, + reinterpret_cast<BYTE*>(&desc.AdapterLuid), sizeof(LUID)))) { + continue; + } + + IMFActivate** pp_activates = nullptr; + uint32_t count = 0; + // MFTEnum2() function call. + hr = mftenum2_func(MFT_CATEGORY_VIDEO_ENCODER, flags, &input_info, + &output_info, attributes.Get(), &pp_activates, &count); + + if (FAILED(hr)) { + // Log to VLOG since errors are expected as part of + // GetSupportedProfiles(). + DVLOG(2) << "Failed to enumerate hardware encoders for " + << GetCodecName(codec) << " at a adapter #" << adapter_idx + << " : " << PrintHr(hr); + continue; + } + + for (UINT32 i = 0; i < count; i++) { + if (codec == VideoCodec::kAV1 && + IsIntelHybridAV1Encoder(pp_activates[i])) { + continue; + } + // It's safe to ignore return value here. + // if SetBlob fails, the IMFActivate won't have a valid adapter LUID + // which will fail the check for preferred adapter LUID, so the + // MFDXGIDeviceManager will not be set for MFT, which is a safe option. + pp_activates[i]->SetBlob(MFT_ENUM_ADAPTER_LUID, + reinterpret_cast<BYTE*>(&desc.AdapterLuid), + sizeof(LUID)); + encoders.push_back(pp_activates[i]); + } + + if (pp_activates) { + CoTaskMemFree(pp_activates); + } + } + + return encoders; +} + +uint32_t CalculateMaxFramerateFromMacroBlocksPerSecond( + const FramerateAndResolution& max_framerate_and_resolution, + uint32_t max_macroblocks_per_second) { + constexpr uint64_t kMacroBlockWidth = 16u; + constexpr uint64_t kMacroBlockHeight = 16u; + + uint64_t max_possible_framerate = std::floor( + (max_macroblocks_per_second * kMacroBlockWidth * kMacroBlockHeight) / + max_framerate_and_resolution.resolution.Area64()); + + return std::clamp(static_cast<uint32_t>(max_possible_framerate), 1u, + max_framerate_and_resolution.frame_rate); +} + +std::vector<FramerateAndResolution> GetMaxFramerateAndResolutionsFromMFT( + VideoCodec codec, + IMFTransform* encoder, + bool allow_set_output_type) { + DCHECK(encoder); + std::vector<FramerateAndResolution> framerate_and_resolutions; + if (allow_set_output_type) { + Microsoft::WRL::ComPtr<IMFMediaType> media_type; + + RETURN_ON_HR_FAILURE(MFCreateMediaType(&media_type), + "Create media type failed", framerate_and_resolutions); + RETURN_ON_HR_FAILURE( + media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + "Set major type failed", framerate_and_resolutions); + RETURN_ON_HR_FAILURE( + media_type->SetGUID(MF_MT_SUBTYPE, VideoCodecToMFSubtype(codec)), + "Set guid for sub type failed", framerate_and_resolutions); + RETURN_ON_HR_FAILURE( + MFSetAttributeSize( + media_type.Get(), MF_MT_FRAME_SIZE, + kDefaultMaxFramerateAndResolution.resolution.width(), + kDefaultMaxFramerateAndResolution.resolution.height()), + "Set attribute size failed", framerate_and_resolutions); + // Frame rate,30, is dummy value for pass through. + RETURN_ON_HR_FAILURE( + MFSetAttributeRatio( + media_type.Get(), MF_MT_FRAME_RATE, + /*unNumerator=*/kDefaultMaxFramerateAndResolution.frame_rate, + /*unDenominator=*/1), + "Set attribute ratio failed", framerate_and_resolutions); + RETURN_ON_HR_FAILURE(media_type->SetUINT32(MF_MT_AVG_BITRATE, 9000000), + "Set avg bitrate failed", framerate_and_resolutions); + RETURN_ON_HR_FAILURE(media_type->SetUINT32(MF_MT_INTERLACE_MODE, + MFVideoInterlace_Progressive), + "Set interlace mode failed", + framerate_and_resolutions); + + if (codec != VideoCodec::kVP9) { + UINT32 max_level; + switch (codec) { + case VideoCodec::kH264: + max_level = eAVEncH264VLevel5_2; + break; + case VideoCodec::kAV1: + max_level = eAVEncAV1VLevel6_3; + break; + case VideoCodec::kHEVC: + max_level = eAVEncH265VLevel6_2; + break; + default: + NOTREACHED(); + } + RETURN_ON_HR_FAILURE(media_type->SetUINT32(MF_MT_VIDEO_LEVEL, max_level), + "Set video level failed", framerate_and_resolutions); + } + + RETURN_ON_HR_FAILURE( + encoder->SetOutputType(/*stream_id=*/0, media_type.Get(), 0), + "Set output type failed", framerate_and_resolutions); + } + + Microsoft::WRL::ComPtr<IMFAttributes> attributes; + RETURN_ON_HR_FAILURE(encoder->GetAttributes(&attributes), + "Get attributes failed", framerate_and_resolutions); + uint32_t max_macroblocks_per_second = + MFGetAttributeUINT32(attributes.Get(), MF_VIDEO_MAX_MB_PER_SEC, 0); + max_macroblocks_per_second &= + 0x0fffffff; // Only lower 28 bits are supported. + + std::vector<FramerateAndResolution> max_framerate_and_resolutions; + if (codec == VideoCodec::kH264) { + max_framerate_and_resolutions.push_back(kLegacy2KMaxFramerateAndResolution); + max_framerate_and_resolutions.push_back(kLegacy4KMaxFramerateAndResolution); + } else { + max_framerate_and_resolutions.push_back(kModern2KMaxFramerateAndResolution); + max_framerate_and_resolutions.push_back(kModern4KMaxFramerateAndResolution); + max_framerate_and_resolutions.push_back(kModern8KMaxFramerateAndResolution); + } + + for (auto& max_framerate_and_resolution : max_framerate_and_resolutions) { + FramerateAndResolution framerate_and_resolution = { + CalculateMaxFramerateFromMacroBlocksPerSecond( + max_framerate_and_resolution, max_macroblocks_per_second), + max_framerate_and_resolution.resolution}; + + // Only if the calculated framerate >= the default framerate, we then + // consider this resolution & framerate combination is supported. + if (framerate_and_resolution.frame_rate >= + (kDefaultFrameRateNumerator / kDefaultFrameRateDenominator)) { + framerate_and_resolutions.push_back(framerate_and_resolution); + } + } + + // If the received value of `max_macroblocks_per_second` equals to zero, + // assign a default value here. + if (framerate_and_resolutions.empty()) { + framerate_and_resolutions.push_back(kDefaultMaxFramerateAndResolution); + } + + return framerate_and_resolutions; +} + +// Ideally, we should query the API to get the minimum resolution of each codec +// under each vendor. However, since there is no such API available, based on +// the actual results, although the minimum resolutions of different codecs for +// each vendor vary, but the results always remain consistent among different +// GPU models. Therefore, we can just hardcode these values within the function. +gfx::Size GetMinResolution(VideoCodec codec, DriverVendor vendor) { + switch (codec) { + case VideoCodec::kH264: + switch (vendor) { + case DriverVendor::kAMD: + // Below result based on: AMD Radeon(TM) Graphics (Ryzen 7 Pro 4750U), + // AMD Radeon(TM) Graphics (Ryzen 9 9950X), AMD Radeon(TM) RX 6600. + return gfx::Size(128, 128); + case DriverVendor::kIntel: + // Below result based on: Intel UHD Graphics 750, Intel Arc(TM) A380, + // Intel Arc(TM) Graphic (Ultra5 125H), Intel(R) Iris(R) Xe MAX + // Graphics. + return gfx::Size(18, 18); + case DriverVendor::kNvidia: + // Below result based on: NVIDIA RTX 3050, NVIDIA RTX 3070, NVIDIA RTX + // 4080. + return gfx::Size(146, 50); + case DriverVendor::kQualcomm: + // Below result based on: Qualcomm(R) Adreno(TM) 690, Qualcomm(R) + // Adreno(TM) X1-85. + return gfx::Size(96, 96); + case DriverVendor::kOther: + return kDefaultMinResolution; + } + case VideoCodec::kHEVC: + switch (vendor) { + case DriverVendor::kAMD: + // Below result based on: AMD Radeon(TM) Graphics (Ryzen 7 Pro 4750U), + // AMD Radeon(TM) Graphics (Ryzen 9 9950X), AMD Radeon(TM) RX 6600. + return gfx::Size(130, 128); + case DriverVendor::kIntel: + // Below result based on: Intel UHD Graphics 750, Intel Arc(TM) A380, + // Intel Arc(TM) Graphic (Ultra5 125H), Intel(R) Iris(R) Xe MAX + // Graphics. + return gfx::Size(66, 114); + case DriverVendor::kNvidia: + // Below result based on: NVIDIA RTX 3050, NVIDIA RTX 3070, NVIDIA RTX + // 4080. + return gfx::Size(130, 34); + case DriverVendor::kQualcomm: + // Below result based on: Qualcomm(R) Adreno(TM) 690, Qualcomm(R) + // Adreno(TM) X1-85. + return gfx::Size(96, 96); + case DriverVendor::kOther: + return kDefaultMinResolution; + } + case VideoCodec::kVP9: + switch (vendor) { + case DriverVendor::kAMD: + // Below result based on: AMD Radeon(TM) Graphics (Ryzen 9 9950X). + return gfx::Size(66, 66); + case DriverVendor::kIntel: + // Below result based on: Intel UHD Graphics 750, Intel Arc(TM) A380, + // Intel Arc(TM) Graphic (Ultra5 125H), Intel(R) Iris(R) Xe MAX + // Graphics. + // + // NOTE: Intel UHD Graphics 750, Intel Arc(TM) A380, Intel(R) Iris(R) + // Xe MAX Graphics actually only requires >= 66x66, but Intel Arc(TM) + // Graphic (Ultra5 125H) requires >= 66x120. + return gfx::Size(66, 120); + case DriverVendor::kNvidia: + // Below result based on: NVIDIA RTX 4080. + return gfx::Size(66, 66); + // As of the testing date, no Qualcomm hardware supports VP9 encoding. + case DriverVendor::kQualcomm: + case DriverVendor::kOther: + return kDefaultMinResolution; + } + case VideoCodec::kAV1: + switch (vendor) { + case DriverVendor::kAMD: + // Below result based on: AMD Radeon(TM) Graphics (Ryzen 9 9950X). + return gfx::Size(114, 82); + case DriverVendor::kIntel: + // Below result based on: Intel Arc(TM) A380, Intel Arc(TM) Graphic + // (Ultra5 125H). + return gfx::Size(114, 82); + case DriverVendor::kNvidia: + // Below result based on: NVIDIA RTX 4080. + return gfx::Size(130, 66); + case DriverVendor::kQualcomm: + // Below result based on: Qualcomm(R) Adreno(TM) X1-85. + return gfx::Size(256, 128); + case DriverVendor::kOther: + return kDefaultMinResolution; + } + default: + NOTREACHED(); + } +} + +size_t GetMFTGuidHash(IMFActivate* activate) { + DCHECK(activate); + + GUID mft_guid = {0}; + activate->GetGUID(MFT_TRANSFORM_CLSID_Attribute, &mft_guid); + return base::FastHash( + base::as_byte_span(base::win::WStringFromGUID(mft_guid))); +} + +} // namespace media
diff --git a/media/gpu/windows/mf_video_encoder_util.h b/media/gpu/windows/mf_video_encoder_util.h new file mode 100644 index 0000000..9fa752b0 --- /dev/null +++ b/media/gpu/windows/mf_video_encoder_util.h
@@ -0,0 +1,171 @@ +// 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 MEDIA_GPU_WINDOWS_MF_VIDEO_ENCODER_UTIL_H_ +#define MEDIA_GPU_WINDOWS_MF_VIDEO_ENCODER_UTIL_H_ + +#include <codecapi.h> +#include <mfapi.h> +#include <mfidl.h> +#include <stdint.h> +#include <wrl/client.h> + +#include <vector> + +#include "base/containers/fixed_flat_set.h" +#include "gpu/config/gpu_driver_bug_workarounds.h" +#include "media/base/video_codecs.h" +#include "media/base/video_types.h" +#include "media/gpu/buildflags.h" +#include "media/gpu/windows/d3d_com_defs.h" +#include "media/media_buildflags.h" +#include "ui/gfx/geometry/size.h" + +namespace media { + +struct FramerateAndResolution { + uint32_t frame_rate; + gfx::Size resolution; +}; + +enum class DriverVendor { kOther, kNvidia, kIntel, kAMD, kQualcomm }; + +static constexpr size_t kDefaultFrameRateNumerator = 30; +static constexpr size_t kDefaultFrameRateDenominator = 1; + +// The default supported max framerate and resolution. +static constexpr FramerateAndResolution kDefaultMaxFramerateAndResolution = { + kDefaultFrameRateNumerator / kDefaultFrameRateDenominator, + gfx::Size(1920, 1080)}; + +// The default supported min resolution. +static constexpr gfx::Size kDefaultMinResolution(32, 32); + +// For H.264, some NVIDIA GPUs may report `MF_VIDEO_MAX_MB_PER_SEC` value equals +// to `6799902`, resulting chromium think 8K & 30fps is supported, and some +// Intel GPUs only support level 5.2. Since most devices only support up to 4K, +// so we set level 5.2 as the max allowed level here to limit max resolution and +// framerate combination can only go up to 2K & 172fps, or 4K & 64fps. +static constexpr FramerateAndResolution kLegacy2KMaxFramerateAndResolution = { + 172, gfx::Size(1920, 1080)}; +static constexpr FramerateAndResolution kLegacy4KMaxFramerateAndResolution = { + 64, gfx::Size(3840, 2160)}; + +// For H.265/AV1, some NVIDIA GPUs may report `MF_VIDEO_MAX_MB_PER_SEC` value +// equals to `7255273`, resulting chromium think 2K & 880fps is supported. Since +// the max level of H.265/AV1 (6.2/6.3) do not allow framerate >= 300fps, so we +// set level 6.2/6.3 as the max allowed level here and limit max resolution and +// framerate combination can only go up to 2K/4K & 300fps, 8K & 128fps. +static constexpr FramerateAndResolution kModern2KMaxFramerateAndResolution = { + 300, gfx::Size(1920, 1080)}; +static constexpr FramerateAndResolution kModern4KMaxFramerateAndResolution = { + 300, gfx::Size(3840, 2160)}; +static constexpr FramerateAndResolution kModern8KMaxFramerateAndResolution = { + 128, gfx::Size(7680, 4320)}; + +static constexpr CLSID kIntelAV1HybridEncoderCLSID = { + 0x62c053ce, + 0x5357, + 0x4794, + {0x8c, 0x5a, 0xfb, 0xef, 0xfe, 0xff, 0xb8, 0x2d}}; + +static constexpr auto kSupportedPixelFormats = + base::MakeFixedFlatSet<VideoPixelFormat>( + {PIXEL_FORMAT_I420, PIXEL_FORMAT_NV12}); +static constexpr auto kSupportedPixelFormatsD3DVideoProcessing = + base::MakeFixedFlatSet<VideoPixelFormat>( + {PIXEL_FORMAT_I420, PIXEL_FORMAT_NV12, PIXEL_FORMAT_YV12, + PIXEL_FORMAT_NV21, PIXEL_FORMAT_ARGB, PIXEL_FORMAT_XRGB, + PIXEL_FORMAT_ABGR, PIXEL_FORMAT_XBGR}); + +static constexpr int kH26xMaxQp = 51; +static constexpr uint64_t kVP9MaxQIndex = 255; +static constexpr uint64_t kAV1MaxQIndex = 255; + +// Quantizer parameter used in libvpx vp9 rate control, whose range is 0-63. +// These are based on WebRTC's defaults, cite from +// third_party/webrtc/media/engine/webrtc_video_engine.h. +static constexpr uint8_t kVP9MinQuantizer = 2; +static constexpr uint8_t kVP9MaxQuantizer = 56; +// Default value from +// //third_party/webrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc, +static constexpr uint8_t kAV1MinQuantizer = 10; +// //third_party/webrtc/media/engine/webrtc_video_engine.h. +static constexpr uint8_t kAV1MaxQuantizer = 56; + +// The range for the quantization parameter is determined by examining the +// estimated QP values from the SW bitrate controller in various encoding +// scenarios. +static constexpr uint8_t kH264MinQuantizer = 16; +static constexpr uint8_t kH264MaxQuantizer = 51; + +#if BUILDFLAG(ENABLE_PLATFORM_HEVC) +// For H.265, ideally we may reuse Min/MaxQp for H.264 from +// media/gpu/vaapi/h264_vaapi_video_encoder_delegate.cc. However +// test shows most of the drivers require a min QP of 10 to reach +// target bitrate especially at low resolution. +static constexpr uint8_t kH265MinQuantizer = 10; +static constexpr uint8_t kH265MaxQuantizer = 42; +#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC) + +// Converts AV1/VP9 qindex (0-255) to the quantizer parameter input in MF +// AVEncVideoEncodeQP. +uint8_t QindextoAVEncQP(VideoCodec codec, uint8_t q_index); + +// Converts AV1/VP9 AVEncVideoEncodeQP values to qindex (0-255) range. +uint8_t AVEncQPtoQindex(VideoCodec codec, uint8_t avenc_qp); + +// Returns true if |qp| is a valid quantizer parameter for |codec|. +bool IsValidQp(VideoCodec codec, uint64_t qp); + +// Returns the maximum quantizer value for |codec|. +uint8_t GetMaxQuantizer(VideoCodec codec); + +// Converts VideoCodecProfile to eAVEncH264VProfile. +eAVEncH264VProfile GetH264VProfile(VideoCodecProfile profile, + bool is_constrained_h264); + +// Converts VideoCodecProfile to eAVEncVP9VProfile. +eAVEncVP9VProfile GetVP9VProfile(VideoCodecProfile profile); + +// Converts VideoCodecProfile to eAVEncAV1VProfile. +eAVEncH265VProfile GetHEVCProfile(VideoCodecProfile profile); + +// Returns the driver vendor of the given |encoder|. +DriverVendor GetDriverVendor(IMFActivate* encoder); + +// Get the maximum number of temporal layers supported by the given |encoder| +// from |vendor|, taking into account |workarounds|. +int GetMaxTemporalLayerVendorLimit( + DriverVendor vendor, + VideoCodec codec, + const gpu::GpuDriverBugWorkarounds& workarounds); + +// Enumeration of HMFT without specifying LUID. +std::vector<Microsoft::WRL::ComPtr<IMFActivate>> +EnumerateHardwareEncodersLegacy(VideoCodec codec); + +// Adapter-based enumeration of HMFT. The adapter with lower index is enumerated +// first. +std::vector<Microsoft::WRL::ComPtr<IMFActivate>> EnumerateHardwareEncoders( + VideoCodec codec); + +// Get the maximum supported framerate and resolution combinations for the given +// codec and HMFT. If |allow_set_output_type| is true, it will try to set the +// output type to get the maximum supported framerate and resolution; otherwise, +// we merely query the maximum supported macroblocks per second for calculation. +std::vector<FramerateAndResolution> GetMaxFramerateAndResolutionsFromMFT( + VideoCodec codec, + IMFTransform* encoder, + bool allow_set_output_type); + +// Get the minimum supported encoding resolution for the given codec and vendor. +gfx::Size GetMinResolution(VideoCodec codec, DriverVendor vendor); + +// Get the hash of the CLSID of the IMFActivate instance. +size_t GetMFTGuidHash(IMFActivate* activate); + +} // namespace media + +#endif // MEDIA_GPU_WINDOWS_MF_VIDEO_ENCODER_UTIL_H_
diff --git a/media/mojo/mojom/speech_recognition.mojom b/media/mojo/mojom/speech_recognition.mojom index ba38326..9839113 100644 --- a/media/mojo/mojom/speech_recognition.mojom +++ b/media/mojo/mojom/speech_recognition.mojom
@@ -230,15 +230,6 @@ OnFullscreenToggled@1(); }; -// Static metadata about a remote speech surface. Used by the speech service -// client in Ash. -struct SpeechRecognitionSurfaceMetadata { - // A unique identifier for the "session" (i.e. tab) of the surface. Is used to - // hide the caption bubble for all streams in a tab if the bubble is closed - // once. - mojo_base.mojom.UnguessableToken session_id; -}; - // This interface between the speech recognition client and the browser. // The remote lives in the renderer process and the receiver lives in the // browser process. Not necessary for browser-side features (e.g. CrOS system @@ -248,16 +239,8 @@ BindSpeechRecognitionBrowserObserver@0( pending_remote<SpeechRecognitionBrowserObserver> observer); - // Requests that a remote speech recognition client be instantiated and bound - // in the Ash browser process. The instantiated client should use the surface - // and surface client bindings to perform tasks (such as refocusing) that - // require coordination with the current lacros tab. [MinVersion=1] - BindRecognizerToRemoteClient@1( - pending_receiver<SpeechRecognitionRecognizerClient> client, - pending_receiver<SpeechRecognitionSurfaceClient> surface_client, - pending_remote<SpeechRecognitionSurface> surface, - SpeechRecognitionSurfaceMetadata metadata); + REMOVED_1@1(); // Similar to BindSpeechRecognitionBrowserObserver, however binds Browser // observers that listen to events specific to BabelOrca rather than
diff --git a/mojo/public/cpp/base/shared_memory_version.cc b/mojo/public/cpp/base/shared_memory_version.cc index 568cf34c..8823d3d 100644 --- a/mojo/public/cpp/base/shared_memory_version.cc +++ b/mojo/public/cpp/base/shared_memory_version.cc
@@ -45,7 +45,7 @@ // Relaxed memory order because no other memory operation depends on the // version. - return mapped_region_->WritableRef().load(std::memory_order_relaxed); + return mapped_region_->ReadOnlyRef().load(std::memory_order_relaxed); } void SharedMemoryVersionController::Increment() {
diff --git a/mojo/public/cpp/base/shared_memory_version.h b/mojo/public/cpp/base/shared_memory_version.h index 64783bc..fe3cb3ef 100644 --- a/mojo/public/cpp/base/shared_memory_version.h +++ b/mojo/public/cpp/base/shared_memory_version.h
@@ -120,7 +120,7 @@ void SetVersion(VersionType version); private: - const std::optional<base::AtomicSharedMemory<VersionType>> mapped_region_; + std::optional<base::AtomicSharedMemory<VersionType>> mapped_region_; }; // Used to keep track of a remote version number and compare it to a
diff --git a/net/dns/host_resolver_manager_service_endpoint_request_impl.cc b/net/dns/host_resolver_manager_service_endpoint_request_impl.cc index 486ec08..32ad45f 100644 --- a/net/dns/host_resolver_manager_service_endpoint_request_impl.cc +++ b/net/dns/host_resolver_manager_service_endpoint_request_impl.cc
@@ -203,7 +203,6 @@ } CHECK(job_); - CHECK(job_.value()->dns_task_results_manager()); CHECK(delegate_); delegate_->OnServiceEndpointsUpdated(); // Do not add code below. `this` may be deleted at this point.
diff --git a/services/media_session/audio_focus_manager.cc b/services/media_session/audio_focus_manager.cc index c277cfd..3fd8540 100644 --- a/services/media_session/audio_focus_manager.cc +++ b/services/media_session/audio_focus_manager.cc
@@ -282,6 +282,26 @@ } } +void AudioFocusManager::StartDuckingAllAudio( + const std::optional<base::UnguessableToken>& exempted_request_id) { + ducking_all_audio_ = true; + ducking_exempted_request_id_ = exempted_request_id; + EnforceAudioFocus(); +} + +void AudioFocusManager::StopDuckingAllAudio() { + ducking_all_audio_ = false; + EnforceAudioFocus(); +} + +void AudioFocusManager::FlushForTesting(FlushForTestingCallback callback) { + for (auto& row : audio_focus_stack_) { + row->FlushForTesting(); // IN-TEST + } + observers_.FlushForTesting(); // IN-TEST + std::move(callback).Run(); +} + void AudioFocusManager::CreateActiveMediaController( mojo::PendingReceiver<mojom::MediaController> receiver) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -474,6 +494,11 @@ bool AudioFocusManager::ShouldSessionBeDucked( const AudioFocusRequest* session, const EnforcementState& state) const { + if (ducking_all_audio_ && (!ducking_exempted_request_id_.has_value() || + *ducking_exempted_request_id_ != session->id())) { + return true; + } + switch (enforcement_mode_) { case mojom::EnforcementMode::kSingleSession: case mojom::EnforcementMode::kSingleGroup:
diff --git a/services/media_session/audio_focus_manager.h b/services/media_session/audio_focus_manager.h index 1dc365f..67449d06 100644 --- a/services/media_session/audio_focus_manager.h +++ b/services/media_session/audio_focus_manager.h
@@ -79,6 +79,10 @@ void GetSourceFocusRequests(const base::UnguessableToken& source_id, GetFocusRequestsCallback callback) override; void RequestIdReleased(const base::UnguessableToken& request_id) override; + void StartDuckingAllAudio(const std::optional<base::UnguessableToken>& + exempted_request_id) override; + void StopDuckingAllAudio() override; + void FlushForTesting(FlushForTestingCallback callback) override; // mojom::AudioFocusManagerDebug. void GetDebugInfoForRequest(const RequestId& request_id, @@ -187,6 +191,10 @@ mojom::EnforcementMode enforcement_mode_; + bool ducking_all_audio_ = false; + + std::optional<base::UnguessableToken> ducking_exempted_request_id_; + // Adding observers should happen on the same thread that the service is // running on. THREAD_CHECKER(thread_checker_);
diff --git a/services/media_session/audio_focus_manager_unittest.cc b/services/media_session/audio_focus_manager_unittest.cc index 988ec81..78910c2 100644 --- a/services/media_session/audio_focus_manager_unittest.cc +++ b/services/media_session/audio_focus_manager_unittest.cc
@@ -132,12 +132,6 @@ test::MockMediaSession* session) { mojom::MediaSessionInfo::SessionState state = session->GetState(); - if (!IsEnforcementEnabled()) { - // If audio focus enforcement is disabled then we should never see ducking - // in the tests. - EXPECT_NE(mojom::MediaSessionInfo::SessionState::kDucking, state); - } - return state; } @@ -234,6 +228,17 @@ ->identity(); } + void StartDuckingAllAudio( + const std::optional<base::UnguessableToken>& exempted_request_id) { + GetService()->StartDuckingAllAudio(exempted_request_id); + FlushForTesting(); + } + + void StopDuckingAllAudio() { + GetService()->StopDuckingAllAudio(); + FlushForTesting(); + } + void FlushForTesting() { audio_focus_remote_.FlushForTesting(); } private: @@ -1742,4 +1747,80 @@ EXPECT_TRUE(identity_3_requests.empty()); } +TEST_P(AudioFocusManagerTest, StartDuckingAllAudio_NoExemption) { + test::MockMediaSession media_session_1; + test::MockMediaSession media_session_2; + + base::UnguessableToken group_id = base::UnguessableToken::Create(); + + // Request audio focus for two media sessions. + ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(), + &media_session_1, + mojom::AudioFocusType::kGain, group_id)); + ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(), + &media_session_2, + mojom::AudioFocusType::kGain, group_id)); + EXPECT_EQ(IsGroupingEnabled() + ? mojom::MediaSessionInfo::SessionState::kActive + : mojom::MediaSessionInfo::SessionState::kSuspended, + GetState(&media_session_1)); + EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive, + GetState(&media_session_2)); + + // A call to `StartDuckingAllAudio()` with no exempted request ID should duck + // all sessions. + StartDuckingAllAudio(std::nullopt); + EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kDucking, + GetState(&media_session_1)); + EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kDucking, + GetState(&media_session_2)); + + // Once ducking all audio is stopped, the sessions should no longer be ducked. + StopDuckingAllAudio(); + EXPECT_EQ(IsGroupingEnabled() + ? mojom::MediaSessionInfo::SessionState::kActive + : mojom::MediaSessionInfo::SessionState::kSuspended, + GetState(&media_session_1)); + EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive, + GetState(&media_session_2)); +} + +TEST_P(AudioFocusManagerTest, StartDuckingAllAudio_WithExemption) { + test::MockMediaSession media_session_1; + test::MockMediaSession media_session_2; + + base::UnguessableToken group_id = base::UnguessableToken::Create(); + base::UnguessableToken id_2 = base::UnguessableToken::Create(); + + // Request audio focus for two media sessions. + ASSERT_TRUE(RequestGroupedAudioFocus(base::UnguessableToken::Create(), + &media_session_1, + mojom::AudioFocusType::kGain, group_id)); + ASSERT_TRUE(RequestGroupedAudioFocus(id_2, &media_session_2, + mojom::AudioFocusType::kGain, group_id)); + EXPECT_EQ(IsGroupingEnabled() + ? mojom::MediaSessionInfo::SessionState::kActive + : mojom::MediaSessionInfo::SessionState::kSuspended, + GetState(&media_session_1)); + EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive, + GetState(&media_session_2)); + + // A call to `StartDuckingAllAudio()` with an exempted request ID should duck + // all sessions except the exempted one. + StartDuckingAllAudio(id_2); + EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kDucking, + GetState(&media_session_1)); + EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive, + GetState(&media_session_2)); + + // Once ducking all audio is stopped, the sessions should no longer be ducked. + StopDuckingAllAudio(); + EXPECT_EQ(IsGroupingEnabled() + ? mojom::MediaSessionInfo::SessionState::kActive + : mojom::MediaSessionInfo::SessionState::kSuspended, + GetState(&media_session_1)); + EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive, + GetState(&media_session_2)); +} + } // namespace media_session
diff --git a/services/media_session/audio_focus_request.cc b/services/media_session/audio_focus_request.cc index 2d0f7b2..b26224d15 100644 --- a/services/media_session/audio_focus_request.cc +++ b/services/media_session/audio_focus_request.cc
@@ -175,6 +175,10 @@ base::Unretained(this), std::move(callback))); } +void AudioFocusRequest::FlushForTesting() { + session_.FlushForTesting(); // IN-TEST +} + void AudioFocusRequest::SetSessionInfo( mojom::MediaSessionInfoPtr session_info) { bool is_controllable_changed =
diff --git a/services/media_session/audio_focus_request.h b/services/media_session/audio_focus_request.h index 756fdf24..6bf9b3d 100644 --- a/services/media_session/audio_focus_request.h +++ b/services/media_session/audio_focus_request.h
@@ -85,6 +85,8 @@ const base::UnguessableToken& group_id() const { return group_id_; } const base::UnguessableToken& identity() const { return identity_; } + void FlushForTesting(); + private: void SetSessionInfo(mojom::MediaSessionInfoPtr session_info); void OnConnectionError();
diff --git a/services/media_session/public/cpp/test/mock_audio_focus_manager.h b/services/media_session/public/cpp/test/mock_audio_focus_manager.h index cf4d212..07f1e4a 100644 --- a/services/media_session/public/cpp/test/mock_audio_focus_manager.h +++ b/services/media_session/public/cpp/test/mock_audio_focus_manager.h
@@ -62,6 +62,12 @@ MOCK_METHOD(void, RequestIdReleased, (const base::UnguessableToken& request_id)); + MOCK_METHOD( + void, + StartDuckingAllAudio, + (const std::optional<base::UnguessableToken>& exempted_request_id)); + MOCK_METHOD(void, StopDuckingAllAudio, ()); + MOCK_METHOD(void, FlushForTesting, (FlushForTestingCallback)); private: mojo::Receiver<mojom::AudioFocusManager> receiver_{this};
diff --git a/services/media_session/public/mojom/audio_focus.mojom b/services/media_session/public/mojom/audio_focus.mojom index dfa07d80..599bcd5 100644 --- a/services/media_session/public/mojom/audio_focus.mojom +++ b/services/media_session/public/mojom/audio_focus.mojom
@@ -7,7 +7,7 @@ import "mojo/public/mojom/base/unguessable_token.mojom"; import "services/media_session/public/mojom/media_session.mojom"; -// Next MinVersion: 10 +// Next MinVersion: 11 // These are the different modes the AudioFocusManager can enforce audio focus. [Stable, Extensible] @@ -167,6 +167,21 @@ // |RequestGroupedAudioFocus()|. [MinVersion=8] RequestIdReleased@9( mojo_base.mojom.UnguessableToken request_id); + + // Begins ducking all audio focus sessions, except the one associated with the + // optionally provided request ID. This ignores the audio focus enforcement + // mode to enforce ducking regardless. If there is already an audio ducking + // request, this request will supersede the previous one. + [MinVersion=10] StartDuckingAllAudio@10( + mojo_base.mojom.UnguessableToken? exempted_request_id); + + // Stops ducking that was started via `StartDuckingAllAudio()`. Does nothing + // if audio is not currently being ducked. + [MinVersion=10] StopDuckingAllAudio@11(); + + // Flushes messages to observers and the audio focus stack. Calls the given + // callback once flushing has occurred. For testing only. + [MinVersion=10] FlushForTesting@12() => (); }; // Provides debug information about audio focus requests.
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index a2fbf1e..f402dc0 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -2648,8 +2648,6 @@ builder.SetCookieStore(std::move(cookie_store)); } - if (base::FeatureList::IsEnabled(features::kPrivateStateTokens) || - base::FeatureList::IsEnabled(features::kFledgePst)) { trust_token_store_ = std::make_unique<PendingTrustTokenStore>(); base::FilePath trust_token_path; @@ -2670,7 +2668,6 @@ std::make_unique<ExpiryInspectingRecordExpiryDelegate>( network_service()->trust_token_key_commitments()))); } - } std::unique_ptr<net::StaticHttpUserAgentSettings> user_agent_settings = std::make_unique<net::StaticHttpUserAgentSettings>(
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index 5bd14a1..54618b9 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -8132,9 +8132,6 @@ } TEST_F(NetworkContextTest, EnableTrustTokens) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8235,10 +8232,6 @@ } TEST_F(NetworkContextTest, EnableTrustTokensForFledge) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures({features::kFledgePst}, - {features::kPrivateStateTokens}); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8256,9 +8249,6 @@ } TEST_F(NetworkContextTestWithMockTime, EnableTrustTokensWithStoreOnDisk) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - base::ScopedTempDir dir; ASSERT_TRUE(dir.CreateUniqueTempDir()); base::FilePath database_name(FILE_PATH_LITERAL("my_token_store")); @@ -8321,20 +8311,6 @@ task_environment_.RunUntilIdle(); } -TEST_F(NetworkContextTest, DisableTrustTokens) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures( - {}, {features::kPrivateStateTokens, features::kFledgePst}); - - std::unique_ptr<NetworkContext> network_context = - CreateContextWithParams(CreateNetworkContextParamsForTesting()); - - // Allow the store time to initialize asynchronously. - task_environment_.RunUntilIdle(); - - EXPECT_FALSE(network_context->trust_token_store()); -} - class NetworkContextExpectBadMessageTest : public NetworkContextTest { public: NetworkContextExpectBadMessageTest() { @@ -8355,36 +8331,7 @@ }; TEST_F(NetworkContextExpectBadMessageTest, - FailsTrustTokenBearingRequestWhenTrustTokensIsDisabled) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures( - {}, {features::kPrivateStateTokens, features::kFledgePst}); - - std::unique_ptr<NetworkContext> network_context = - CreateContextWithParams(CreateNetworkContextParamsForTesting()); - - // Allow the store time to initialize asynchronously. - task_environment_.RunUntilIdle(); - - EXPECT_FALSE(network_context->trust_token_store()); - - ResourceRequest my_request; - my_request.request_initiator = - url::Origin::Create(GURL("https://initiator.com")); - my_request.trust_token_params = - OptionalTrustTokenParams(mojom::TrustTokenParams::New()); - - std::unique_ptr<TestURLLoaderClient> client = - FetchRequest(my_request, network_context.get()); - - AssertBadMessage(); -} - -TEST_F(NetworkContextExpectBadMessageTest, FailsTrustTokenRedemptionWhenForbidden) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8412,9 +8359,6 @@ TEST_F(NetworkContextExpectBadMessageTest, FailsTrustTokenSigningWhenForbidden) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8442,9 +8386,6 @@ TEST_F(NetworkContextExpectBadMessageTest, FailsTrustTokenIssuanceWhenForbidden) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8472,9 +8413,6 @@ TEST_F(NetworkContextTest, AttemptsTrustTokenBearingRequestWhenTrustTokensIsEnabled) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8498,9 +8436,6 @@ TEST_F(NetworkContextTest, RejectsTrustTokenBearingRequestWhenTrustTokensAreBlocked) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8528,9 +8463,6 @@ TEST_F(NetworkContextTest, RejectsTrustTokenBearingRequestWhenStorageIsBlocked) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8557,27 +8489,7 @@ mojom::TrustTokenOperationStatus::kUnauthorized); } -TEST_F(NetworkContextTest, - NoAvailableRedemptionRecordsWhenTrustTokensAreDisabled) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures( - /*enabled_features=*/{}, /*disabled_features=*/{ - features::kPrivateStateTokens, features::kFledgePst}); - - std::unique_ptr<NetworkContext> network_context = - CreateContextWithParams(CreateNetworkContextParamsForTesting()); - - base::test::TestFuture<base::flat_map< - url::Origin, std::vector<network::mojom::ToplevelRedemptionRecordPtr>>> - future; - network_context->GetPrivateStateTokenRedemptionRecords(future.GetCallback()); - EXPECT_THAT(future.Get(), testing::IsEmpty()); -} - TEST_F(NetworkContextTestWithMockTime, GetPrivateStateTokenRedemptionRecords) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); base::RunLoop run_loop; @@ -8676,33 +8588,7 @@ last_redemption_b); } -TEST_F(NetworkContextTest, NoAvailableTrustTokensWhenTrustTokensAreDisabled) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures( - {}, {features::kPrivateStateTokens, features::kFledgePst}); - - std::unique_ptr<NetworkContext> network_context = - CreateContextWithParams(CreateNetworkContextParamsForTesting()); - - // Allow the store time to initialize asynchronously. - base::RunLoop run_loop; - std::optional<std::vector<mojom::StoredTrustTokensForIssuerPtr>> trust_tokens; - network_context->GetStoredTrustTokenCounts(base::BindLambdaForTesting( - [&trust_tokens, - &run_loop](std::vector<mojom::StoredTrustTokensForIssuerPtr> tokens) { - trust_tokens = std::move(tokens); - run_loop.Quit(); - })); - run_loop.Run(); - - ASSERT_TRUE(trust_tokens.has_value()); - EXPECT_TRUE(trust_tokens->empty()); -} - TEST_F(NetworkContextTest, GetStoredTrustTokens) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8748,9 +8634,6 @@ } TEST_F(NetworkContextTest, GetStoredTrustTokensReentrant) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8791,36 +8674,7 @@ } TEST_F(NetworkContextTest, - DeleteStoredTrustTokensReportsErrorWhenFeatureIsDisabled) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures( - {}, {features::kPrivateStateTokens, features::kFledgePst}); - - std::unique_ptr<NetworkContext> network_context = - CreateContextWithParams(CreateNetworkContextParamsForTesting()); - - // Allow the store time to initialize asynchronously. - base::RunLoop run_loop; - std::optional<mojom::DeleteStoredTrustTokensStatus> actual_status; - network_context->DeleteStoredTrustTokens( - url::Origin::Create(GURL("https://example.com")), - base::BindLambdaForTesting( - [&](mojom::DeleteStoredTrustTokensStatus status) { - actual_status = status; - run_loop.Quit(); - })); - run_loop.Run(); - - EXPECT_THAT( - actual_status, - Optional(mojom::DeleteStoredTrustTokensStatus::kFailureFeatureDisabled)); -} - -TEST_F(NetworkContextTest, DeleteStoredTrustTokensReportsErrorWithInvalidOrigin) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8842,9 +8696,6 @@ } TEST_F(NetworkContextTest, DeleteStoredTrustTokens) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8897,9 +8748,6 @@ } TEST_F(NetworkContextTest, DeleteStoredTrustTokensReentrant) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -8964,9 +8812,6 @@ test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES); ASSERT_TRUE(test_server.Start()); - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting()); @@ -9043,9 +8888,6 @@ test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES); ASSERT_TRUE(test_server.Start()); - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kPrivateStateTokens); - std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateNetworkContextParamsForTesting());
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc index e4a9992..c6bbf5f 100644 --- a/services/network/public/cpp/features.cc +++ b/services/network/public/cpp/features.cc
@@ -178,48 +178,6 @@ "AttributionReportingCrossAppWeb", base::FEATURE_ENABLED_BY_DEFAULT); -// Enables preprocessing requests with the Private State Tokens API Fetch flags -// set, and handling their responses, according to the protocol. -// (See https://github.com/WICG/trust-token-api.) -BASE_FEATURE(kPrivateStateTokens, - "PrivateStateTokens", - base::FEATURE_ENABLED_BY_DEFAULT); - -// Secondary flag used by the FLEDGE ads experiment in the interim before -// PSTs are fully rolled out to stable. -BASE_FEATURE(kFledgePst, "TrustTokens", base::FEATURE_ENABLED_BY_DEFAULT); - -// Determines which Trust Tokens operations require the TrustTokens origin trial -// active in order to be used. This is runtime-configurable so that the Trust -// Tokens operations of issuance, redemption, and signing are compatible with -// both standard origin trials and third-party origin trials: -// -// - For standard origin trials, set kOnlyIssuanceRequiresOriginTrial. In Blink, -// all of the interface will be enabled (so long as the base::Feature is!), and -// issuance operations will check at runtime if the origin trial is enabled, -// returning an error if it is not. -// - For third-party origin trials, set kAllOperationsRequireOriginTrial. In -// Blink, the interface will be enabled exactly when the origin trial is present -// in the executing context (so long as the base::Feature is present). -// -// For testing, set kOriginTrialNotRequired. With this option, although all -// operations will still only be available if the base::Feature is enabled, none -// will additionally require that the origin trial be active. -const base::FeatureParam<TrustTokenOriginTrialSpec>::Option - kTrustTokenOriginTrialParamOptions[] = { - {TrustTokenOriginTrialSpec::kOriginTrialNotRequired, - "origin-trial-not-required"}, - {TrustTokenOriginTrialSpec::kAllOperationsRequireOriginTrial, - "all-operations-require-origin-trial"}, - {TrustTokenOriginTrialSpec::kOnlyIssuanceRequiresOriginTrial, - "only-issuance-requires-origin-trial"}}; -BASE_FEATURE_ENUM_PARAM(TrustTokenOriginTrialSpec, - kTrustTokenOperationsRequiringOriginTrial, - &kFledgePst, - "TrustTokenOperationsRequiringOriginTrial", - TrustTokenOriginTrialSpec::kOriginTrialNotRequired, - &kTrustTokenOriginTrialParamOptions); - // Enable support for ACCEPT_CH H2/3 frame as part of Client Hint Reliability. // See: // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02#section-4.3
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h index aca47aa..a2d1dad 100644 --- a/services/network/public/cpp/features.h +++ b/services/network/public/cpp/features.h
@@ -60,26 +60,6 @@ COMPONENT_EXPORT(NETWORK_CPP) BASE_DECLARE_FEATURE(kAttributionReportingCrossAppWeb); -// Both flags need to be checked for required PST components as they are being -// used in different experiments. -// -// kFledgePst is the original flag used in the OT and respects -// the TrustTrialOriginTrialSpec. It will be deprecated in favor of -// kPrivateStateTokens when the experiment is over. -COMPONENT_EXPORT(NETWORK_CPP) BASE_DECLARE_FEATURE(kPrivateStateTokens); -COMPONENT_EXPORT(NETWORK_CPP) BASE_DECLARE_FEATURE(kFledgePst); - -enum class TrustTokenOriginTrialSpec { - // See the .cc file for definitions. - kAllOperationsRequireOriginTrial, - kOnlyIssuanceRequiresOriginTrial, - kOriginTrialNotRequired, -}; -COMPONENT_EXPORT(NETWORK_CPP) -BASE_DECLARE_FEATURE_PARAM(TrustTokenOriginTrialSpec, - kTrustTokenOperationsRequiringOriginTrial); -COMPONENT_EXPORT(NETWORK_CPP) - COMPONENT_EXPORT(NETWORK_CPP) BASE_DECLARE_FEATURE(kAcceptCHFrame); COMPONENT_EXPORT(NETWORK_CPP)
diff --git a/services/tracing/perfetto/consumer_host_unittest.cc b/services/tracing/perfetto/consumer_host_unittest.cc index ed637c3..8ec64b9c 100644 --- a/services/tracing/perfetto/consumer_host_unittest.cc +++ b/services/tracing/perfetto/consumer_host_unittest.cc
@@ -557,28 +557,22 @@ no_more_data.Run(); } -#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_ANDROID) -// TODO(crbug.com/383878432): Re-enable this test -#define MAYBE_FlushProducers DISABLED_FlushProducers -#else -#define MAYBE_FlushProducers FlushProducers -#endif -TEST_F(TracingConsumerTest, MAYBE_FlushProducers) { +TEST_F(TracingConsumerTest, FlushProducers) { EnableTracingWithDataSourceName(kDataSourceName); threaded_perfetto_service()->CreateProducer(); auto writer = threaded_perfetto_service()->CreateTraceWriter(kDataSourceName); - MockProducer::WritePackets(*writer, 10); base::RunLoop wait_for_packets; ExpectPackets(kPerfettoTestString, wait_for_packets.QuitClosure()); - base::RunLoop wait_for_flush; + MockProducer::WritePackets(*writer, 10); + base::RunLoop wait_for_flush; threaded_perfetto_service()->Flush(*writer, wait_for_flush.QuitClosure()); - ReadBuffers(); wait_for_flush.Run(); + ReadBuffers(); wait_for_packets.Run(); EXPECT_EQ(10u, matching_packet_count());
diff --git a/testing/buildbot/internal.optimization_guide.json b/testing/buildbot/internal.optimization_guide.json index d319de5..0167e217 100644 --- a/testing/buildbot/internal.optimization_guide.json +++ b/testing/buildbot/internal.optimization_guide.json
@@ -932,38 +932,7 @@ ] }, "optimization_guide-android-arm64": { - "gtest_tests": [ - { - "args": [ - "--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*", - "--gs-results-bucket=chromium-result-details", - "--recover-devices" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", - "optimization_guide_components_unittests" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "name": "optimization_guide_components_unittests", - "swarming": { - "dimensions": { - "cpu": null, - "device_os": "R", - "device_os_type": "userdebug", - "device_type": "flame", - "os": "Android", - "pool": "chrome.tests" - }, - "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" - } - ] + "gtest_tests": [] }, "optimization_guide-chromeos": { "gtest_tests": [ @@ -985,25 +954,6 @@ }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ - "--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "optimization_guide_components_unittests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Ubuntu-22.04", - "pool": "chrome.tests" - }, - "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" } ] }, @@ -1230,27 +1180,6 @@ }, { "args": [ - "--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*", - "--use-xvfb" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "optimization_guide_components_unittests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "gce": "1", - "os": "Ubuntu-22.04", - "pool": "chrome.tests.intelligence" - }, - "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "args": [ "--ui-test-action-timeout=30000", "-use-xvfb" ], @@ -1470,25 +1399,6 @@ }, { "args": [ - "--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "optimization_guide_components_unittests", - "swarming": { - "dimensions": { - "cpu": "arm64", - "os": "Mac-14", - "pool": "chrome.tests" - }, - "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "args": [ "--ui-test-action-timeout=30000" ], "merge": { @@ -1695,25 +1605,6 @@ }, { "args": [ - "--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "optimization_guide_components_unittests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-14", - "pool": "chrome.tests" - }, - "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "args": [ "--ui-test-action-timeout=30000" ], "merge": { @@ -1924,27 +1815,6 @@ }, { "args": [ - "--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "optimization_guide_components_unittests", - "swarming": { - "dimensions": { - "cpu": "arm64", - "os": "Windows-11", - "pool": "chrome.tests", - "screen_scaling_percent": "100" - }, - "expiration": 7200, - "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "args": [ "--ui-test-action-timeout=30000" ], "merge": { @@ -2133,25 +2003,6 @@ }, { "args": [ - "--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "optimization_guide_components_unittests", - "swarming": { - "dimensions": { - "gce": "1", - "os": "Windows-10-19045", - "pool": "chrome.tests.intelligence" - }, - "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "args": [ "--ui-test-action-timeout=30000" ], "merge": { @@ -2421,25 +2272,6 @@ }, { "args": [ - "--gtest_filter=*OptimizationGuide*:*PageEntities*:*EntityAnnotator*" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "optimization_guide_components_unittests", - "swarming": { - "dimensions": { - "gce": "1", - "os": "Windows-10-19045", - "pool": "chrome.tests.intelligence" - }, - "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "components_unittests", - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "args": [ "--ui-test-action-timeout=30000" ], "merge": {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index d4c45d6b..74720b0 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2958,7 +2958,7 @@ ], "experiments": [ { - "name": "Disabled", + "name": "Holdback", "disable_features": [ "BackForwardCacheNonStickyDoubleFix" ] @@ -13329,6 +13329,7 @@ "name": "Enabled_Dogfood", "enable_features": [ "LobsterDogfood", + "LobsterQuickInsertZeroState", "LobsterRightClickMenu" ] } @@ -17353,24 +17354,6 @@ ] } ], - "Prerender2NewTabPageAndroidTrigger": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled_20240821", - "params": { - "prerender_new_tab_page_on_touch_trigger": "47" - }, - "enable_features": [ - "NewTabPageAndroidTriggerForPrerender2" - ] - } - ] - } - ], "Prerender2NewTabPageTriggerV2": [ { "platforms": [
diff --git a/third_party/angle b/third_party/angle index e72cc71..1c096a8 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit e72cc71b28a13ec0dcd9791bc2467f55482afa35 +Subproject commit 1c096a8589802f2cdc12cd423a1b6f248fc930b0
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index fdcc294..deecb3a2 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -2265,10 +2265,6 @@ "ReleaseResourceDecodedDataOnMemoryPressure", base::FEATURE_ENABLED_BY_DEFAULT); -BASE_FEATURE(kRemoveAuthroizationOnCrossOriginRedirect, - "RemoveAutorizationOnCrossOriginRedirect", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kRenderBlockingFonts, "RenderBlockingFonts", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index bc94dd2..ce91b3f 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -1454,10 +1454,6 @@ BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE( kReleaseResourceStrongReferencesOnMemoryPressure); -// Kill-switch for removing Authorization header upon cross origin redirects. -BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE( - kRemoveAuthroizationOnCrossOriginRedirect); - // Makes preloaded fonts render-blocking up to the limits below. // See https://crbug.com/1412861 BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kRenderBlockingFonts);
diff --git a/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom index 1f7305c7..38a71c5 100644 --- a/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom +++ b/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom
@@ -325,6 +325,7 @@ kWindowControlsOverlay = 267, kFetchPriority = 268, kHighlight = 269, + kDRAFT_ErrorIsError = 270, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc index 3a66b8f..d605775 100644 --- a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc +++ b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
@@ -450,6 +450,9 @@ case v8::Isolate::kWeakReferences: webdx_feature = WebDXFeature::kWeakReferences; break; + case v8::Isolate::kErrorIsError: + webdx_feature = WebDXFeature::kDRAFT_ErrorIsError; + break; default: // This can happen if V8 has added counters that this version of Blink // does not know about. It's harmless.
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc index 98da84e..464528e 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -742,6 +742,10 @@ meta->CreateDataProperty(context, resolve_key, resolve_value).ToChecked(); } +bool IsDOMExceptionWrapper(v8::Isolate* isolate, v8::Local<v8::Object> object) { + return V8DOMException::HasInstance(isolate, object); +} + struct PrintV8OOM { const char* location; const v8::OOMDetails& details; @@ -783,6 +787,7 @@ isolate->SetHostImportModuleDynamicallyCallback(HostImportModuleDynamically); isolate->SetHostInitializeImportMetaObjectCallback( HostGetImportMetaProperties); + isolate->SetIsJSApiWrapperNativeErrorCallback(IsDOMExceptionWrapper); isolate->SetMetricsRecorder(std::make_shared<V8MetricsRecorder>(isolate)); #if BUILDFLAG(IS_WIN)
diff --git a/third_party/blink/renderer/core/css/build.gni b/third_party/blink/renderer/core/css/build.gni index 0c9bfa9..528d3d8 100644 --- a/third_party/blink/renderer/core/css/build.gni +++ b/third_party/blink/renderer/core/css/build.gni
@@ -545,8 +545,8 @@ "parser/css_at_rule_id.h", "parser/css_lazy_parsing_state.cc", "parser/css_lazy_parsing_state.h", - "parser/css_lazy_property_parser_impl.cc", - "parser/css_lazy_property_parser_impl.h", + "parser/css_lazy_property_parser.cc", + "parser/css_lazy_property_parser.h", "parser/css_nesting_type.h", "parser/css_parser.cc", "parser/css_parser.h",
diff --git a/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.cc b/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.cc index 44b2b64..d8ed363 100644 --- a/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.cc +++ b/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.cc
@@ -245,8 +245,11 @@ CheckPseudoHasArgumentContext::CheckPseudoHasArgumentContext( const CSSSelector* selector, + const ContainerNode* scope, bool match_in_shadow_tree) - : has_argument_(selector), match_in_shadow_tree_(match_in_shadow_tree) { + : has_argument_(selector), + scope_(scope), + match_in_shadow_tree_(match_in_shadow_tree) { depth_limit_ = 0; adjacent_distance_limit_ = 0; bool contains_child_or_descendant_combinator = false;
diff --git a/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.h b/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.h index 72556ce23..e094a52 100644 --- a/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.h +++ b/third_party/blink/renderer/core/css/check_pseudo_has_argument_context.h
@@ -90,6 +90,7 @@ public: explicit CheckPseudoHasArgumentContext(const CSSSelector* selector, + const ContainerNode* scope, bool match_in_shadow_tree); inline bool AdjacentDistanceFixed() const { @@ -130,6 +131,9 @@ const CSSSelector* HasArgument() const { return has_argument_; } + // See SelectorCheckingContext::scope. + const ContainerNode* Scope() const { return scope_; } + const Vector<unsigned>& GetPseudoHasArgumentHashes() const { return pseudo_has_argument_hashes_; } @@ -281,6 +285,7 @@ CheckPseudoHasArgumentTraversalScope traversal_scope_; SiblingsAffectedByHasFlags siblings_affected_by_has_flags_; const CSSSelector* has_argument_; + const ContainerNode* scope_; bool match_in_shadow_tree_; Vector<unsigned> pseudo_has_argument_hashes_;
diff --git a/third_party/blink/renderer/core/css/check_pseudo_has_argument_context_test.cc b/third_party/blink/renderer/core/css/check_pseudo_has_argument_context_test.cc index d512002..ca77fdb1 100644 --- a/third_party/blink/renderer/core/css/check_pseudo_has_argument_context_test.cc +++ b/third_party/blink/renderer/core/css/check_pseudo_has_argument_context_test.cc
@@ -37,7 +37,8 @@ CSSSelectorList* selector_list = css_test_helpers::ParseSelectorList(selector_text); CheckPseudoHasArgumentContext context( - selector_list->First()->SelectorList()->First(), match_in_shadow_tree); + selector_list->First()->SelectorList()->First(), /*scope=*/nullptr, + match_in_shadow_tree); EXPECT_EQ(expected_leftmost_relation, context.LeftmostRelation()) << "Failed : " << selector_text; @@ -73,7 +74,8 @@ CSSSelectorList* selector_list = css_test_helpers::ParseSelectorList(selector_text); CheckPseudoHasArgumentContext argument_context( - selector_list->First()->SelectorList()->First(), match_in_shadow_tree); + selector_list->First()->SelectorList()->First(), /*scope=*/nullptr, + match_in_shadow_tree); for (CheckPseudoHasArgumentTraversalIterator iterator(*has_anchor_element, argument_context); !iterator.AtEnd(); ++iterator, ++i) { @@ -100,7 +102,8 @@ EXPECT_EQ(selector_list->First()->GetPseudoType(), CSSSelector::kPseudoHas); CheckPseudoHasArgumentContext context( - selector_list->First()->SelectorList()->First(), match_in_shadow_tree); + selector_list->First()->SelectorList()->First(), /*scope=*/nullptr, + match_in_shadow_tree); return context.TraversalType(); } @@ -124,7 +127,8 @@ CSSSelectorList* selector_list = css_test_helpers::ParseSelectorList(selector_text); CheckPseudoHasArgumentContext argument_context( - selector_list->First()->SelectorList()->First(), match_in_shadow_tree); + selector_list->First()->SelectorList()->First(), /*scope=*/nullptr, + match_in_shadow_tree); for (CheckPseudoHasArgumentTraversalIterator iterator(*has_anchor_element, argument_context); !iterator.AtEnd(); ++iterator, ++i) {
diff --git a/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope.cc b/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope.cc index aa98248..55ed147 100644 --- a/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope.cc +++ b/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope.cc
@@ -44,11 +44,14 @@ // static ElementCheckPseudoHasResultMap& CheckPseudoHasCacheScope::GetResultMap( const Document* document, - const CSSSelector* selector) { + const CSSSelector* selector, + const ContainerNode* scope) { + uintptr_t scope_id = reinterpret_cast<uintptr_t>(scope); // To increase the cache hit ratio, we need to have a same cache key // for multiple selector instances those are actually has a same selector. // TODO(blee@igalia.com) Find a way to get hash key without serialization. - String selector_text = selector->SelectorTextExpandingPseudoParent(); + String selector_text = + selector->SelectorTextExpandingPseudoReferences(scope_id); DCHECK(document); DCHECK(document->GetCheckPseudoHasCacheScope()); @@ -93,7 +96,7 @@ case CheckPseudoHasArgumentTraversalScope::kAllNextSiblings: cache_allowed_ = true; result_map_ = &CheckPseudoHasCacheScope::GetResultMap( - document, argument_context.HasArgument()); + document, argument_context.HasArgument(), argument_context.Scope()); fast_reject_filter_map_ = &CheckPseudoHasCacheScope::GetFastRejectFilterMap( document, argument_context.TraversalType());
diff --git a/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope.h b/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope.h index acd19cf..194c2eb 100644 --- a/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope.h +++ b/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope.h
@@ -290,8 +290,8 @@ }; private: - static ElementCheckPseudoHasResultMap& GetResultMap(const Document*, - const CSSSelector*); + static ElementCheckPseudoHasResultMap& + GetResultMap(const Document*, const CSSSelector*, const ContainerNode* scope); static ElementCheckPseudoHasFastRejectFilterMap& GetFastRejectFilterMap( const Document*, CheckPseudoHasArgumentTraversalType);
diff --git a/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope_context_test.cc b/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope_context_test.cc index 9c90a22..d52d767b 100644 --- a/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope_context_test.cc +++ b/third_party/blink/renderer/core/css/check_pseudo_has_cache_scope_context_test.cc
@@ -113,6 +113,7 @@ const CSSSelector* argument_selector = selector->SelectorList()->First(); CheckPseudoHasArgumentContext argument_context(argument_selector, + /*scope=*/nullptr, match_in_shadow_tree); CheckPseudoHasCacheScope::Context cache_scope_context(document, argument_context);
diff --git a/third_party/blink/renderer/core/css/check_pseudo_has_fast_reject_filter_test.cc b/third_party/blink/renderer/core/css/check_pseudo_has_fast_reject_filter_test.cc index 13790fe..07d20e24 100644 --- a/third_party/blink/renderer/core/css/check_pseudo_has_fast_reject_filter_test.cc +++ b/third_party/blink/renderer/core/css/check_pseudo_has_fast_reject_filter_test.cc
@@ -49,6 +49,7 @@ CheckPseudoHasArgumentContext context( selector_list->First()->SelectorList()->First(), + /*scope=*/nullptr, /* match_in_shadow_tree */ false); return filter.FastReject(context.GetPseudoHasArgumentHashes());
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.cc b/third_party/blink/renderer/core/css/css_property_value_set.cc index 5e2ac6f..4675138 100644 --- a/third_party/blink/renderer/core/css/css_property_value_set.cc +++ b/third_party/blink/renderer/core/css/css_property_value_set.cc
@@ -805,6 +805,4 @@ } #endif -void CSSLazyPropertyParser::Trace(Visitor* visitor) const {} - } // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.h b/third_party/blink/renderer/core/css/css_property_value_set.h index 8cfac35..24adc9c 100644 --- a/third_party/blink/renderer/core/css/css_property_value_set.h +++ b/third_party/blink/renderer/core/css/css_property_value_set.h
@@ -196,17 +196,6 @@ friend class PropertySetCSSStyleDeclaration; }; -// Used for lazily parsing properties. -class CSSLazyPropertyParser : public GarbageCollected<CSSLazyPropertyParser> { - public: - CSSLazyPropertyParser() = default; - CSSLazyPropertyParser(const CSSLazyPropertyParser&) = delete; - CSSLazyPropertyParser& operator=(const CSSLazyPropertyParser&) = delete; - virtual ~CSSLazyPropertyParser() = default; - virtual CSSPropertyValueSet* ParseProperties() = 0; - virtual void Trace(Visitor*) const; -}; - class CORE_EXPORT alignas(CSSPropertyName) ImmutableCSSPropertyValueSet : public CSSPropertyValueSet { public:
diff --git a/third_party/blink/renderer/core/css/css_selector.cc b/third_party/blink/renderer/core/css/css_selector.cc index aba7ba9..aaee3dc 100644 --- a/third_party/blink/renderer/core/css/css_selector.cc +++ b/third_party/blink/renderer/core/css/css_selector.cc
@@ -59,7 +59,7 @@ namespace { -constexpr bool kExpandPseudoParent = true; +constexpr bool kExpandPseudoReferences = true; unsigned MaximumSpecificity(const CSSSelectorList* list) { if (!list) { @@ -1097,29 +1097,35 @@ } // static -template <bool expand_pseudo_parent> +template <bool expand_pseudo_references> void CSSSelector::SerializeSelectorList(const CSSSelectorList* selector_list, - StringBuilder& builder) { + StringBuilder& builder, + uintptr_t scope_id) { const CSSSelector* first_sub_selector = selector_list->First(); for (const CSSSelector* sub_selector = first_sub_selector; sub_selector; sub_selector = CSSSelectorList::Next(*sub_selector)) { if (sub_selector != first_sub_selector) { builder.Append(", "); } - builder.Append(sub_selector->SelectorTextInternal<expand_pseudo_parent>()); + builder.Append( + sub_selector->SelectorTextInternal<expand_pseudo_references>(scope_id)); } } String CSSSelector::SelectorText() const { - return SelectorTextInternal<!kExpandPseudoParent>(); + // The value of `scope_id` does not matter when + // `expand_pseudo_references` is `false`. + return SelectorTextInternal<!kExpandPseudoReferences>(/*scope_id=*/0); } -String CSSSelector::SelectorTextExpandingPseudoParent() const { - return SelectorTextInternal<kExpandPseudoParent>(); +String CSSSelector::SelectorTextExpandingPseudoReferences( + uintptr_t scope_id) const { + return SelectorTextInternal<kExpandPseudoReferences>(scope_id); } -template <bool expand_pseudo_parent> -bool CSSSelector::SerializeSimpleSelector(StringBuilder& builder) const { +template <bool expand_pseudo_references> +bool CSSSelector::SerializeSimpleSelector(StringBuilder& builder, + uintptr_t scope_id) const { bool suppress_selector_list = false; if (Match() == kId) { builder.Append('#'); @@ -1130,7 +1136,8 @@ } else if (Match() == kPseudoClass || Match() == kPagePseudoClass) { if (GetPseudoType() == kPseudoUnparsed) { builder.Append(Value()); - } else if (GetPseudoType() != kPseudoParent) { + } else if (GetPseudoType() != kPseudoParent && + GetPseudoType() != kPseudoScope) { builder.Append(':'); builder.Append(SerializingValue()); } @@ -1166,8 +1173,8 @@ // Only relevant for :nth-child, not :nth-of-type. if (data_.rare_data_->selector_list_ != nullptr) { builder.Append(" of "); - SerializeSelectorList<expand_pseudo_parent>( - data_.rare_data_->selector_list_, builder); + SerializeSelectorList<expand_pseudo_references>( + data_.rare_data_->selector_list_, builder, scope_id); suppress_selector_list = true; } @@ -1192,18 +1199,28 @@ case kPseudoWhere: break; case kPseudoParent: - if constexpr (expand_pseudo_parent) { + if constexpr (expand_pseudo_references) { // Replace parent pseudo with equivalent :is() pseudo. builder.Append(":is"); if (auto* parent = SelectorListOrParent()) { builder.Append('('); - builder.Append(parent->SelectorTextExpandingPseudoParent()); + builder.Append( + parent->SelectorTextExpandingPseudoReferences(scope_id)); builder.Append(')'); } } else { builder.Append('&'); } break; + case kPseudoScope: + if constexpr (expand_pseudo_references) { + builder.Append(":-internal-scope-"); + builder.AppendNumber(scope_id); + } else { + builder.Append(':'); + builder.Append(SerializingValue()); + } + break; case kPseudoRelativeAnchor: NOTREACHED(); case kPseudoActiveViewTransitionType: { @@ -1319,15 +1336,16 @@ if (SelectorList() && !suppress_selector_list) { builder.Append('('); - SerializeSelectorList<expand_pseudo_parent>(SelectorList(), builder); + SerializeSelectorList<expand_pseudo_references>(SelectorList(), builder, + scope_id); builder.Append(')'); } return true; } -template <bool expand_pseudo_parent> -const CSSSelector* CSSSelector::SerializeCompound( - StringBuilder& builder) const { +template <bool expand_pseudo_references> +const CSSSelector* CSSSelector::SerializeCompound(StringBuilder& builder, + uintptr_t scope_id) const { if (Match() == kTag && !IsImplicit()) { SerializeNamespacePrefixIfNeeded(TagQName().Prefix(), g_star_atom, builder, IsAttributeSelector()); @@ -1337,8 +1355,8 @@ for (const CSSSelector* simple_selector = this; simple_selector; simple_selector = simple_selector->NextSimpleSelector()) { - if (!simple_selector->SerializeSimpleSelector<expand_pseudo_parent>( - builder)) { + if (!simple_selector->SerializeSimpleSelector<expand_pseudo_references>( + builder, scope_id)) { return nullptr; } if (simple_selector->Relation() != kSubSelector) { @@ -1348,13 +1366,14 @@ return nullptr; } -template <bool expand_pseudo_parent> -String CSSSelector::SelectorTextInternal() const { +template <bool expand_pseudo_references> +String CSSSelector::SelectorTextInternal(uintptr_t scope_id) const { String result; for (const CSSSelector* compound = this; compound; compound = compound->NextSimpleSelector()) { StringBuilder builder; - compound = compound->SerializeCompound<expand_pseudo_parent>(builder); + compound = compound->SerializeCompound<expand_pseudo_references>(builder, + scope_id); if (!compound) { return builder.ReleaseString() + result; } @@ -1366,10 +1385,13 @@ DCHECK(next_compound); // If we are combining with an implicit :scope, it is as if we - // used a relative combinator. - if (!next_compound || (next_compound->Match() == kPseudoClass && - next_compound->GetPseudoType() == kPseudoScope && - next_compound->IsImplicit())) { + // used a relative combinator. However, when expand_pseudo_references=true, + // we must serialize the implicit compound anyway, since the :has() cache + // needs this to be a part of the key. + bool implicit = next_compound->IsImplicit() && !expand_pseudo_references; + if (!next_compound || + (next_compound->Match() == kPseudoClass && + next_compound->GetPseudoType() == kPseudoScope && implicit)) { relation = ConvertRelationToRelative(relation); } @@ -1413,7 +1435,8 @@ SerializeIdentifierOrAny(TagQName().LocalName(), UniversalSelectorAtom(), builder); } else { - SerializeSimpleSelector<!kExpandPseudoParent>(builder); + // `scope_id` is ignored when `expand_pseudo_references` is false. + SerializeSimpleSelector<!kExpandPseudoReferences>(builder, /*scope_id=*/0); } return builder.ToString(); }
diff --git a/third_party/blink/renderer/core/css/css_selector.h b/third_party/blink/renderer/core/css/css_selector.h index 6f505ad..23a932ad 100644 --- a/third_party/blink/renderer/core/css/css_selector.h +++ b/third_party/blink/renderer/core/css/css_selector.h
@@ -156,11 +156,15 @@ ~CSSSelector(); String SelectorText() const; - // Like `SelectorText`, but replaces any '&' selectors - // with ':is(<parent rule selector list>)'. This is needed - // by the :has() cache, because it uses the serialization of - // the selector as a key. - String SelectorTextExpandingPseudoParent() const; + // Like `SelectorText`, but replaces any "pseudo-references" with an expansion + // which makes the result useful as a key in the :has() cache. + // A "pseudo-reference" is either a '&' selector (which is replaced with + // :is(<parent rule selector list>)), or a :scope selector (which is replaced + // with :-internal-scope-<scope_id>). + // + // Note that this means that the returned text is not necessarily a valid + // selector. + String SelectorTextExpandingPseudoReferences(uintptr_t scope_id) const; String SimpleSelectorTextForDebug() const; CSSSelector& operator=(const CSSSelector&) = delete; @@ -685,18 +689,21 @@ unsigned SpecificityForOneSelector() const; unsigned SpecificityForPage() const; - template <bool expand_pseudo_parent> - bool SerializeSimpleSelector(WTF::StringBuilder& builder) const; + template <bool expand_pseudo_references> + bool SerializeSimpleSelector(WTF::StringBuilder& builder, + uintptr_t scope_id) const; - template <bool expand_pseudo_parent> - const CSSSelector* SerializeCompound(WTF::StringBuilder&) const; + template <bool expand_pseudo_references> + const CSSSelector* SerializeCompound(WTF::StringBuilder&, + uintptr_t scope_id) const; - template <bool expand_pseudo_parent> + template <bool expand_pseudo_references> static void SerializeSelectorList(const CSSSelectorList* selector_list, - WTF::StringBuilder& builder); + WTF::StringBuilder& builder, + uintptr_t scope_id); - template <bool expand_pseudo_parent> - String SelectorTextInternal() const; + template <bool expand_pseudo_references> + String SelectorTextInternal(uintptr_t scope_id) const; struct RareData : public GarbageCollected<RareData> { explicit RareData(const AtomicString& value);
diff --git a/third_party/blink/renderer/core/css/css_selector_test.cc b/third_party/blink/renderer/core/css/css_selector_test.cc index d98cdd3..1c91b13 100644 --- a/third_party/blink/renderer/core/css/css_selector_test.cc +++ b/third_party/blink/renderer/core/css/css_selector_test.cc
@@ -312,7 +312,7 @@ selector[0].Specificity()); } -TEST(CSSSelector, CheckSelectorTextExpandingPseudoParent) { +TEST(CSSSelector, SelectorTextExpandingPseudoReferences_Parent) { test::TaskEnvironment task_environment; css_test_helpers::TestStyleSheet sheet; @@ -330,21 +330,23 @@ ASSERT_EQ(1u, rules.size()); selector = &rules[0].Selector(); EXPECT_EQ("& .b", selector->SelectorText()); - EXPECT_EQ(":is(.a) .b", selector->SelectorTextExpandingPseudoParent()); + EXPECT_EQ(":is(.a) .b", + selector->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); rules = rule_set.ClassRules(AtomicString("c")); ASSERT_EQ(3u, rules.size()); selector = &rules[0].Selector(); EXPECT_EQ("& .c", selector->SelectorText()); EXPECT_EQ(":is(:is(.a) .b) .c", - selector->SelectorTextExpandingPseudoParent()); + selector->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); selector = &rules[1].Selector(); EXPECT_EQ("&.c", selector->SelectorText()); - EXPECT_EQ(":is(:is(.a) .b).c", selector->SelectorTextExpandingPseudoParent()); + EXPECT_EQ(":is(:is(.a) .b).c", + selector->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); selector = &rules[2].Selector(); EXPECT_EQ(".c:has(&)", selector->SelectorText()); EXPECT_EQ(".c:has(:is(:is(.a) .b))", - selector->SelectorTextExpandingPseudoParent()); + selector->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); rules = rule_set.ClassRules(AtomicString("e")); ASSERT_EQ(1u, rules.size()); @@ -356,7 +358,54 @@ selector = &rules[0].Selector(); EXPECT_EQ(".f:has(> &)", selector->SelectorText()); EXPECT_EQ(".f:has(> :is(.d .e))", - selector->SelectorTextExpandingPseudoParent()); + selector->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); +} + +TEST(CSSSelector, SelectorTextExpandingPseudoReferences_Scope) { + test::TaskEnvironment task_environment; + + auto expanded_selector_text = [](String s) { + return css_test_helpers::ParseSelectorList(s) + ->First() + ->SelectorTextExpandingPseudoReferences(/*scope_id=*/42); + }; + + EXPECT_EQ(".a .b :has(.c)", expanded_selector_text(".a .b :has(.c)")); + + EXPECT_EQ(":-internal-scope-42", expanded_selector_text(":scope")); + EXPECT_EQ(".a:-internal-scope-42", expanded_selector_text(".a:scope")); + EXPECT_EQ(".a :-internal-scope-42", expanded_selector_text(".a :scope")); + EXPECT_EQ(":-internal-scope-42.a", expanded_selector_text(":scope.a")); + EXPECT_EQ(":is(.a, :-internal-scope-42)", + expanded_selector_text(":is(.a, :scope)")); + EXPECT_EQ(":not(.a, :-internal-scope-42)", + expanded_selector_text(":not(.a, :scope)")); + EXPECT_EQ( + ":not(.a, :-internal-scope-42)" + ":where(:-internal-scope-42, :-internal-scope-42):-internal-scope-42", + expanded_selector_text(":not(.a, :scope):where(:scope, :scope):scope")); + EXPECT_EQ(":has(.b:not(:-internal-scope-42 .a *))", + expanded_selector_text(":has(.b:not(:scope .a *))")); +} + +TEST(CSSSelector, SelectorTextExpandingPseudoReferences_ImplicitScope) { + test::TaskEnvironment task_environment; + + css_test_helpers::TestStyleSheet sheet; + sheet.AddCSSRules(R"CSS( + @scope (.a) { + /* There's an implicit (non-serialized) ':scope' (plus descendant + combinator) prepended to the selector below. */ + .b {} + } + )CSS"); + RuleSet& rule_set = sheet.GetRuleSet(); + base::span<const RuleData> rules = rule_set.ClassRules(AtomicString("b")); + ASSERT_EQ(1u, rules.size()); + const CSSSelector* selector = &rules[0].Selector(); + EXPECT_EQ(".b", selector->SelectorText()); + EXPECT_EQ(":-internal-scope-99 .b", + selector->SelectorTextExpandingPseudoReferences(/*scope_id=*/99)); } TEST(CSSSelector, CheckHasArgumentMatchInShadowTreeFlag) { @@ -482,10 +531,12 @@ CSSSelectorList* new_list = old_list->Renest(b); EXPECT_NE(old_list, new_list); - EXPECT_EQ(":is(.a):is(:is(.a), .d)", - old_list->First()->SelectorTextExpandingPseudoParent()); - EXPECT_EQ(":is(.b):is(:is(.b), .d)", - new_list->First()->SelectorTextExpandingPseudoParent()); + EXPECT_EQ( + ":is(.a):is(:is(.a), .d)", + old_list->First()->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); + EXPECT_EQ( + ":is(.b):is(:is(.b), .d)", + new_list->First()->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); } TEST(CSSSelector, RenestNoNesting) {
diff --git a/third_party/blink/renderer/core/css/css_style_declaration.cc b/third_party/blink/renderer/core/css/css_style_declaration.cc index 0cf3b1c..2b9fdd53 100644 --- a/third_party/blink/renderer/core/css/css_style_declaration.cc +++ b/third_party/blink/renderer/core/css/css_style_declaration.cc
@@ -192,26 +192,23 @@ if (!IsValidCSSPropertyID(unresolved_property)) { return NamedPropertySetterResult::kDidNotIntercept; } - // We create the ExceptionState manually due to performance issues: adding - // [RaisesException] to the IDL causes the bindings layer to expensively - // create a std::string to set the ExceptionState's |property_name| argument, - // while we can use CSSProperty::GetPropertyName() here (see bug 829408). - ExceptionState exception_state(script_state->GetIsolate()); // TODO(crbug.com/1499981): This should be removed once synchronized scrolling // impact is understood. SyncScrollAttemptHeuristic::DidSetStyle(); if (value->IsNumber()) { - double double_value = NativeValueTraits<IDLUnrestrictedDouble>::NativeValue( - script_state->GetIsolate(), value, exception_state); - if (exception_state.HadException()) [[unlikely]] { - return NamedPropertySetterResult::kIntercepted; - } + double double_value = value.As<v8::Number>()->Value(); if (FastPathSetProperty(unresolved_property, double_value)) { return NamedPropertySetterResult::kIntercepted; } // The fast path failed, e.g. because the property was a longhand, // so let the normal string handling deal with it. } + // We create the ExceptionState manually due to performance issues: adding + // [RaisesException] to the IDL causes the bindings layer to expensively + // create a std::string to set the ExceptionState's |property_name| + // argument, while we can use CSSProperty::GetPropertyName() here (see bug + // 829408). + ExceptionState exception_state(script_state->GetIsolate()); if (value->IsString()) { // NativeValueTraits::ToBlinkStringView() (called implicitly on conversion) // tries fairly hard to make an AtomicString out of the string,
diff --git a/third_party/blink/renderer/core/css/cssom_utils.cc b/third_party/blink/renderer/core/css/cssom_utils.cc index c5ef5c6..55aeb1e 100644 --- a/third_party/blink/renderer/core/css/cssom_utils.cc +++ b/third_party/blink/renderer/core/css/cssom_utils.cc
@@ -157,11 +157,10 @@ grid_area_text.Append(' '); } } - if (!grid_area_text.empty()) { - template_row_list->Append(*MakeGarbageCollected<CSSStringValue>( - grid_area_text.ReleaseString())); - ++row; - } + DCHECK(!grid_area_text.empty()); + template_row_list->Append( + *MakeGarbageCollected<CSSStringValue>(grid_area_text.ReleaseString())); + ++row; // Omit `auto` values. if (!IsAutoValue(row_value.Get())) {
diff --git a/third_party/blink/renderer/core/css/parser/css_lazy_property_parser.cc b/third_party/blink/renderer/core/css/parser/css_lazy_property_parser.cc new file mode 100644 index 0000000..a5199aa --- /dev/null +++ b/third_party/blink/renderer/core/css/parser/css_lazy_property_parser.cc
@@ -0,0 +1,25 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/css/parser/css_lazy_property_parser.h" + +#include "third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h" +#include "third_party/blink/renderer/core/css/parser/css_parser_impl.h" + +namespace blink { + +CSSLazyPropertyParser::CSSLazyPropertyParser(wtf_size_t offset, + CSSLazyParsingState* state) + : offset_(offset), lazy_state_(state) {} + +CSSPropertyValueSet* CSSLazyPropertyParser::ParseProperties() { + return CSSParserImpl::ParseDeclarationListForLazyStyle( + lazy_state_->SheetText(), offset_, lazy_state_->Context()); +} + +void CSSLazyPropertyParser::Trace(Visitor* visitor) const { + visitor->Trace(lazy_state_); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.h b/third_party/blink/renderer/core/css/parser/css_lazy_property_parser.h similarity index 66% rename from third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.h rename to third_party/blink/renderer/core/css/parser/css_lazy_property_parser.h index 9a1baf7..f7e72ce 100644 --- a/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.h +++ b/third_party/blink/renderer/core/css/parser/css_lazy_property_parser.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_LAZY_PROPERTY_PARSER_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_LAZY_PROPERTY_PARSER_IMPL_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_LAZY_PROPERTY_PARSER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_LAZY_PROPERTY_PARSER_H_ #include "third_party/blink/renderer/core/css/css_property_value_set.h" #include "third_party/blink/renderer/core/css/parser/css_tokenizer.h" @@ -13,17 +13,14 @@ class CSSLazyParsingState; // This class is responsible for lazily parsing a single CSS declaration list. -class CSSLazyPropertyParserImpl : public CSSLazyPropertyParser { +class CSSLazyPropertyParser : public GarbageCollected<CSSLazyPropertyParser> { public: - CSSLazyPropertyParserImpl(wtf_size_t offset, CSSLazyParsingState*); + CSSLazyPropertyParser(wtf_size_t offset, CSSLazyParsingState*); // CSSLazyPropertyParser: - CSSPropertyValueSet* ParseProperties() override; + CSSPropertyValueSet* ParseProperties(); - void Trace(Visitor* visitor) const override { - visitor->Trace(lazy_state_); - CSSLazyPropertyParser::Trace(visitor); - } + void Trace(Visitor* visitor) const; private: wtf_size_t offset_; @@ -32,4 +29,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_LAZY_PROPERTY_PARSER_IMPL_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_LAZY_PROPERTY_PARSER_H_
diff --git a/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.cc b/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.cc deleted file mode 100644 index a4314d8f..0000000 --- a/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.cc +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2016 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.h" - -#include "third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h" -#include "third_party/blink/renderer/core/css/parser/css_parser_impl.h" - -namespace blink { - -CSSLazyPropertyParserImpl::CSSLazyPropertyParserImpl(wtf_size_t offset, - CSSLazyParsingState* state) - : CSSLazyPropertyParser(), offset_(offset), lazy_state_(state) {} - -CSSPropertyValueSet* CSSLazyPropertyParserImpl::ParseProperties() { - return CSSParserImpl::ParseDeclarationListForLazyStyle( - lazy_state_->SheetText(), offset_, lazy_state_->Context()); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc index 477862b..cdde6c0 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
@@ -30,7 +30,7 @@ #include "third_party/blink/renderer/core/css/parser/container_query_parser.h" #include "third_party/blink/renderer/core/css/parser/css_at_rule_id.h" #include "third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h" -#include "third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.h" +#include "third_party/blink/renderer/core/css/parser/css_lazy_property_parser.h" #include "third_party/blink/renderer/core/css/parser/css_parser_observer.h" #include "third_party/blink/renderer/core/css/parser/css_parser_token_stream.h" #include "third_party/blink/renderer/core/css/parser/css_property_parser.h" @@ -2671,9 +2671,9 @@ if (len != 0) { wtf_size_t block_start_offset = stream.Offset(); stream.SkipToEndOfBlock(len + 2); // +2 for { and }. - return StyleRule::Create( - selector_vector, MakeGarbageCollected<CSSLazyPropertyParserImpl>( - block_start_offset, lazy_state_)); + return StyleRule::Create(selector_vector, + MakeGarbageCollected<CSSLazyPropertyParser>( + block_start_offset, lazy_state_)); } } CSSParserTokenStream::BlockGuard guard(stream); @@ -2706,7 +2706,7 @@ } return StyleRule::Create(selector_vector, - MakeGarbageCollected<CSSLazyPropertyParserImpl>( + MakeGarbageCollected<CSSLazyPropertyParser>( block_start_offset, lazy_state_)); } return ConsumeStyleRuleContents(selector_vector, stream,
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc b/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc index 9f02b9fa..5a9db03 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc
@@ -1374,9 +1374,10 @@ auto* a = To<StyleRule>(css_test_helpers::ParseRule(*document, ".a{}")); StyleRuleBase* nested = css_test_helpers::ParseNestedRule( *document, "&{}", CSSNestingType::kNesting, a); - EXPECT_EQ(":is(.a)", To<StyleRule>(nested) - ->FirstSelector() - ->SelectorTextExpandingPseudoParent()); + EXPECT_EQ(":is(.a)", + To<StyleRule>(nested) + ->FirstSelector() + ->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h index c8ba7a6..c747cce5 100644 --- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h +++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
@@ -143,7 +143,9 @@ // well with complex keys. Of course, it means we are vulnerable to hash // collisions, in that we cannot store more than one different cache entry // with the same hash. - using Cache = HeapHashMap<unsigned, Member<CachedMatchedProperties>>; + using Cache = HeapHashMap<unsigned, + Member<CachedMatchedProperties>, + AlreadyHashedTraits>; void CleanMatchedPropertiesCache(const LivenessBroker&);
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc index 82816d5..0c27bb1 100644 --- a/third_party/blink/renderer/core/css/selector_checker.cc +++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -1418,7 +1418,7 @@ DCHECK(context.selector->SelectorList()); for (const CSSSelector* selector = context.selector->SelectorList()->First(); selector; selector = CSSSelectorList::Next(*selector)) { - CheckPseudoHasArgumentContext argument_context(selector, + CheckPseudoHasArgumentContext argument_context(selector, context.scope, match_in_shadow_tree); // In case of matching a :has() argument on a shadow root subtree, skip
diff --git a/third_party/blink/renderer/core/css/style_rule.h b/third_party/blink/renderer/core/css/style_rule.h index d43bf22..b5c77cdf 100644 --- a/third_party/blink/renderer/core/css/style_rule.h +++ b/third_party/blink/renderer/core/css/style_rule.h
@@ -40,6 +40,7 @@ #include "third_party/blink/renderer/core/css/css_variable_data.h" #include "third_party/blink/renderer/core/css/media_list.h" #include "third_party/blink/renderer/core/css/parser/css_at_rule_id.h" +#include "third_party/blink/renderer/core/css/parser/css_lazy_property_parser.h" #include "third_party/blink/renderer/core/css/parser/css_nesting_type.h" #include "third_party/blink/renderer/core/css/style_scope.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -409,6 +410,7 @@ void TraceAfterDispatch(blink::Visitor*) const; const StyleScope& GetStyleScope() const { return *style_scope_; } + private: Member<const StyleScope> style_scope_; };
diff --git a/third_party/blink/renderer/core/css/style_rule_test.cc b/third_party/blink/renderer/core/css/style_rule_test.cc index 9190d822..1299379 100644 --- a/third_party/blink/renderer/core/css/style_rule_test.cc +++ b/third_party/blink/renderer/core/css/style_rule_test.cc
@@ -317,14 +317,17 @@ /*parent_rule_for_nesting=*/a)); EXPECT_EQ(":is(.a)", - nested->FirstSelector()->SelectorTextExpandingPseudoParent()); + nested->FirstSelector()->SelectorTextExpandingPseudoReferences( + /*scope_id=*/0)); auto* reparented = To<StyleRule>(nested->Renest(b)); EXPECT_NE(nested, reparented); EXPECT_EQ(":is(.a)", - nested->FirstSelector()->SelectorTextExpandingPseudoParent()); + nested->FirstSelector()->SelectorTextExpandingPseudoReferences( + /*scope_id=*/0)); EXPECT_EQ(":is(.b)", - reparented->FirstSelector()->SelectorTextExpandingPseudoParent()); + reparented->FirstSelector()->SelectorTextExpandingPseudoReferences( + /*scope_id=*/0)); } TEST_F(StyleRuleTest, RenestStyleRuleNoOp) { @@ -333,7 +336,8 @@ GetDocument(), "& {}", CSSNestingType::kNesting, /*parent_rule_for_nesting=*/a)); EXPECT_EQ(":is(.a)", - nested->FirstSelector()->SelectorTextExpandingPseudoParent()); + nested->FirstSelector()->SelectorTextExpandingPseudoReferences( + /*scope_id=*/0)); auto* reparented = To<StyleRule>(nested->Renest(a)); EXPECT_EQ(nested, reparented); } @@ -346,20 +350,23 @@ /*parent_rule_for_nesting=*/a)); ASSERT_EQ(1u, media->ChildRules().size()); - EXPECT_EQ(":is(.a)", To<StyleRule>(media->ChildRules().front().Get()) - ->FirstSelector() - ->SelectorTextExpandingPseudoParent()); + EXPECT_EQ(":is(.a)", + To<StyleRule>(media->ChildRules().front().Get()) + ->FirstSelector() + ->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); EXPECT_EQ(media->Renest(a), media); // No-op. auto* reparented = To<StyleRuleMedia>(media->Renest(b)); EXPECT_NE(media, reparented); - EXPECT_EQ(":is(.a)", To<StyleRule>(media->ChildRules().front().Get()) - ->FirstSelector() - ->SelectorTextExpandingPseudoParent()); - EXPECT_EQ(":is(.b)", To<StyleRule>(reparented->ChildRules().front().Get()) - ->FirstSelector() - ->SelectorTextExpandingPseudoParent()); + EXPECT_EQ(":is(.a)", + To<StyleRule>(media->ChildRules().front().Get()) + ->FirstSelector() + ->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); + EXPECT_EQ(":is(.b)", + To<StyleRule>(reparented->ChildRules().front().Get()) + ->FirstSelector() + ->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); } TEST_F(StyleRuleTest, RenestStyleRuleStartingStyle) { @@ -371,20 +378,23 @@ /*parent_rule_for_nesting=*/a)); ASSERT_EQ(1u, starting_style->ChildRules().size()); - EXPECT_EQ(":is(.a)", To<StyleRule>(starting_style->ChildRules().front().Get()) - ->FirstSelector() - ->SelectorTextExpandingPseudoParent()); + EXPECT_EQ(":is(.a)", + To<StyleRule>(starting_style->ChildRules().front().Get()) + ->FirstSelector() + ->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); EXPECT_EQ(starting_style->Renest(a), starting_style); // No-op. auto* reparented = To<StyleRuleStartingStyle>(starting_style->Renest(b)); EXPECT_NE(starting_style, reparented); - EXPECT_EQ(":is(.a)", To<StyleRule>(starting_style->ChildRules().front().Get()) - ->FirstSelector() - ->SelectorTextExpandingPseudoParent()); - EXPECT_EQ(":is(.b)", To<StyleRule>(reparented->ChildRules().front().Get()) - ->FirstSelector() - ->SelectorTextExpandingPseudoParent()); + EXPECT_EQ(":is(.a)", + To<StyleRule>(starting_style->ChildRules().front().Get()) + ->FirstSelector() + ->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); + EXPECT_EQ(":is(.b)", + To<StyleRule>(reparented->ChildRules().front().Get()) + ->FirstSelector() + ->SelectorTextExpandingPseudoReferences(/*scope_id=*/0)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/abort_controller.idl b/third_party/blink/renderer/core/dom/abort_controller.idl index 748c127..3effadd 100644 --- a/third_party/blink/renderer/core/dom/abort_controller.idl +++ b/third_party/blink/renderer/core/dom/abort_controller.idl
@@ -5,7 +5,7 @@ // https://dom.spec.whatwg.org/#interface-abortcontroller [ - Exposed=(Window,Worker) + Exposed=(Window,Worker,ShadowRealm) // TODO(crbug.com/41480387): This should be Exposed=* ] interface AbortController { [CallWith=ScriptState, Measure] constructor(); [SameObject] readonly attribute AbortSignal signal;
diff --git a/third_party/blink/renderer/core/dom/abort_signal.idl b/third_party/blink/renderer/core/dom/abort_signal.idl index d0d3318..7f1d3e0 100644 --- a/third_party/blink/renderer/core/dom/abort_signal.idl +++ b/third_party/blink/renderer/core/dom/abort_signal.idl
@@ -5,7 +5,7 @@ // https://dom.spec.whatwg.org/#interface-AbortSignal [ - Exposed=(Window,Worker) + Exposed=(Window,Worker,ShadowRealm) // TODO(crbug.com/41480387): This should be Exposed=* ] interface AbortSignal : EventTarget { [ CallWith=ScriptState, @@ -13,6 +13,7 @@ NewObject ] static AbortSignal abort(optional any reason); [ + Exposed=(Window,Worker), CallWith=ScriptState, MeasureAs=AbortSignalTimeout, NewObject
diff --git a/third_party/blink/renderer/core/dom/dom_exception.idl b/third_party/blink/renderer/core/dom/dom_exception.idl index 866ffbc..6e82962 100644 --- a/third_party/blink/renderer/core/dom/dom_exception.idl +++ b/third_party/blink/renderer/core/dom/dom_exception.idl
@@ -31,7 +31,7 @@ // https://webidl.spec.whatwg.org/#es-DOMException [ - Exposed=(Window,Worker), + Exposed=(Window,Worker,ShadowRealm), // TODO(crbug.com/41480387): This should be Exposed=* Serializable ] interface DOMException { constructor(optional DOMString message = "", optional DOMString name = "Error");
diff --git a/third_party/blink/renderer/core/dom/events/custom_event.idl b/third_party/blink/renderer/core/dom/events/custom_event.idl index 0bb00fd..91eb44be 100644 --- a/third_party/blink/renderer/core/dom/events/custom_event.idl +++ b/third_party/blink/renderer/core/dom/events/custom_event.idl
@@ -26,7 +26,7 @@ // https://dom.spec.whatwg.org/#interface-customevent [ - Exposed=(Window,Worker) + Exposed=(Window,Worker,ShadowRealm) // TODO(crbug.com/41480387): This should be Exposed=* ] interface CustomEvent : Event { [CallWith=ScriptState] constructor(DOMString type, optional CustomEventInit eventInitDict = {}); [CallWith=ScriptState] readonly attribute any detail;
diff --git a/third_party/blink/renderer/core/dom/events/event.idl b/third_party/blink/renderer/core/dom/events/event.idl index 5566b4b8..7ef78b6 100644 --- a/third_party/blink/renderer/core/dom/events/event.idl +++ b/third_party/blink/renderer/core/dom/events/event.idl
@@ -21,7 +21,7 @@ // https://dom.spec.whatwg.org/#interface-event [ - Exposed=(Window,Worker,AudioWorklet) + Exposed=(Window,Worker,AudioWorklet,ShadowRealm) // TODO(crbug.com/41480387): This should be Exposed=* ] interface Event { constructor(DOMString type, optional EventInit eventInitDict = {}); readonly attribute DOMString type;
diff --git a/third_party/blink/renderer/core/dom/events/event_listener.h b/third_party/blink/renderer/core/dom/events/event_listener.h index 373cf6e..c8ddba3 100644 --- a/third_party/blink/renderer/core/dom/events/event_listener.h +++ b/third_party/blink/renderer/core/dom/events/event_listener.h
@@ -22,7 +22,6 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_LISTENER_H_ #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/probe/async_task_context.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -85,11 +84,8 @@ virtual bool IsJSBasedEventListener() const { return false; } virtual bool IsNativeEventListener() const { return false; } - probe::AsyncTaskContext* async_task_context() { return &async_task_context_; } - private: EventListener() = default; - probe::AsyncTaskContext async_task_context_; // Only these two classes are direct subclasses of EventListener. Other // subclasses must inherit from either of them.
diff --git a/third_party/blink/renderer/core/dom/events/event_target.cc b/third_party/blink/renderer/core/dom/events/event_target.cc index 7d081b1..49f2d7f 100644 --- a/third_party/blink/renderer/core/dom/events/event_target.cc +++ b/third_party/blink/renderer/core/dom/events/event_target.cc
@@ -111,11 +111,6 @@ IsWheelScrollBlockingEvent(event_type); } -bool IsInstrumentedForAsyncStack(const AtomicString& event_type) { - return event_type == event_type_names::kLoad || - event_type == event_type_names::kError; -} - base::TimeDelta BlockedEventsWarningThreshold(ExecutionContext* context, const Event& event) { if (!event.cancelable()) @@ -673,11 +668,6 @@ } AddedEventListener(event_type, *registered_listener); - if (IsA<JSBasedEventListener>(listener) && - IsInstrumentedForAsyncStack(event_type)) { - listener->async_task_context()->Schedule(GetExecutionContext(), - event_type); - } } return added; } @@ -867,11 +857,6 @@ return false; } if (registered_listener) { - if (IsA<JSBasedEventListener>(listener) && - IsInstrumentedForAsyncStack(event_type)) { - listener->async_task_context()->Schedule(GetExecutionContext(), - event_type); - } registered_listener->SetCallback(listener); return true; } @@ -1103,9 +1088,6 @@ event.SetHandlingPassive(EventPassiveMode(*registered_listener)); probe::UserCallback probe(context, nullptr, event.type(), false, this); - probe::AsyncTask async_task(context, listener->async_task_context(), - "event", - IsInstrumentedForAsyncStack(event.type())); // To match Mozilla, the AT_TARGET phase fires both capturing and bubbling // event listeners, even though that violates some versions of the DOM spec.
diff --git a/third_party/blink/renderer/core/dom/events/event_target.idl b/third_party/blink/renderer/core/dom/events/event_target.idl index c85efe46..8eebe64 100644 --- a/third_party/blink/renderer/core/dom/events/event_target.idl +++ b/third_party/blink/renderer/core/dom/events/event_target.idl
@@ -26,7 +26,7 @@ }; [ - Exposed=(Window,Worker,AudioWorklet) + Exposed=(Window,Worker,AudioWorklet,ShadowRealm) // TODO(crbug.com/41480387): This should be Exposed=* ] interface EventTarget { [CallWith=ScriptState] constructor(); void addEventListener(DOMString type, EventListener? listener, optional (AddEventListenerOptions or boolean) options);
diff --git a/third_party/blink/renderer/core/dom/observable.idl b/third_party/blink/renderer/core/dom/observable.idl index 648c9ba..b4660e8 100644 --- a/third_party/blink/renderer/core/dom/observable.idl +++ b/third_party/blink/renderer/core/dom/observable.idl
@@ -45,7 +45,7 @@ typedef (ObserverCallback or Observer) ObserverUnion; typedef (ObserverCallback or ObservableInspector) ObservableInspectorUnion; -[Exposed=(Window,Worker), RuntimeEnabled=ObservableAPI] +[Exposed=(Window,Worker,ShadowRealm), RuntimeEnabled=ObservableAPI] // TODO(crbug.com/40282760): This should be Exposed=* interface Observable { [CallWith=ScriptState, MeasureAs=ObservableConstructor] constructor(SubscribeCallback callback); [CallWith=ScriptState] void subscribe(optional ObserverUnion observer = {}, optional SubscribeOptions options = {});
diff --git a/third_party/blink/renderer/core/dom/subscriber.idl b/third_party/blink/renderer/core/dom/subscriber.idl index 889cff6..197ed3ed 100644 --- a/third_party/blink/renderer/core/dom/subscriber.idl +++ b/third_party/blink/renderer/core/dom/subscriber.idl
@@ -4,7 +4,7 @@ // https://github.com/WICG/observable -[Exposed=(Window,Worker), RuntimeEnabled=ObservableAPI] +[Exposed=(Window,Worker,ShadowRealm), RuntimeEnabled=ObservableAPI] // TODO(crbug.com/40282760): This should be Exposed=* interface Subscriber { void next(any result); [CallWith=ScriptState] void error(any error);
diff --git a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc index a75a1d8..d2ce8672 100644 --- a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc +++ b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
@@ -218,9 +218,11 @@ } if (RuntimeEnabledFeatures::IncludeTableTagInExtendedSelectionEnabled()) { if (last_closed_ && IsTablePartElement(last_closed_)) { - last_closed_ = - Traversal<HTMLTableElement>::FirstAncestor(*last_closed_); - should_append_parent_tag = true; + if (auto* first_ancestor_table_traversal = + Traversal<HTMLTableElement>::FirstAncestor(*last_closed_)) { + last_closed_ = first_ancestor_table_traversal; + should_append_parent_tag = true; + } } } } @@ -304,7 +306,7 @@ if (ancestor == highest_node_to_be_serialized_) break; } - } else if (should_append_parent_tag) { + } else if (should_append_parent_tag && last_closed_) { EditingStyle* style = traverser.CreateInlineStyleIfNeeded(*last_closed_); traverser.WrapWithNode(To<ContainerNode>(*last_closed_), style); }
diff --git a/third_party/blink/renderer/core/events/error_event.idl b/third_party/blink/renderer/core/events/error_event.idl index d3e4362..cacba41 100644 --- a/third_party/blink/renderer/core/events/error_event.idl +++ b/third_party/blink/renderer/core/events/error_event.idl
@@ -31,7 +31,7 @@ // https://html.spec.whatwg.org/C/#the-errorevent-interface [ - Exposed=(Window,Worker) + Exposed=(Window,Worker,ShadowRealm) // TODO(crbug.com/41480387): This should be Exposed=* ] interface ErrorEvent : Event { [CallWith=ScriptState] constructor(DOMString type, optional ErrorEventInit eventInitDict = {}); readonly attribute DOMString message;
diff --git a/third_party/blink/renderer/core/events/promise_rejection_event.idl b/third_party/blink/renderer/core/events/promise_rejection_event.idl index bd64040d..2885d196 100644 --- a/third_party/blink/renderer/core/events/promise_rejection_event.idl +++ b/third_party/blink/renderer/core/events/promise_rejection_event.idl
@@ -5,7 +5,7 @@ // https://html.spec.whatwg.org/C/#promiserejectionevent [ - Exposed=(Window,Worker) + Exposed=(Window,Worker,ShadowRealm) // TODO(crbug.com/41480387): This should be Exposed=* ] interface PromiseRejectionEvent : Event { [CallWith=ScriptState] constructor(DOMString type, PromiseRejectionEventInit eventInitDict); [CallWith=ScriptState] readonly attribute Promise<any> promise;
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.cc b/third_party/blink/renderer/core/fetch/fetch_request_data.cc index 8e0104c..79d6efd5 100644 --- a/third_party/blink/renderer/core/fetch/fetch_request_data.cc +++ b/third_party/blink/renderer/core/fetch/fetch_request_data.cc
@@ -196,11 +196,6 @@ request->SetWindowId(fetch_api_request->fetch_window_id.value()); if (fetch_api_request->trust_token_params) { - if (script_state) { - // script state might be null for some tests - DCHECK(RuntimeEnabledFeatures::PrivateStateTokensEnabled( - ExecutionContext::From(script_state))); - } std::optional<network::mojom::blink::TrustTokenParams> trust_token_params = std::move(*(fetch_api_request->trust_token_params->Clone().get())); request->SetTrustTokenParams(trust_token_params);
diff --git a/third_party/blink/renderer/core/frame/build.gni b/third_party/blink/renderer/core/frame/build.gni index 43da1ba..b94981da 100644 --- a/third_party/blink/renderer/core/frame/build.gni +++ b/third_party/blink/renderer/core/frame/build.gni
@@ -91,6 +91,8 @@ "frame_view.h", "frame_view_auto_size_info.cc", "frame_view_auto_size_info.h", + "frame_visibility_observer.cc", + "frame_visibility_observer.h", "fullscreen_controller.cc", "fullscreen_controller.h", "history.cc",
diff --git a/third_party/blink/renderer/core/frame/frame_visibility_observer.cc b/third_party/blink/renderer/core/frame/frame_visibility_observer.cc new file mode 100644 index 0000000..303966b --- /dev/null +++ b/third_party/blink/renderer/core/frame/frame_visibility_observer.cc
@@ -0,0 +1,15 @@ +// 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/core/frame/frame_visibility_observer.h" + +#include "third_party/blink/renderer/core/frame/local_frame.h" + +namespace blink { + +FrameVisibilityObserver::FrameVisibilityObserver(LocalFrame* frame) { + frame->GetFrameVisibilityObserverSet().insert(this); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/frame_visibility_observer.h b/third_party/blink/renderer/core/frame/frame_visibility_observer.h new file mode 100644 index 0000000..8c53e25 --- /dev/null +++ b/third_party/blink/renderer/core/frame/frame_visibility_observer.h
@@ -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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_VISIBILITY_OBSERVER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_VISIBILITY_OBSERVER_H_ + +#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" + +namespace blink { + +class LocalFrame; + +// This is an observer to observe changes to the in-viewport visibility of a +// given frame. +class CORE_EXPORT FrameVisibilityObserver : public GarbageCollectedMixin { + public: + virtual ~FrameVisibilityObserver() = default; + + virtual void FrameVisibilityChanged(mojom::blink::FrameVisibility) = 0; + + protected: + explicit FrameVisibilityObserver(LocalFrame*); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_VISIBILITY_OBSERVER_H_
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 53ed7eae..30b4225 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -214,6 +214,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" #include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h" +#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/persistent.h" @@ -528,6 +529,7 @@ visitor->Trace(lcpp_); visitor->Trace(v8_local_compile_hints_producer_); visitor->Trace(browser_interface_broker_proxy_); + visitor->Trace(frame_visibility_observers_); #if !BUILDFLAG(IS_ANDROID) visitor->Trace(window_controls_overlay_changed_delegate_); #endif @@ -796,6 +798,8 @@ if (text_fragment_handler_) text_fragment_handler_->DidDetachDocumentOrFrame(); + frame_visibility_observers_.clear(); + not_restored_reasons_.reset(); DCHECK(!view_->IsAttached()); @@ -4163,4 +4167,18 @@ std::move(callback).Run(is_allowed); } +void LocalFrame::NotifyFrameVisibilityChanged( + mojom::blink::FrameVisibility visibility) { + HeapVector<Member<FrameVisibilityObserver>> + frame_visibility_observers_as_vector; + // Iterate on a copy of the vector to avoid invalidating the iterator if + // `FrameVisibilityChanged` happens to remove the observer from + // `frame_visibility_observers_`. + CopyToVector(frame_visibility_observers_, + frame_visibility_observers_as_vector); + for (auto observer : frame_visibility_observers_as_vector) { + observer->FrameVisibilityChanged(visibility); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index fb7996c..af3627c 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -79,6 +79,7 @@ #include "third_party/blink/renderer/core/frame/ad_script_identifier.h" #include "third_party/blink/renderer/core/frame/frame.h" #include "third_party/blink/renderer/core/frame/frame_types.h" +#include "third_party/blink/renderer/core/frame/frame_visibility_observer.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/loader/back_forward_cache_loader_helper_impl.h" #include "third_party/blink/renderer/core/loader/frame_loader.h" @@ -961,6 +962,13 @@ bool AllowStorageAccessSyncAndNotify( blink::WebContentSettingsClient::StorageType storage_type); + void NotifyFrameVisibilityChanged(mojom::blink::FrameVisibility visibility); + + HeapHashSet<WeakMember<FrameVisibilityObserver>>& + GetFrameVisibilityObserverSet() { + return frame_visibility_observers_; + } + private: friend class FrameNavigationDisabler; // LocalFrameMojoHandler is a part of LocalFrame. @@ -1234,6 +1242,8 @@ bool is_link_preivew_triggerer_initialized_ = false; std::unique_ptr<WebLinkPreviewTriggerer> link_preview_triggerer_; + HeapHashSet<WeakMember<FrameVisibilityObserver>> frame_visibility_observers_; + void OnStorageAccessCallback(base::OnceCallback<void(bool)> callback, mojom::blink::StorageTypeAccessed storage_type, bool isAllowed);
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index a719ef5..a177acf 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2326,7 +2326,7 @@ // RunPostLayoutIntersectionObserverSteps will return true if any // observations led to content-visibility intersection changing visibility // state synchronously (which happens on the first intersection - // observeration of a context). + // observation of a context). // // Note that we run the content-visibility intersection observation first. // The idea is that we want to synchronously determine the initial, @@ -4376,6 +4376,8 @@ frame_->Client()->GetWebFrame()->Client()->OnFrameVisibilityChanged( visibility); } + + frame_->NotifyFrameVisibilityChanged(visibility); } void LocalFrameView::RenderThrottlingStatusChanged() {
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h index 06ab196..01c0086 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h +++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
@@ -180,9 +180,7 @@ virtual SkColorInfo CanvasRenderingContextSkColorInfo() const = 0; virtual SkAlphaType GetAlphaType() const = 0; - SkColorType GetSkColorType() const { - return CanvasRenderingContextSkColorInfo().colorType(); - } + virtual SkColorType GetSkColorType() const = 0; virtual sk_sp<SkColorSpace> GetSkColorSpace() const = 0; virtual scoped_refptr<StaticBitmapImage> GetImage(FlushReason) = 0;
diff --git a/third_party/blink/renderer/core/html/html_script_element.cc b/third_party/blink/renderer/core/html/html_script_element.cc index 9e04983..e47cf6e 100644 --- a/third_party/blink/renderer/core/html/html_script_element.cc +++ b/third_party/blink/renderer/core/html/html_script_element.cc
@@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/loader/render_blocking_resource_manager.h" +#include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/script/script_loader.h" #include "third_party/blink/renderer/core/script/script_runner.h" #include "third_party/blink/renderer/core/script_type_names.h" @@ -54,7 +55,11 @@ : HTMLElement(html_names::kScriptTag, document), children_changed_by_api_(false), blocking_attribute_(MakeGarbageCollected<BlockingAttribute>(this)), - loader_(InitializeScriptLoader(flags)) {} + loader_(InitializeScriptLoader(flags)) { + if (!flags.IsCreatedByParser()) { + async_task_context_.Schedule(document.GetExecutionContext(), localName()); + } +} const AttrNameToTrustedType& HTMLScriptElement::GetCheckedAttributeTypes() const { @@ -335,10 +340,12 @@ } void HTMLScriptElement::DispatchLoadEvent() { + probe::AsyncTask async_task(GetExecutionContext(), &async_task_context_); DispatchEvent(*Event::Create(event_type_names::kLoad)); } void HTMLScriptElement::DispatchErrorEvent() { + probe::AsyncTask async_task(GetExecutionContext(), &async_task_context_); DispatchEvent(*Event::Create(event_type_names::kError)); }
diff --git a/third_party/blink/renderer/core/html/html_script_element.h b/third_party/blink/renderer/core/html/html_script_element.h index 8f6fedc6..e11ef446 100644 --- a/third_party/blink/renderer/core/html/html_script_element.h +++ b/third_party/blink/renderer/core/html/html_script_element.h
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/core/dom/create_element_flags.h" #include "third_party/blink/renderer/core/html/blocking_attribute.h" #include "third_party/blink/renderer/core/html/html_element.h" +#include "third_party/blink/renderer/core/probe/async_task_context.h" #include "third_party/blink/renderer/core/script/script_element_base.h" #include "third_party/blink/renderer/core/script/script_loader.h" #include "third_party/blink/renderer/platform/bindings/parkable_string.h" @@ -131,6 +132,8 @@ Member<BlockingAttribute> blocking_attribute_; Member<ScriptLoader> loader_; + + probe::AsyncTaskContext async_task_context_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/anchor_evaluator_impl.cc b/third_party/blink/renderer/core/layout/anchor_evaluator_impl.cc index 87287c9..35892ce8 100644 --- a/third_party/blink/renderer/core/layout/anchor_evaluator_impl.cc +++ b/third_party/blink/renderer/core/layout/anchor_evaluator_impl.cc
@@ -310,7 +310,12 @@ const PhysicalOffset& offset_to_padding_box, bool is_y_axis, bool is_right_or_bottom) const { - const PhysicalRect anchor = container_converter.ToPhysical(reference.rect); + PhysicalRect anchor_rect = container_converter.ToPhysical(reference.rect); + // Make the offset relative to the padding box, because the containing block + // is formed by the padding edge. + // https://www.w3.org/TR/CSS21/visudet.html#containing-block-details + anchor_rect.offset -= offset_to_padding_box; + anchor_value = PhysicalAnchorValueFromLogicalOrAuto( anchor_value, container_converter.GetWritingDirection(), self_writing_direction, is_y_axis); @@ -319,54 +324,45 @@ LayoutUnit value; switch (anchor_value) { case CSSAnchorValue::kCenter: { - const LayoutUnit start = is_y_axis - ? anchor.Y() - offset_to_padding_box.top - : anchor.X() - offset_to_padding_box.left; - const LayoutUnit end = is_y_axis - ? anchor.Bottom() - offset_to_padding_box.top - : anchor.Right() - offset_to_padding_box.left; + const LayoutUnit start = is_y_axis ? anchor_rect.Y() : anchor_rect.X(); + const LayoutUnit end = + is_y_axis ? anchor_rect.Bottom() : anchor_rect.Right(); value = start + LayoutUnit::FromFloatRound((end - start) * 0.5); break; } case CSSAnchorValue::kLeft: if (is_y_axis) return std::nullopt; // Wrong axis. - // Make the offset relative to the padding box, because the containing - // block is formed by the padding edge. - // https://www.w3.org/TR/CSS21/visudet.html#containing-block-details - value = anchor.X() - offset_to_padding_box.left; + value = anchor_rect.X(); break; case CSSAnchorValue::kRight: if (is_y_axis) return std::nullopt; // Wrong axis. - // See |CSSAnchorValue::kLeft|. - value = anchor.Right() - offset_to_padding_box.left; + value = anchor_rect.Right(); break; case CSSAnchorValue::kTop: if (!is_y_axis) return std::nullopt; // Wrong axis. - // See |CSSAnchorValue::kLeft|. - value = anchor.Y() - offset_to_padding_box.top; + value = anchor_rect.Y(); break; case CSSAnchorValue::kBottom: if (!is_y_axis) return std::nullopt; // Wrong axis. - // See |CSSAnchorValue::kLeft|. - value = anchor.Bottom() - offset_to_padding_box.top; + value = anchor_rect.Bottom(); break; case CSSAnchorValue::kPercentage: { LayoutUnit size; if (is_y_axis) { - value = anchor.Y() - offset_to_padding_box.top; - size = anchor.Height(); + value = anchor_rect.Y(); + size = anchor_rect.Height(); // The percentage is logical, between the `start` and `end` sides. // Convert to the physical percentage. // https://drafts.csswg.org/css-anchor-1/#anchor-pos if (container_converter.GetWritingDirection().IsFlippedY()) percentage = 100 - percentage; } else { - value = anchor.X() - offset_to_padding_box.left; - size = anchor.Width(); + value = anchor_rect.X(); + size = anchor_rect.Width(); // Convert the logical percentage to physical. See above. if (container_converter.GetWritingDirection().IsFlippedX()) percentage = 100 - percentage;
diff --git a/third_party/blink/renderer/core/layout/box_fragment_builder.h b/third_party/blink/renderer/core/layout/box_fragment_builder.h index d1ab545..d530700 100644 --- a/third_party/blink/renderer/core/layout/box_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/box_fragment_builder.h
@@ -16,6 +16,7 @@ #include "third_party/blink/renderer/core/layout/flex/devtools_flex_info.h" #include "third_party/blink/renderer/core/layout/fragment_builder.h" #include "third_party/blink/renderer/core/layout/frame_set_layout_data.h" +#include "third_party/blink/renderer/core/layout/gap_fragment_data.h" #include "third_party/blink/renderer/core/layout/geometry/box_sides.h" #include "third_party/blink/renderer/core/layout/geometry/box_strut.h" #include "third_party/blink/renderer/core/layout/geometry/fragment_geometry.h" @@ -574,6 +575,11 @@ use_last_baseline_for_inline_baseline_ = true; } + void SetGapGeometry( + std::unique_ptr<GapFragmentData::GapGeometry> gap_geometry) { + gap_geometry_ = std::move(gap_geometry); + } + void SetTableGridRect(const LogicalRect& table_grid_rect) { table_grid_rect_ = table_grid_rect; } @@ -750,6 +756,8 @@ std::optional<LayoutUnit> last_baseline_; LayoutUnit math_italic_correction_; + std::unique_ptr<GapFragmentData::GapGeometry> gap_geometry_; + // Table specific types. std::optional<LogicalRect> table_grid_rect_; TableFragmentData::ColumnGeometries table_column_geometries_;
diff --git a/third_party/blink/renderer/core/layout/build.gni b/third_party/blink/renderer/core/layout/build.gni index d40038d..e73db76 100644 --- a/third_party/blink/renderer/core/layout/build.gni +++ b/third_party/blink/renderer/core/layout/build.gni
@@ -150,6 +150,7 @@ "frame_set_layout_algorithm.cc", "frame_set_layout_algorithm.h", "frame_set_layout_data.h", + "gap_fragment_data.h", "generated_children.h", "geometry/axis.h", "geometry/bfc_offset.cc",
diff --git a/third_party/blink/renderer/core/layout/exclusions/exclusion_area.cc b/third_party/blink/renderer/core/layout/exclusions/exclusion_area.cc index 3feafc1d..c6ef93ec 100644 --- a/third_party/blink/renderer/core/layout/exclusions/exclusion_area.cc +++ b/third_party/blink/renderer/core/layout/exclusions/exclusion_area.cc
@@ -26,14 +26,13 @@ }; std::ostream& operator<<(std::ostream& os, const PrintableEFloat& printable) { - const char* kStrings[] = { + std::array<const char*, 5> kStrings = { "kNone", "kLeft", "kRight", "kInlineStart", "kInlineEnd", }; const unsigned index = static_cast<unsigned>(printable.value); if (index >= std::size(kStrings)) return os << "EFloat::" << index; - // TODO(crbug.com/351564777): Resolve a buffer safety issue. - return os << "EFloat::" << UNSAFE_TODO(kStrings[index]); + return os << "EFloat::" << kStrings[index]; } struct PrintableKind { @@ -42,15 +41,14 @@ }; std::ostream& operator<<(std::ostream& os, const PrintableKind& printable) { - const char* kStrings[] = { + std::array<const char*, 2> kStrings = { "kFloat", "kInitialLetterBox", }; const unsigned index = static_cast<unsigned>(printable.value); if (index >= std::size(kStrings)) return os << "Kind::" << index; - // TODO(crbug.com/351564777): Resolve a buffer safety issue. - return os << UNSAFE_TODO(kStrings[index]); + return os << kStrings[index]; } } // namespace
diff --git a/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.cc b/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.cc index 14a69f14..c695b35 100644 --- a/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.cc +++ b/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.cc
@@ -117,31 +117,27 @@ } else { position = style.ResolvedJustifyContentPosition(ContentAlignmentNormalBehavior()); - } - if (position == ContentPosition::kLeft || - position == ContentPosition::kRight) { - if (IsColumnFlow(style)) { - if (style.IsHorizontalWritingMode()) { - // Main axis is perpendicular to both the physical left<->right and - // inline start<->end axes, so kLeft and kRight behave as kStart. - position = ContentPosition::kStart; - } else if ((position == ContentPosition::kLeft && - style.IsFlippedBlocksWritingMode()) || - (position == ContentPosition::kRight && - style.GetWritingDirection().BlockEnd() == - PhysicalDirection::kRight)) { - position = ContentPosition::kEnd; + + const auto writing_direction = style.GetWritingDirection(); + if (position == ContentPosition::kLeft || + position == ContentPosition::kRight) { + if (IsColumnFlow(style)) { + if (writing_direction.IsHorizontal()) { + // The main-axis is in the top-down direction, fallback to start. + position = ContentPosition::kStart; + } else { + LogicalToPhysical physical( + writing_direction, ContentPosition::kStart, ContentPosition::kEnd, + ContentPosition::kStart, ContentPosition::kEnd); + position = position == ContentPosition::kLeft ? physical.Left() + : physical.Right(); + } } else { - position = ContentPosition::kStart; + position = + ((position == ContentPosition::kLeft) == writing_direction.IsLtr()) + ? ContentPosition::kStart + : ContentPosition::kEnd; } - } else if ((position == ContentPosition::kLeft && - !style.IsLeftToRightDirection()) || - (position == ContentPosition::kRight && - style.IsLeftToRightDirection())) { - DCHECK(!FlexibleBoxAlgorithm::IsColumnFlow(style)); - position = ContentPosition::kEnd; - } else { - position = ContentPosition::kStart; } } DCHECK_NE(position, ContentPosition::kLeft); @@ -197,14 +193,10 @@ return ItemPosition::kFlexEnd; if (align == ItemPosition::kSelfStart || align == ItemPosition::kSelfEnd) { - LogicalToPhysical<ItemPosition> physical( - child_style.GetWritingDirection(), ItemPosition::kFlexStart, - ItemPosition::kFlexEnd, ItemPosition::kFlexStart, - ItemPosition::kFlexEnd); - - PhysicalToLogical<ItemPosition> logical(flexbox_style.GetWritingDirection(), - physical.Top(), physical.Right(), - physical.Bottom(), physical.Left()); + LogicalToLogical<ItemPosition> logical( + child_style.GetWritingDirection(), flexbox_style.GetWritingDirection(), + ItemPosition::kFlexStart, ItemPosition::kFlexEnd, + ItemPosition::kFlexStart, ItemPosition::kFlexEnd); if (flexbox_style.ResolvedIsColumnFlexDirection()) { return align == ItemPosition::kSelfStart ? logical.InlineStart()
diff --git a/third_party/blink/renderer/core/layout/gap_fragment_data.h b/third_party/blink/renderer/core/layout/gap_fragment_data.h new file mode 100644 index 0000000..45efe94 --- /dev/null +++ b/third_party/blink/renderer/core/layout/gap_fragment_data.h
@@ -0,0 +1,64 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GAP_FRAGMENT_DATA_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GAP_FRAGMENT_DATA_H_ + +#include <optional> + +#include "third_party/blink/renderer/platform/geometry/layout_unit.h" +#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" + +namespace blink { + +class GapFragmentData { + public: + // GapBoundary represents the start and end offsets of a single gap. + // A fragment can contain the start offset, the end offset, or both, + // indicating the boundaries of the gap. When a grid container is fragmented, + // it is possible to have only the start/end offsets for a given row gap in a + // fragment. Example: Consider a grid container fragmented into two parts. The + // gap between rows might be represented as follows: + // + // Fragment 1: Fragment 2: + // +-----------------+ +-------------------+ + // | Item 1| |Item 2 | | | + // | | | | | Gap End | + // |_______| |_______| |________ ________| + // | Gap Start | | Item 3 | | Item 4 | + // | | | | | | + // +-----------------+ +-------------------+ + struct GapBoundary { + DISALLOW_NEW(); + + public: + GapBoundary(wtf_size_t index, + std::optional<LayoutUnit> start_offset = std::nullopt, + std::optional<LayoutUnit> end_offset = std::nullopt) + : index(index), start_offset(start_offset), end_offset(end_offset) {} + + wtf_size_t index; + std::optional<LayoutUnit> start_offset; + std::optional<LayoutUnit> end_offset; + }; + + using GapBoundaries = HeapVector<GapBoundary>; + + // Gap locations are used for painting gap decorations. + struct GapGeometry { + USING_FAST_MALLOC(GapGeometry); + + public: + GapBoundaries columns; + GapBoundaries rows; + + void Trace(Visitor* visitor) const { + visitor->Trace(rows); + visitor->Trace(columns); + } + }; +}; + +} // namespace blink +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GAP_DECORATIONS_FRAGMENT_GEOMETRY_H_
diff --git a/third_party/blink/renderer/core/layout/inline/offset_mapping.cc b/third_party/blink/renderer/core/layout/inline/offset_mapping.cc index 6c8f995..0db5a53 100644 --- a/third_party/blink/renderer/core/layout/inline/offset_mapping.cc +++ b/third_party/blink/renderer/core/layout/inline/offset_mapping.cc
@@ -297,15 +297,15 @@ if (range_start == range_end || units_[range_start].DOMStart() > offset) return nullptr; // Find the last unit where unit.dom_start <= offset - // TODO(crbug.com/351564777): Resolve a buffer safety issue. - auto unit = std::prev(UNSAFE_TODO(std::upper_bound( - units_.begin() + range_start, units_.begin() + range_end, offset, - [](unsigned offset, const OffsetMappingUnit& unit) { + auto range = base::span(units_).subspan(range_start, range_end - range_start); + auto i = base::ranges::upper_bound( + range, offset, [](unsigned offset, const OffsetMappingUnit& unit) { return offset < unit.DOMStart(); - }))); + }); + const OffsetMappingUnit* unit = &range[std::distance(range.begin(), i) - 1]; if (unit->DOMEnd() < offset) return nullptr; - return &*unit; + return unit; } OffsetMapping::UnitVector OffsetMapping::GetMappingUnitsForDOMRange( @@ -328,25 +328,30 @@ return UnitVector(); // Find the first unit where unit.dom_end >= start_offset - // TODO(crbug.com/351564777): Resolve a buffer safety issue. - auto result_begin = UNSAFE_TODO(std::lower_bound( - units_.begin() + range_start, units_.begin() + range_end, start_offset, - [](const OffsetMappingUnit& unit, unsigned offset) { - return unit.DOMEnd() < offset; - })); + auto span1 = base::span(units_).subspan(range_start, range_end - range_start); + size_t result_begin = + range_start + + std::distance(span1.begin(), + base::ranges::lower_bound( + span1, start_offset, + [](const OffsetMappingUnit& unit, unsigned offset) { + return unit.DOMEnd() < offset; + })); // Find the next of the last unit where unit.dom_start <= end_offset - // TODO(crbug.com/351564777): Resolve a buffer safety issue. - auto result_end = UNSAFE_TODO( - std::upper_bound(result_begin, units_.begin() + range_end, end_offset, - [](unsigned offset, const OffsetMappingUnit& unit) { - return offset < unit.DOMStart(); - })); + auto span2 = + base::span(units_).subspan(result_begin, range_end - result_begin); + size_t result_size = std::distance( + span2.begin(), base::ranges::upper_bound( + span2, end_offset, + [](unsigned offset, const OffsetMappingUnit& unit) { + return offset < unit.DOMStart(); + })); UnitVector result; - result.reserve(base::checked_cast<wtf_size_t>(result_end - result_begin)); - // TODO(crbug.com/351564777): Resolve a buffer safety issue. - for (const auto& unit : UNSAFE_TODO(base::span(result_begin, result_end))) { + result.reserve(base::checked_cast<wtf_size_t>(result_size)); + for (const auto& unit : + base::span(units_).subspan(result_begin, result_size)) { // If the unit isn't fully within the range, create a new unit that's // within the range. const unsigned clamped_start = std::max(unit.DOMStart(), start_offset);
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 108dc1d..1e6c63c 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -2697,8 +2697,6 @@ void LayoutBox::RebuildFragmentTreeSpine() { DCHECK(PhysicalFragmentCount()); - SCOPED_BLINK_UMA_HISTOGRAM_TIMER_HIGHRES( - "Blink.Layout.RebuildFragmentTreeSpine"); // If this box has an associated layout-result, rebuild the spine of the // fragment-tree to ensure consistency. LayoutBox* container = this;
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 846d6d45..486ac54 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -758,6 +758,17 @@ children->RemoveChildNode(this, old_child); } +bool LayoutObject::IsInTopOrViewTransitionLayer() const { + NOT_DESTROYED(); + if (IsViewTransitionRoot()) { + return true; + } + if (Element* element = DynamicTo<Element>(GetNode())) { + return StyleRef().IsRenderedInTopLayer(*element); + } + return false; +} + void LayoutObject::NotifyPriorityScrollAnchorStatusChanged() { NOT_DESTROYED(); if (!Parent())
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index 40314c8..524b763e 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -732,16 +732,7 @@ // Returns true if the LayoutObject is rendered in the top layer or the layer // for view transitions. Such objects are rendered as subsequent siblings of // the root element box and have specific stacking requirements. - bool IsInTopOrViewTransitionLayer() const { - NOT_DESTROYED(); - if (IsViewTransitionRoot()) { - return true; - } - if (Element* element = DynamicTo<Element>(GetNode())) { - return StyleRef().IsRenderedInTopLayer(*element); - } - return false; - } + bool IsInTopOrViewTransitionLayer() const; void NotifyPriorityScrollAnchorStatusChanged();
diff --git a/third_party/blink/renderer/core/layout/physical_box_fragment.cc b/third_party/blink/renderer/core/layout/physical_box_fragment.cc index f2fe692..d3b2569 100644 --- a/third_party/blink/renderer/core/layout/physical_box_fragment.cc +++ b/third_party/blink/renderer/core/layout/physical_box_fragment.cc
@@ -334,7 +334,7 @@ has_scrollable_overflow + !!builder->frame_set_layout_data_ + !!builder->mathml_paint_info_ + !!builder->table_grid_rect_ + !!builder->table_collapsed_borders_ + - !!builder->table_collapsed_borders_geometry_ + + !!builder->table_collapsed_borders_geometry_ + !!builder->gap_geometry_ + !!builder->table_cell_column_index_ + (builder->table_section_row_offsets_.empty() ? 0 : 2) + !!builder->page_name_ + !!borders + !!scrollbar + !!padding +
diff --git a/third_party/blink/renderer/core/layout/physical_box_fragment.h b/third_party/blink/renderer/core/layout/physical_box_fragment.h index 5bc6cdfa..60ae7dfb 100644 --- a/third_party/blink/renderer/core/layout/physical_box_fragment.h +++ b/third_party/blink/renderer/core/layout/physical_box_fragment.h
@@ -10,6 +10,7 @@ #include "base/dcheck_is_on.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/layout/block_break_token.h" +#include "third_party/blink/renderer/core/layout/gap_fragment_data.h" #include "third_party/blink/renderer/core/layout/geometry/box_sides.h" #include "third_party/blink/renderer/core/layout/geometry/box_strut.h" #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h" @@ -171,6 +172,13 @@ !Style().ShouldIgnoreOverflowPropertyForInlineBlockBaseline(); } + const GapFragmentData::GapGeometry* GapGeometry() const { + if (const auto* field = GetRareField(FieldId::kGapGeometry)) { + return field->gap_geometry.get(); + } + return nullptr; + } + LogicalRect TableGridRect() const { return rare_data_->GetField(FieldId::kTableGridRect)->table_grid_rect; }
diff --git a/third_party/blink/renderer/core/layout/physical_fragment_rare_data.cc b/third_party/blink/renderer/core/layout/physical_fragment_rare_data.cc index ac215f8..11297f4a 100644 --- a/third_party/blink/renderer/core/layout/physical_fragment_rare_data.cc +++ b/third_party/blink/renderer/core/layout/physical_fragment_rare_data.cc
@@ -53,6 +53,10 @@ SetField(FieldId::kFrameSetLayoutData).frame_set_layout_data = std::move(builder.frame_set_layout_data_); } + if (builder.gap_geometry_) { + SetField(FieldId::kGapGeometry).gap_geometry = + std::move(builder.gap_geometry_); + } if (builder.table_grid_rect_) { SetField(FieldId::kTableGridRect).table_grid_rect = *builder.table_grid_rect_; @@ -112,6 +116,7 @@ SET_IF_EXISTS(kPadding, padding, other); SET_IF_EXISTS(kInflowBounds, inflow_bounds, other); CLONE_IF_EXISTS(kFrameSetLayoutData, frame_set_layout_data, other); + CLONE_IF_EXISTS(kGapGeometry, gap_geometry, other); SET_IF_EXISTS(kTableGridRect, table_grid_rect, other); CLONE_IF_EXISTS(kTableCollapsedBordersGeometry, table_collapsed_borders_geometry, other); @@ -147,6 +152,7 @@ FUNC(kTableSectionRowOffsets, table_section_row_offsets); \ FUNC(kPageName, page_name); \ FUNC(kMargins, margins); \ + FUNC(kGapGeometry, gap_geometry); \ } #define CONSTRUCT_UNION_MEMBER(id, name) \
diff --git a/third_party/blink/renderer/core/layout/physical_fragment_rare_data.h b/third_party/blink/renderer/core/layout/physical_fragment_rare_data.h index e73c984..adae6cd3 100644 --- a/third_party/blink/renderer/core/layout/physical_fragment_rare_data.h +++ b/third_party/blink/renderer/core/layout/physical_fragment_rare_data.h
@@ -7,6 +7,7 @@ #include <climits> +#include "third_party/blink/renderer/core/layout/gap_fragment_data.h" #include "third_party/blink/renderer/core/layout/geometry/logical_rect.h" #include "third_party/blink/renderer/core/layout/table/table_fragment_data.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -73,8 +74,9 @@ kTableSectionRowOffsets, kPageName, kMargins, + kGapGeometry, - kMaxValue = kMargins, + kMaxValue = kGapGeometry, }; static_assert(sizeof(RareBitFieldType) * CHAR_BIT > static_cast<unsigned>(FieldId::kMaxValue), @@ -92,6 +94,7 @@ scoped_refptr<const TableBorders> table_collapsed_borders; std::unique_ptr<TableFragmentData::CollapsedBordersGeometry> table_collapsed_borders_geometry; + std::unique_ptr<GapFragmentData::GapGeometry> gap_geometry; wtf_size_t table_cell_column_index; wtf_size_t table_section_start_row_index; Vector<LayoutUnit> table_section_row_offsets;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc index fe74f9c..3b7a5fc 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
@@ -91,13 +91,17 @@ gfx::RectF LayoutSVGInline::ObjectBoundingBox() const { NOT_DESTROYED(); - gfx::RectF bounds; - if (IsInLayoutNGInlineFormattingContext()) { - InlineCursor cursor; - cursor.MoveToIncludingCulledInline(*this); - ObjectBoundingBoxForCursor(cursor, bounds); + if (!RuntimeEnabledFeatures::SvgTspanBboxCacheEnabled() || + needs_update_bounding_box_) { + needs_update_bounding_box_ = false; + bounding_box_ = gfx::RectF(); + if (IsInLayoutNGInlineFormattingContext()) { + InlineCursor cursor; + cursor.MoveToIncludingCulledInline(*this); + ObjectBoundingBoxForCursor(cursor, bounding_box_); + } } - return bounds; + return bounding_box_; } gfx::RectF LayoutSVGInline::DecoratedBoundingBox() const {
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h index 69eb19a0..827a10c 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
@@ -65,6 +65,11 @@ const PhysicalOffset& additional_offset, OutlineType) const final; + void InvalidateObjectBoundingBox() { + NOT_DESTROYED(); + needs_update_bounding_box_ = true; + } + private: void WillBeDestroyed() final; void StyleDidChange(StyleDifference, const ComputedStyle* old_style) final; @@ -76,10 +81,18 @@ void InsertedIntoTree() override; void WillBeRemovedFromTree() override; + // Return true if this can have an object bounding box. + // bounding_box_ can be dirty even if this flag is true. bool IsObjectBoundingBoxValid() const; static void ObjectBoundingBoxForCursor(InlineCursor& cursor, gfx::RectF& bounds); + + // `bounding_box_` and `needs_update_bounding_box_` are mutable for + // on-demand computation of bounding_box_. + mutable gfx::RectF bounding_box_; + // True if we need to update bounding_box_. + mutable bool needs_update_bounding_box_ = true; }; template <>
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc index 31d741e4..151c2db 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
@@ -11,6 +11,7 @@ #include "third_party/blink/renderer/core/layout/constraint_space_builder.h" #include "third_party/blink/renderer/core/layout/inline/fragment_item.h" #include "third_party/blink/renderer/core/layout/physical_box_fragment.h" +#include "third_party/blink/renderer/core/layout/svg/layout_svg_inline.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h" @@ -245,6 +246,9 @@ BlockNode(this).Layout(builder.ToConstraintSpace()); needs_update_bounding_box_ = true; + if (RuntimeEnabledFeatures::SvgTspanBboxCacheEnabled()) { + InvalidateDescendantObjectBoundingBoxes(); + } const gfx::RectF boundaries = ObjectBoundingBox(); const bool bounds_changed = old_boundaries != boundaries; @@ -406,6 +410,16 @@ return needs_text_metrics_update_; } +void LayoutSVGText::InvalidateDescendantObjectBoundingBoxes() { + NOT_DESTROYED(); + for (LayoutObject* object = NextInPreOrder(this); object; + object = object->NextInPreOrder(this)) { + if (auto* svg_inline = DynamicTo<LayoutSVGInline>(object)) { + svg_inline->InvalidateObjectBoundingBox(); + } + } +} + LayoutSVGText* LayoutSVGText::LocateLayoutSVGTextAncestor(LayoutObject* start) { return const_cast<LayoutSVGText*>(FindTextRoot(start)); }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_text.h b/third_party/blink/renderer/core/layout/svg/layout_svg_text.h index be05650b..8143fc6f 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_text.h +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_text.h
@@ -74,6 +74,7 @@ void UpdateFont(); void UpdateTransformAffectsVectorEffect(); + void InvalidateDescendantObjectBoundingBoxes(); // bounding_box_* are mutable for on-demand computation in a const method. mutable gfx::RectF bounding_box_;
diff --git a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc index 852814c9..69c5eb36 100644 --- a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc +++ b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
@@ -506,9 +506,6 @@ if (trial_name == "AdInterestGroupAPI") return base::FeatureList::IsEnabled(features::kInterestGroupStorage); - if (trial_name == "TrustTokens") - return base::FeatureList::IsEnabled(network::features::kFledgePst); - if (trial_name == "SpeculationRulesPrefetchFuture") { return base::FeatureList::IsEnabled( features::kSpeculationRulesPrefetchFuture);
diff --git a/third_party/blink/renderer/core/page/focus_controller.cc b/third_party/blink/renderer/core/page/focus_controller.cc index 924f171..38f4356 100644 --- a/third_party/blink/renderer/core/page/focus_controller.cc +++ b/third_party/blink/renderer/core/page/focus_controller.cc
@@ -1782,12 +1782,12 @@ return true; } -Element* FocusController::FindFocusableElement(mojom::blink::FocusType type, - Element& element, - OwnerMap& owner_map) { - // FIXME: No spacial navigation code yet. - DCHECK(type == mojom::blink::FocusType::kForward || - type == mojom::blink::FocusType::kBackward); +Element* FocusController::FindFocusableElementForImeAutofillAndTesting( + mojom::blink::FocusType type, + Element& element, + OwnerMap& owner_map) { + CHECK(type == mojom::blink::FocusType::kForward || + type == mojom::blink::FocusType::kBackward); ScopedFocusNavigation scope = ScopedFocusNavigation::CreateFor(element, owner_map); return FindFocusableElementAcrossFocusScopes(type, scope, owner_map); @@ -1795,7 +1795,7 @@ Element* FocusController::NextFocusableElementForImeAndAutofill( Element* element, - mojom::blink::FocusType focus_type) { + const mojom::blink::FocusType focus_type) { // TODO(ajith.v) Due to crbug.com/781026 when next/previous element is far // from current element in terms of tabindex, then it's signalling CPU load. // Will investigate further for a proper solution later. @@ -1816,11 +1816,12 @@ form_owner = form_control_element->formOwner(); OwnerMap owner_map; - Element* next_element = FindFocusableElement(focus_type, *element, owner_map); + Element* next_element = FindFocusableElementForImeAutofillAndTesting( + focus_type, *element, owner_map); int traversal = 0; for (; next_element && traversal < kFocusTraversalThreshold; - next_element = - FindFocusableElement(focus_type, *next_element, owner_map), + next_element = FindFocusableElementForImeAutofillAndTesting( + focus_type, *next_element, owner_map), ++traversal) { auto* next_html_element = DynamicTo<HTMLElement>(next_element); if (!next_html_element) @@ -1913,18 +1914,6 @@ return nullptr; } -Element* FocusController::FindFocusableElementAfter( - Element& element, - mojom::blink::FocusType type) { - if (type != mojom::blink::FocusType::kForward && - type != mojom::blink::FocusType::kBackward) - return nullptr; - element.GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kFocus); - - OwnerMap owner_map; - return FindFocusableElement(type, element, owner_map); -} - static bool RelinquishesEditingFocus(const Element& element) { DCHECK(IsEditable(element)); return element.GetDocument().GetFrame() && RootEditableElement(element);
diff --git a/third_party/blink/renderer/core/page/focus_controller.h b/third_party/blink/renderer/core/page/focus_controller.h index 7ee1ac1..65f9d74 100644 --- a/third_party/blink/renderer/core/page/focus_controller.h +++ b/third_party/blink/renderer/core/page/focus_controller.h
@@ -98,7 +98,9 @@ // next focusable element. Element* NextFocusableElementForImeAndAutofill(Element*, mojom::blink::FocusType); - Element* FindFocusableElementAfter(Element& element, mojom::blink::FocusType); + Element* FindFocusableElementForImeAutofillAndTesting(mojom::blink::FocusType, + Element&, + OwnerMap&); bool SetFocusedElement(Element*, Frame*, const FocusParams&); // |setFocusedElement| variant with SelectionBehaviorOnFocus::None, @@ -120,8 +122,6 @@ void Trace(Visitor*) const; private: - Element* FindFocusableElement(mojom::blink::FocusType, Element&, OwnerMap&); - bool AdvanceFocus(mojom::blink::FocusType, bool initial_focus, InputDeviceCapabilities* source_capabilities = nullptr);
diff --git a/third_party/blink/renderer/core/page/focus_controller_test.cc b/third_party/blink/renderer/core/page/focus_controller_test.cc index 5ef7908..d26e5de5 100644 --- a/third_party/blink/renderer/core/page/focus_controller_test.cc +++ b/third_party/blink/renderer/core/page/focus_controller_test.cc
@@ -22,6 +22,19 @@ namespace blink { class FocusControllerTest : public PageTestBase { + public: + Element* FindFocusableElementAfter(Element& element, + mojom::blink::FocusType type) { + if (type != mojom::blink::FocusType::kForward && + type != mojom::blink::FocusType::kBackward) { + return nullptr; + } + element.GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kFocus); + FocusController::OwnerMap owner_map; + return GetFocusController().FindFocusableElementForImeAutofillAndTesting( + type, element, owner_map); + } + private: void SetUp() override { PageTestBase::SetUp(gfx::Size()); } }; @@ -121,26 +134,26 @@ Element* second = GetElementById("second"); Element* third = GetElementById("third"); Element* fourth = GetElementById("fourth"); - EXPECT_EQ(third, GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(third, FindFocusableElementAfter( *first, mojom::blink::FocusType::kForward)); - EXPECT_EQ(third, GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(third, FindFocusableElementAfter( *second, mojom::blink::FocusType::kForward)); - EXPECT_EQ(fourth, GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(fourth, FindFocusableElementAfter( *third, mojom::blink::FocusType::kForward)); - EXPECT_EQ(nullptr, GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(nullptr, FindFocusableElementAfter( *fourth, mojom::blink::FocusType::kForward)); - EXPECT_EQ(nullptr, GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(nullptr, FindFocusableElementAfter( *first, mojom::blink::FocusType::kBackward)); - EXPECT_EQ(first, GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(first, FindFocusableElementAfter( *second, mojom::blink::FocusType::kBackward)); - EXPECT_EQ(first, GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(first, FindFocusableElementAfter( *third, mojom::blink::FocusType::kBackward)); - EXPECT_EQ(third, GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(third, FindFocusableElementAfter( *fourth, mojom::blink::FocusType::kBackward)); - EXPECT_EQ(nullptr, GetFocusController().FindFocusableElementAfter( - *first, mojom::blink::FocusType::kNone)); + EXPECT_EQ(nullptr, + FindFocusableElementAfter(*first, mojom::blink::FocusType::kNone)); } TEST_F(FocusControllerTest, NextFocusableElementForImeAndAutofill) { @@ -486,11 +499,11 @@ post_input}; for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i + 1], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i + 1], FindFocusableElementAfter( *order[i], mojom::blink::FocusType::kForward)); } for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i], FindFocusableElementAfter( *order[i + 1], mojom::blink::FocusType::kBackward)); } @@ -502,14 +515,12 @@ const auto* style = before_second_scroll_marker->GetComputedStyle(); EXPECT_TRUE(before_second_scroll_marker->IsFocused()); EXPECT_EQ(0.5, style->Opacity()); - EXPECT_EQ( - before_second_scroll_marker, - GetFocusController().FindFocusableElementAfter( - *before_scroll_marker_group, mojom::blink::FocusType::kForward)); - EXPECT_EQ( - before_block_start_button, - GetFocusController().FindFocusableElementAfter( - *before_second_scroll_marker, mojom::blink::FocusType::kForward)); + EXPECT_EQ(before_second_scroll_marker, + FindFocusableElementAfter(*before_scroll_marker_group, + mojom::blink::FocusType::kForward)); + EXPECT_EQ(before_block_start_button, + FindFocusableElementAfter(*before_second_scroll_marker, + mojom::blink::FocusType::kForward)); } TEST_F(FocusControllerTest, CarouselWithOnlyButtonsFocusOrder) { @@ -590,11 +601,11 @@ post_input}; for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i + 1], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i + 1], FindFocusableElementAfter( *order[i], mojom::blink::FocusType::kForward)); } for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i], FindFocusableElementAfter( *order[i + 1], mojom::blink::FocusType::kBackward)); } @@ -670,11 +681,11 @@ post_input}; for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i + 1], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i + 1], FindFocusableElementAfter( *order[i], mojom::blink::FocusType::kForward)); } for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i], FindFocusableElementAfter( *order[i + 1], mojom::blink::FocusType::kBackward)); } } @@ -730,11 +741,11 @@ post_input}; for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i + 1], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i + 1], FindFocusableElementAfter( *order[i], mojom::blink::FocusType::kForward)); } for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i], FindFocusableElementAfter( *order[i + 1], mojom::blink::FocusType::kBackward)); } } @@ -771,11 +782,11 @@ after_scroller, after_scroll_marker_group, post_input}; for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i + 1], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i + 1], FindFocusableElementAfter( *order[i], mojom::blink::FocusType::kForward)); } for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i], FindFocusableElementAfter( *order[i + 1], mojom::blink::FocusType::kBackward)); } } @@ -880,11 +891,11 @@ post_input}; for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i + 1], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i + 1], FindFocusableElementAfter( *order[i], mojom::blink::FocusType::kForward)); } for (std::size_t i = 0u; i < order.size() - 1; ++i) { - EXPECT_EQ(order[i], GetFocusController().FindFocusableElementAfter( + EXPECT_EQ(order[i], FindFocusableElementAfter( *order[i + 1], mojom::blink::FocusType::kBackward)); } }
diff --git a/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.idl b/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.idl index 4010a9f..1456cdf 100644 --- a/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.idl +++ b/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.idl
@@ -5,7 +5,7 @@ // https://streams.spec.whatwg.org/#blqs-class [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface ByteLengthQueuingStrategy { [CallWith=ScriptState, MeasureAs=ByteLengthQueuingStrategyConstructor] constructor(QueuingStrategyInit init); readonly attribute unrestricted double highWaterMark;
diff --git a/third_party/blink/renderer/core/streams/count_queuing_strategy.idl b/third_party/blink/renderer/core/streams/count_queuing_strategy.idl index a0b8ded..5d47e8f 100644 --- a/third_party/blink/renderer/core/streams/count_queuing_strategy.idl +++ b/third_party/blink/renderer/core/streams/count_queuing_strategy.idl
@@ -5,7 +5,7 @@ // https://streams.spec.whatwg.org/#cqs-class [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface CountQueuingStrategy { [CallWith=ScriptState, MeasureAs=CountQueuingStrategyConstructor] constructor(QueuingStrategyInit init); readonly attribute unrestricted double highWaterMark;
diff --git a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.idl b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.idl index 30ee973..d4ba351 100644 --- a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.idl +++ b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.idl
@@ -4,7 +4,7 @@ // https://streams.spec.whatwg.org/#rbs-controller-class-definition [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface ReadableByteStreamController { readonly attribute ReadableStreamBYOBRequest? byobRequest; readonly attribute double? desiredSize;
diff --git a/third_party/blink/renderer/core/streams/readable_stream.idl b/third_party/blink/renderer/core/streams/readable_stream.idl index affe0f0..d5f1bc5f 100644 --- a/third_party/blink/renderer/core/streams/readable_stream.idl +++ b/third_party/blink/renderer/core/streams/readable_stream.idl
@@ -10,7 +10,7 @@ enum ReadableStreamType { "bytes" }; [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface ReadableStream { [RuntimeEnabled=ReadableStreamAsyncIterable, HasAsyncIteratorReturnAlgorithm] async iterable<any>(optional ReadableStreamIteratorOptions options = {});
diff --git a/third_party/blink/renderer/core/streams/readable_stream_byob_reader.idl b/third_party/blink/renderer/core/streams/readable_stream_byob_reader.idl index 7907190..fee1494d 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_byob_reader.idl +++ b/third_party/blink/renderer/core/streams/readable_stream_byob_reader.idl
@@ -4,7 +4,7 @@ // https://streams.spec.whatwg.org/#byob-reader-class-definition [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface ReadableStreamBYOBReader { [CallWith=ScriptState, RaisesException] constructor(ReadableStream stream);
diff --git a/third_party/blink/renderer/core/streams/readable_stream_byob_request.idl b/third_party/blink/renderer/core/streams/readable_stream_byob_request.idl index a5101f6a..727cfad 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_byob_request.idl +++ b/third_party/blink/renderer/core/streams/readable_stream_byob_request.idl
@@ -4,7 +4,7 @@ // https://streams.spec.whatwg.org/#readablestreambyobrequest [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface ReadableStreamBYOBRequest { readonly attribute ArrayBufferView? view;
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_controller.idl b/third_party/blink/renderer/core/streams/readable_stream_default_controller.idl index ab81ed9..61ad2d4 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_default_controller.idl +++ b/third_party/blink/renderer/core/streams/readable_stream_default_controller.idl
@@ -4,7 +4,7 @@ // https://streams.spec.whatwg.org/#rs-default-controller-class-definition [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface ReadableStreamDefaultController { readonly attribute double? desiredSize;
diff --git a/third_party/blink/renderer/core/streams/readable_stream_default_reader.idl b/third_party/blink/renderer/core/streams/readable_stream_default_reader.idl index 9fe0981..16abf83 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_default_reader.idl +++ b/third_party/blink/renderer/core/streams/readable_stream_default_reader.idl
@@ -4,7 +4,7 @@ // https://streams.spec.whatwg.org/#default-reader-class-definition [ - Exposed=(Window,Worker,Worklet), + Exposed=*, ActiveScriptWrappable ] interface ReadableStreamDefaultReader { [CallWith=ScriptState, RaisesException] constructor(ReadableStream stream);
diff --git a/third_party/blink/renderer/core/streams/readable_stream_generic_reader.idl b/third_party/blink/renderer/core/streams/readable_stream_generic_reader.idl index bde6f558..6b5b9348 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_generic_reader.idl +++ b/third_party/blink/renderer/core/streams/readable_stream_generic_reader.idl
@@ -4,7 +4,7 @@ // https://streams.spec.whatwg.org/#readablestreamgenericreader [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface mixin ReadableStreamGenericReader { [CallWith=ScriptState] readonly attribute Promise<undefined> closed; [CallWith=ScriptState, RaisesException] Promise<undefined> cancel(optional any reason);
diff --git a/third_party/blink/renderer/core/streams/transform_stream.idl b/third_party/blink/renderer/core/streams/transform_stream.idl index c8830b6..0878a92 100644 --- a/third_party/blink/renderer/core/streams/transform_stream.idl +++ b/third_party/blink/renderer/core/streams/transform_stream.idl
@@ -4,7 +4,7 @@ // https://streams.spec.whatwg.org/#ts-class [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface TransformStream { [CallWith=ScriptState, RaisesException] constructor(optional any transformer, optional any writableStrategy,
diff --git a/third_party/blink/renderer/core/streams/transform_stream_default_controller.idl b/third_party/blink/renderer/core/streams/transform_stream_default_controller.idl index 31a8a07..1a40138 100644 --- a/third_party/blink/renderer/core/streams/transform_stream_default_controller.idl +++ b/third_party/blink/renderer/core/streams/transform_stream_default_controller.idl
@@ -4,7 +4,7 @@ // https://streams.spec.whatwg.org/#ts-default-controller-class-definition [ - Exposed=(Window,Worker,Worklet) + Exposed=* ]interface TransformStreamDefaultController { readonly attribute unrestricted double? desiredSize; [CallWith=ScriptState, RaisesException] void enqueue(
diff --git a/third_party/blink/renderer/core/streams/writable_stream.idl b/third_party/blink/renderer/core/streams/writable_stream.idl index 70338f1..cc93364 100644 --- a/third_party/blink/renderer/core/streams/writable_stream.idl +++ b/third_party/blink/renderer/core/streams/writable_stream.idl
@@ -4,7 +4,7 @@ // https://streams.spec.whatwg.org/#ws-class [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface WritableStream { [CallWith=ScriptState, RaisesException, MeasureAs=WritableStreamConstructor] constructor(optional any underlyingSink, optional any strategy); readonly attribute boolean locked;
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl b/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl index aea0822..fb362a5 100644 --- a/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl +++ b/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl
@@ -4,7 +4,7 @@ // https://streams.spec.whatwg.org/#ws-default-controller-class-definition [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface WritableStreamDefaultController { readonly attribute AbortSignal signal;
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl b/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl index 6515199..2c1ad0b 100644 --- a/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl +++ b/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl
@@ -6,7 +6,7 @@ // https://streams.spec.whatwg.org/#default-writer-class-definition [ - Exposed=(Window,Worker,Worklet) + Exposed=* ] interface WritableStreamDefaultWriter { [CallWith=ScriptState, RaisesException] constructor(WritableStream stream); [CallWith=ScriptState] readonly attribute Promise<undefined>
diff --git a/third_party/blink/renderer/core/url/url.idl b/third_party/blink/renderer/core/url/url.idl index bf9f75d..54aae2ed 100644 --- a/third_party/blink/renderer/core/url/url.idl +++ b/third_party/blink/renderer/core/url/url.idl
@@ -27,7 +27,7 @@ // https://url.spec.whatwg.org/#url [ - Exposed=(Window,Worker), + Exposed=(Window,Worker,ShadowRealm), // TODO(crbug.com/41480387): This should be Exposed=* ImplementedAs=DOMURL, LegacyWindowAlias=webkitURL ] interface URL {
diff --git a/third_party/blink/renderer/core/url/url_search_params.idl b/third_party/blink/renderer/core/url/url_search_params.idl index 2a55e58..2ac09cb 100644 --- a/third_party/blink/renderer/core/url/url_search_params.idl +++ b/third_party/blink/renderer/core/url/url_search_params.idl
@@ -5,7 +5,7 @@ // https://url.spec.whatwg.org/#interface-urlsearchparams [ - Exposed=(Window,Worker) + Exposed=(Window,Worker,ShadowRealm) // TODO(crbug.com/41480387): This should be Exposed=* ] interface URLSearchParams { [RaisesException] constructor(optional (sequence<sequence<USVString>> or record<USVString, USVString> or USVString) init = ""); readonly attribute unsigned long size;
diff --git a/third_party/blink/renderer/core/url_pattern/url_pattern.idl b/third_party/blink/renderer/core/url_pattern/url_pattern.idl index a96991e..437195f 100644 --- a/third_party/blink/renderer/core/url_pattern/url_pattern.idl +++ b/third_party/blink/renderer/core/url_pattern/url_pattern.idl
@@ -10,7 +10,7 @@ // https://wicg.github.io/urlpattern/ [ - Exposed=(Window,Worker) + Exposed=(Window,Worker,ShadowRealm) // TODO(crbug.com/41480387): This should be Exposed=* ] interface URLPattern { [RaisesException, CallWith=Isolate, Measure] constructor(URLPatternInput input, USVString baseURL, optional URLPatternOptions options = {});
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h index b453894..7139b0b 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
@@ -197,6 +197,9 @@ SkAlphaType GetAlphaType() const override { return color_params_.GetAlphaType(); } + SkColorType GetSkColorType() const override { + return CanvasRenderingContextSkColorInfo().colorType(); + } sk_sp<SkColorSpace> GetSkColorSpace() const override { return color_params_.GetSkColorSpace(); }
diff --git a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h index 48c77e3..9115b3a 100644 --- a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h +++ b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h
@@ -47,6 +47,7 @@ SkColorSpace::MakeSRGB()); } SkAlphaType GetAlphaType() const override { return kPremul_SkAlphaType; } + SkColorType GetSkColorType() const override { return kN32_SkColorType; } sk_sp<SkColorSpace> GetSkColorSpace() const override { return SkColorSpace::MakeSRGB(); }
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h index 5e8d44f..2ac3be9 100644 --- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
@@ -67,6 +67,9 @@ SkAlphaType GetAlphaType() const override { return color_params_.GetAlphaType(); } + SkColorType GetSkColorType() const override { + return CanvasRenderingContextSkColorInfo().colorType(); + } sk_sp<SkColorSpace> GetSkColorSpace() const override { return color_params_.GetSkColorSpace(); }
diff --git a/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent.cc b/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent.cc index 0fe97de..374e80a 100644 --- a/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent.cc +++ b/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent.cc
@@ -109,6 +109,26 @@ return DynamicTo<LayoutIFrame>(object); } +bool IsGenericContainer(const LayoutObject& object) { + if (object.Style()->GetPosition() == EPosition::kFixed) { + return true; + } + + if (object.Style()->GetPosition() == EPosition::kSticky) { + return true; + } + + if (object.Style()->ScrollsOverflow()) { + return true; + } + + if (object.IsInTopOrViewTransitionLayer()) { + return true; + } + + return false; +} + std::optional<mojom::blink::AIPageContentAttributeType> GetAttributeType( const LayoutObject& object) { if (GetIFrame(object)) { @@ -199,12 +219,8 @@ // TODO: Add FormData for attribute_type = FORM. - // If an object is fixed or sticky position or scrolls, set it as its own - // container. Keep container at the bottom of the list as it is the least - // specific. - if (object.Style()->GetPosition() == EPosition::kFixed || - object.Style()->GetPosition() == EPosition::kSticky || - object.Style()->ScrollsOverflow()) { + // Keep container at the bottom of the list as it is the least specific. + if (IsGenericContainer(object)) { return mojom::blink::AIPageContentAttributeType::kContainer; }
diff --git a/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent_unittest.cc b/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent_unittest.cc index 13e9ec64..2d038ef 100644 --- a/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent_unittest.cc +++ b/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent_unittest.cc
@@ -1064,5 +1064,37 @@ mojom::blink::AIPageContentAnchorRel::kRelationNoReferrer); } +TEST_F(AIPageContentAgentTest, TopLayerContainer) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + "<body>" + " <dialog id='welcomeDialog' style='position: absolute; overflow: " + "visible;'>" + " This is a dialog." + " </dialog>" + " <script>" + " const dialog = document.getElementById('welcomeDialog');" + " dialog.showModal();" + " </script>" + "</body>", + url_test_helpers::ToKURL("http://foobar.com")); + + auto* agent = AIPageContentAgent::GetOrCreateForTesting( + *helper_.LocalMainFrame()->GetFrame()->GetDocument()); + ASSERT_TRUE(agent); + + auto content = agent->GetAIPageContentSync(); + ASSERT_TRUE(content); + ASSERT_TRUE(content->root_node); + + const auto& root = *content->root_node; + EXPECT_EQ(root.children_nodes.size(), 1u); + + const auto& dialog = root.children_nodes.at(0); + EXPECT_EQ(dialog->content_attributes->attribute_type, + mojom::blink::AIPageContentAttributeType::kContainer); + EXPECT_TRUE(dialog->children_nodes.empty()); +} + } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_provider_config.idl b/third_party/blink/renderer/modules/credentialmanagement/identity_provider_config.idl index 968ed92..0dd1af2e 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_provider_config.idl +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_provider_config.idl
@@ -31,5 +31,5 @@ [RuntimeEnabled=FedCmDomainHint] DOMString domainHint; [RuntimeEnabled=FedCmAuthz] sequence<(USVString or IdentityProviderField)> fields; [RuntimeEnabled=FedCmAuthz] any params; - [RuntimeEnabled=FedCmIdPRegistration] IdentityProviderRequestOptionsFormat format; + [RuntimeEnabled=FedCmDelegation] IdentityProviderRequestOptionsFormat format; };
diff --git a/third_party/blink/renderer/modules/mediastream/web_media_player_ms.cc b/third_party/blink/renderer/modules/mediastream/web_media_player_ms.cc index 21d4877..b825da9 100644 --- a/third_party/blink/renderer/modules/mediastream/web_media_player_ms.cc +++ b/third_party/blink/renderer/modules/mediastream/web_media_player_ms.cc
@@ -1239,7 +1239,8 @@ } void WebMediaPlayerMS::SetVolumeMultiplier(double multiplier) { - // TODO(perkj, magjed): See TODO in OnPlay(). + volume_multiplier_ = multiplier; + SetVolume(volume_); } void WebMediaPlayerMS::ActivateSurfaceLayerForVideo(
diff --git a/third_party/blink/renderer/modules/mediastream/web_media_player_ms_test.cc b/third_party/blink/renderer/modules/mediastream/web_media_player_ms_test.cc index a379be1..bd47a05 100644 --- a/third_party/blink/renderer/modules/mediastream/web_media_player_ms_test.cc +++ b/third_party/blink/renderer/modules/mediastream/web_media_player_ms_test.cc
@@ -267,7 +267,7 @@ void Stop() override {} void Play() override {} void Pause() override {} - void SetVolume(float volume) override {} + MOCK_METHOD(void, SetVolume, (float volume)); void SwitchOutputDevice(const std::string& device_id, media::OutputDeviceStatusCB callback) override {} @@ -1762,6 +1762,37 @@ EXPECT_NE(gpu_frame, compositor_->GetCurrentFrame()); } +TEST_P(WebMediaPlayerMSTest, VolumeMultiplierAdjustsOutputVolume) { + InitializeWebMediaPlayerMS(); + is_audio_element_ = true; + auto audio_renderer = base::MakeRefCounted<MockMediaStreamAudioRenderer>(); + render_factory_->set_audio_renderer(audio_renderer); + + player_->Load(WebMediaPlayer::kLoadTypeURL, WebMediaPlayerSource(), + WebMediaPlayer::kCorsModeUnspecified, + /*is_cache_disabled=*/false); + + message_loop_controller_.RunAndWaitForStatus(media::PIPELINE_OK); + + // Setting the volume multiplier should adjust the volume sent to the audio + // renderer. + EXPECT_CALL(*audio_renderer, SetVolume(0.2)); + player_->SetVolumeMultiplier(0.2); + testing::Mock::VerifyAndClearExpectations(audio_renderer.get()); + + // Setting the volume after the multiplier should still take the multiplier + // into account. + EXPECT_CALL(*audio_renderer, SetVolume(0.1)); + player_->SetVolume(0.5); + testing::Mock::VerifyAndClearExpectations(audio_renderer.get()); + + // Resetting the multiplier should take the previously set volume into + // account. + EXPECT_CALL(*audio_renderer, SetVolume(0.5)); + player_->SetVolumeMultiplier(1.0); + testing::Mock::VerifyAndClearExpectations(audio_renderer.get()); +} + INSTANTIATE_TEST_SUITE_P(All, WebMediaPlayerMSTest, ::testing::Combine(::testing::Bool(),
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.cc b/third_party/blink/renderer/modules/webaudio/audio_context.cc index 7056ad0b..60cd8c6 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -253,6 +253,7 @@ WebAudioSinkDescriptor sink_descriptor, bool update_echo_cancellation_on_first_start) : BaseAudioContext(&window, kRealtimeContext), + FrameVisibilityObserver(GetLocalFrame()), context_id_(context_id++), audio_context_manager_(&window), permission_service_(&window), @@ -261,7 +262,15 @@ v8_sink_id_( MakeGarbageCollected<V8UnionAudioSinkInfoOrString>(g_empty_string)), media_device_service_(&window), - media_device_service_receiver_(this, &window) { + media_device_service_receiver_(this, &window), + should_interrupt_when_frame_is_hidden_( + RuntimeEnabledFeatures:: + MediaPlaybackWhileNotVisiblePermissionPolicyEnabled() && + RuntimeEnabledFeatures::AudioContextInterruptedStateEnabled() && + !GetExecutionContext()->IsFeatureEnabled( + mojom::blink::PermissionsPolicyFeature:: + kMediaPlaybackWhileNotVisible, + ReportOptions::kDoNotReport)) { RecordAudioContextOperation(AudioContextOperation::kCreate); SendLogMessage(__func__, GetAudioContextLogString(latency_hint, sample_rate)); @@ -378,6 +387,7 @@ visitor->Trace(media_device_service_receiver_); visitor->Trace(v8_sink_id_); BaseAudioContext::Trace(visitor); + FrameVisibilityObserver::Trace(visitor); } ScriptPromise<IDLUndefined> AudioContext::suspendContext( @@ -431,6 +441,8 @@ script_state, MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, "Cannot resume an interrupted AudioContext.")); + } else if (is_frame_hidden_ && should_interrupt_when_frame_is_hidden_) { + StartContextInterruption(); } auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLUndefined>>( @@ -1210,6 +1222,31 @@ } } +void AudioContext::FrameVisibilityChanged( + mojom::blink::FrameVisibility frame_visibility) { + DCHECK_CALLED_ON_VALID_SEQUENCE(main_thread_sequence_checker_); + + bool is_frame_hidden = + (frame_visibility == mojom::blink::FrameVisibility::kNotRendered); + if (is_frame_hidden == is_frame_hidden_) { + return; + } + + is_frame_hidden_ = is_frame_hidden; + + if (!should_interrupt_when_frame_is_hidden_) { + return; + } + + if (is_frame_hidden_) { + // The frame is not rendered, so the audio context should be suspended. + StartContextInterruption(); + } else { + // The frame is rendered, so the audio context should be resumed. + EndContextInterruption(); + } +} + void AudioContext::UninitializeMediaDeviceService() { if (media_device_service_.is_bound()) { media_device_service_.reset(); @@ -1370,4 +1407,13 @@ .Utf8()); } +LocalFrame* AudioContext::GetLocalFrame() const { + LocalDOMWindow* window = GetWindow(); + if (!window) { + return nullptr; + } + + return window->GetFrame(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.h b/third_party/blink/renderer/modules/webaudio/audio_context.h index ceb5d79..7706e55 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context.h +++ b/third_party/blink/renderer/modules/webaudio/audio_context.h
@@ -16,6 +16,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_context_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_union_audiosinkinfo_string.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_union_audiosinkoptions_string.h" +#include "third_party/blink/renderer/core/frame/frame_visibility_observer.h" #include "third_party/blink/renderer/core/html/media/autoplay_policy.h" #include "third_party/blink/renderer/modules/webaudio/base_audio_context.h" #include "third_party/blink/renderer/modules/webaudio/setsinkid_resolver.h" @@ -49,7 +50,8 @@ class MODULES_EXPORT AudioContext final : public BaseAudioContext, public mojom::blink::PermissionObserver, - public mojom::blink::MediaDevicesListener { + public mojom::blink::MediaDevicesListener, + public FrameVisibilityObserver { DEFINE_WRAPPERTYPEINFO(); public: @@ -99,6 +101,10 @@ void OnDevicesChanged(mojom::blink::MediaDeviceType, const Vector<WebMediaDeviceInfo>&) override; + // FrameVisibilityObserver + void FrameVisibilityChanged( + mojom::blink::FrameVisibility frame_visibility) override; + // https://webaudio.github.io/web-audio-api/#AudioContext double baseLatency() const; double outputLatency() const; @@ -276,6 +282,8 @@ // https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/media/capture/README.md#logs void SendLogMessage(const char* const function_name, const String& message); + LocalFrame* GetLocalFrame() const; + // https://webaudio.github.io/web-audio-api/#dom-audiocontext-suspended-by-user-slot bool suspended_by_user_ = false; @@ -387,6 +395,14 @@ // ends. bool should_transition_to_running_after_interruption_ = false; + // True if the context should be interrupted when the frame is hidden. + const bool should_interrupt_when_frame_is_hidden_; + + // True if the host frame's: + // - 'display' property is set to 'none'; + // - 'visibility' property is set to 'hidden'; + bool is_frame_hidden_ = false; + // The number of pending device list updates, to allow waiting until the // device list is refrehsed before using it. A value of 0 means no updates // are pending.
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index 1a50e49..bd0b8d0 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -5635,6 +5635,10 @@ return CreationAttributes().alpha ? kPremul_SkAlphaType : kOpaque_SkAlphaType; } +SkColorType WebGLRenderingContextBase::GetSkColorType() const { + return CanvasRenderingContextSkColorInfo().colorType(); +} + sk_sp<SkColorSpace> WebGLRenderingContextBase::GetSkColorSpace() const { return PredefinedColorSpaceToSkColorSpace(drawing_buffer_color_space_); }
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h index f28c157..c52e939 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -636,6 +636,7 @@ // contexts, and should be removed. SkColorInfo CanvasRenderingContextSkColorInfo() const override; SkAlphaType GetAlphaType() const override; + SkColorType GetSkColorType() const override; sk_sp<SkColorSpace> GetSkColorSpace() const override; scoped_refptr<StaticBitmapImage> GetImage(FlushReason) override; void SetHdrMetadata(const gfx::HDRMetadata& hdr_metadata) override;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc index 46312f0a..caded933 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
@@ -107,9 +107,7 @@ return SkColorInfo(kN32_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()); } - return SkColorInfo(viz::ToClosestSkColorType( - /*gpu_compositing=*/true, swap_buffers_->Format()), - GetAlphaType(), GetSkColorSpace()); + return SkColorInfo(GetSkColorType(), GetAlphaType(), GetSkColorSpace()); } SkAlphaType GPUCanvasContext::GetAlphaType() const { @@ -118,6 +116,14 @@ : kPremul_SkAlphaType; } +SkColorType GPUCanvasContext::GetSkColorType() const { + if (!swap_buffers_) { + return kN32_SkColorType; + } + return viz::ToClosestSkColorType( + /*gpu_compositing=*/true, swap_buffers_->Format()); +} + sk_sp<SkColorSpace> GPUCanvasContext::GetSkColorSpace() const { if (!swap_buffers_) { return SkColorSpace::MakeSRGB();
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h index 3653d91..0ced6cb5 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
@@ -64,6 +64,7 @@ V8OffscreenRenderingContext* AsV8OffscreenRenderingContext() final; SkColorInfo CanvasRenderingContextSkColorInfo() const override; SkAlphaType GetAlphaType() const override; + SkColorType GetSkColorType() const override; sk_sp<SkColorSpace> GetSkColorSpace() const override; // Produces a snapshot of the current contents of the swap chain if possible. // If that texture has already been sent to the compositor, will produce a
diff --git a/third_party/blink/renderer/platform/graphics/canvas_hibernation_handler.cc b/third_party/blink/renderer/platform/graphics/canvas_hibernation_handler.cc index b056386..db00d061 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_hibernation_handler.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_hibernation_handler.cc
@@ -6,6 +6,7 @@ #include "base/feature_list.h" #include "base/memory/post_delayed_memory_reduction_task.h" +#include "base/strings/stringprintf.h" #include "base/timer/elapsed_timer.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/memory_dump_request_args.h"
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/third_party/blink/renderer/platform/graphics/canvas_resource.cc index bc177a1..f925749 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -9,6 +9,7 @@ #include "base/functional/callback_helpers.h" #include "base/memory/read_only_shared_memory_region.h" +#include "base/strings/stringprintf.h" #include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h"
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h index d11e345..38333da 100644 --- a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h +++ b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h
@@ -45,4 +45,17 @@ } // namespace blink +namespace WTF { + +template <typename ValueArg, typename TraitsArg, typename VectorType> +inline void CopyToVector(const blink::HeapHashSet<ValueArg, TraitsArg>& set, + VectorType& vector) { + CopyToVector( + static_cast<const HashSet<ValueArg, TraitsArg, blink::HeapAllocator>&>( + set), + vector); +} + +} // namespace WTF + #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_HASH_SET_H_
diff --git a/third_party/blink/renderer/platform/heap/test/heap_test.cc b/third_party/blink/renderer/platform/heap/test/heap_test.cc index 32f494d..dcb2855 100644 --- a/third_party/blink/renderer/platform/heap/test/heap_test.cc +++ b/third_party/blink/renderer/platform/heap/test/heap_test.cc
@@ -2078,6 +2078,41 @@ EXPECT_TRUE(i->Value() == 1 || i->Value() == 2); } +TEST_F(HeapTest, HeapHashSetToVector) { + HeapHashSet<Member<IntWrapper>> set; + HeapVector<Member<IntWrapper>> vector; + set.insert(MakeGarbageCollected<IntWrapper>(1)); + set.insert(MakeGarbageCollected<IntWrapper>(1)); + set.insert(MakeGarbageCollected<IntWrapper>(2)); + + CopyToVector(set, vector); + EXPECT_EQ(3u, vector.size()); + + Vector<int> int_vector; + for (const auto& i : vector) { + int_vector.push_back(i->Value()); + } + std::sort(int_vector.begin(), int_vector.end()); + ASSERT_EQ(3u, int_vector.size()); + EXPECT_EQ(1, int_vector[0]); + EXPECT_EQ(1, int_vector[1]); + EXPECT_EQ(2, int_vector[2]); +} + +TEST_F(HeapTest, WeakHeapHashSetToVector) { + HeapHashSet<WeakMember<IntWrapper>> set; + HeapVector<Member<IntWrapper>> vector; + set.insert(MakeGarbageCollected<IntWrapper>(1)); + set.insert(MakeGarbageCollected<IntWrapper>(1)); + set.insert(MakeGarbageCollected<IntWrapper>(2)); + + CopyToVector(set, vector); + EXPECT_EQ(3u, vector.size()); + for (const auto& i : vector) { + EXPECT_TRUE(i->Value() == 1 || i->Value() == 2); + } +} + TEST_F(HeapTest, RefCountedGarbageCollected) { RefCountedAndGarbageCollected::destructor_calls_ = 0; {
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 96be4c8..1759495e 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -602,9 +602,7 @@ // the placement of this code, together with the //net counterpart. if (removed_headers) { // Step 13 of https://fetch.spec.whatwg.org/#http-redirect-fetch - if (base::FeatureList::IsEnabled( - features::kRemoveAuthroizationOnCrossOriginRedirect) && - !SecurityOrigin::AreSameOrigin(resource_->LastResourceRequest().Url(), + if (!SecurityOrigin::AreSameOrigin(resource_->LastResourceRequest().Url(), new_url)) { removed_headers->push_back(net::HttpRequestHeaders::kAuthorization); }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index b1bd6e5..5a9b3466 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1781,6 +1781,13 @@ origin_trial_allows_third_party: true, }, { + name: "FedCmDelegation", + depends_on: ["FedCm"], + public: true, + status: "test", + base_feature: "none", + }, + { name: "FedCmDisconnect", depends_on: ["FedCm"], base_feature: "none", @@ -3362,10 +3369,8 @@ }, { name: "PrivateStateTokens", - // status: "test", + status: "stable", base_feature: "none", - origin_trial_feature_name: "TrustTokens", - origin_trial_allows_third_party: true, public: true, }, { @@ -4111,6 +4116,11 @@ status: "stable", }, { + // crbug.com/40890818 + name: "SvgTspanBboxCache", + status: "stable", + }, + { name: "SynthesizedKeyboardEventsForAccessibilityActions", status: "experimental", },
diff --git a/third_party/blink/renderer/platform/wtf/hash_set.h b/third_party/blink/renderer/platform/wtf/hash_set.h index 77c222a..247e61b 100644 --- a/third_party/blink/renderer/platform/wtf/hash_set.h +++ b/third_party/blink/renderer/platform/wtf/hash_set.h
@@ -378,6 +378,25 @@ return Take(begin()); } +template <typename Value, + typename Traits, + typename Allocator, + typename VectorType> +inline void CopyToVector(const HashSet<Value, Traits, Allocator>& collection, + VectorType& vector) { + { + // Disallow GC across resize allocation, see crbug.com/568173 + typename VectorType::GCForbiddenScope scope; + vector.resize(collection.size()); + } + + auto it = collection.begin(); + auto end = collection.end(); + for (unsigned i = 0; it != end; ++it, ++i) { + vector[i] = (*it); + } +} + } // namespace WTF using WTF::HashSet;
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index b3f1c8f..cc45b28 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3267,10 +3267,6 @@ crbug.com/331915503 [ Mac11 ] virtual/fenced-frame-mparch/external/wpt/fenced-frame/notify-event-iframe.https.html [ Skip Timeout ] crbug.com/331851044 [ Mac14 ] virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any.worker.html?gpu [ Failure ] crbug.com/331711029 [ Win11-arm64 ] virtual/fenced-frame-mparch/external/wpt/fenced-frame/notify-event-success.https.html [ Failure Timeout ] -crbug.com/626703 [ Mac11 ] virtual/threaded/external/wpt/css/css-view-transitions/navigation/chromium-paint-holding-timeout.html [ Timeout ] -crbug.com/626703 [ Mac12 ] virtual/threaded/external/wpt/css/css-view-transitions/navigation/chromium-paint-holding-timeout.html [ Timeout ] -crbug.com/626703 [ Mac15 ] virtual/threaded/external/wpt/css/css-view-transitions/navigation/chromium-paint-holding-timeout.html [ Timeout ] -crbug.com/626703 [ Win11-arm64 ] virtual/threaded/external/wpt/css/css-view-transitions/navigation/chromium-paint-holding-timeout.html [ Timeout ] crbug.com/626703 external/wpt/css/css-text/white-space/text-wrap-balance-004.html [ Failure ] crbug.com/626703 external/wpt/editing/crashtests/designMode-caret-change.html [ Timeout ] crbug.com/626703 [ Mac14 ] external/wpt/webrtc-encoded-transform/tentative/RTCPeerConnection-insertable-streams-simulcast.https.html [ Pass Timeout ] @@ -8849,8 +8845,8 @@ crbug.com/383105114 [ Linux ] tables/mozilla/bugs/bug78162.html [ Failure Pass ] crbug.com/383105114 [ Win ] tables/mozilla/bugs/bug78162.html [ Failure Pass ] -crbug.com/378549335 [ Mac ] wpt_internal/ai/language-model-api-context-overflow.https.any.html [ Pass Timeout ] -crbug.com/378549335 [ Mac ] wpt_internal/ai/language-model-api-context-overflow.https.any.worker.html [ Pass Timeout ] +crbug.com/378549335 [ Mac ] wpt_internal/ai/language-model-api-context-overflow.https.any.html [ Failure Pass Timeout ] +crbug.com/378549335 [ Mac ] wpt_internal/ai/language-model-api-context-overflow.https.any.worker.html [ Failure Pass Timeout ] crbug.com/383855460 inspector-protocol/css/css-get-animated-styles.js [ Failure Pass ] @@ -8858,3 +8854,6 @@ # Gardener 2024-12-16 crbug.com/381238355 [ Mac11 ] virtual/gpu-rasterization/external/wpt/css/css-images/object-view-box-fit-fill-video.html [ Failure Pass ] + +# Gardener 2024-12-17 +crbug.com/384549646 virtual/threaded/external/wpt/css/css-view-transitions/navigation/chromium-paint-holding-timeout.html [ Failure Pass Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 9060562..eeeca29e 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -4789,5 +4789,15 @@ "args": ["--enable-features=SRIMessageSignatureEnforcement"], "owners": ["mkwst@chromium.org"], "expires": "May 1, 2025" + }, + { + "prefix": "error-iserror-enabled", + "platforms": ["Linux"], + "bases": ["external/wpt/webidl/ecmascript-binding/es-exceptions/DOMException-is-error.any.js"], + "exclusive_tests": "ALL", + "args": ["--js-flags=--js-error-iserror"], + "owners": ["syg@chromium.org"], + "expires": "Feb 1, 2025" } + ]
diff --git a/third_party/blink/web_tests/editing/pasteboard/extend_table_selection_crash_test.html b/third_party/blink/web_tests/editing/pasteboard/extend_table_selection_crash_test.html new file mode 100644 index 0000000..a9b85bf8 --- /dev/null +++ b/third_party/blink/web_tests/editing/pasteboard/extend_table_selection_crash_test.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<body></body> +<script> + test(() => { + const body = document.getElementsByTagName("body")[0]; + body.appendChild(document.createElement("td")); + body.appendChild(document.createElement("td")); + body.appendChild(document.createElement("td")); + document.designMode = "on"; + assert_true(document.execCommand("selectAll")); + assert_true(document.execCommand("Cut")); + }, "copying only table part should not crash"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/scope-overlapping-has.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/scope-overlapping-has.html new file mode 100644 index 0000000..542cda0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/scope-overlapping-has.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<title>@scope - Overlapping scopes with :has(..:scope..) selector</title> +<link rel="help" href="https://drafts.csswg.org/css-cascade-6/#scope-atrule"> +<link rel="help" href="https://issues.chromium.org/issues/383343312"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + :where(*) { + background-color: green; + } + @scope (.a) to (.limit) { + :scope:has(.b:not(:scope .a *)) .hello { + background-color: red; + } + } +</style> +<div class=a id=outer> + <div> + <div class=limit> + <div class=a id=inner> + <div class=b></div> + <div class=hello id=first>hello</div> + </div> + </div> + </div> + <div class=hello id=second>hello</div> +</div> +<script> +test(() => { + assert_equals(getComputedStyle(first).backgroundColor, 'rgb(255, 0, 0)'); + assert_equals(getComputedStyle(second).backgroundColor, 'rgb(0, 128, 0)'); +}, ':has() with inner :scope works when scopes overlap'); +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-buttons-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-buttons-invalid.html similarity index 97% rename from third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-buttons-invalid.html rename to third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-buttons-invalid.html index 6d7178b..752aa3c 100644 --- a/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-buttons-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-buttons-invalid.html
@@ -1,4 +1,4 @@ -<!DOCTYPE html> +<!doctype html> <meta charset="utf-8"> <title>CSS Overflow Test: ::scroll-button() invalid tests</title> <link rel="help" href="https://drafts.csswg.org/css-overflow-5/#scroll-buttons">
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-buttons-valid.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-buttons-valid.html similarity index 98% rename from third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-buttons-valid.html rename to third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-buttons-valid.html index 0198a65..b4e747e 100644 --- a/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-buttons-valid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-buttons-valid.html
@@ -1,4 +1,4 @@ -<!DOCTYPE html> +<!doctype html> <meta charset="utf-8"> <title>CSS Overflow Test: ::scroll-button() valid tests</title> <link rel="help" href="https://drafts.csswg.org/css-overflow-5/#scroll-buttons">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-markers-computed.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-markers-computed.html new file mode 100644 index 0000000..882ed83 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-markers-computed.html
@@ -0,0 +1,34 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Overflow: scroll-marker-group computed values</title> +<link rel="help" href="https://drafts.csswg.org/css-overflow-5/#scroll-marker-group-property"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +<style> + #target { + scroll-marker-group: before; + } +</style> +<div id="target"></div> +<script> + test_computed_value('scroll-marker-group', 'initial', 'none'); + test_computed_value('scroll-marker-group', 'inherit', 'none'); + test_computed_value('scroll-marker-group', 'unset', 'none'); + test_computed_value('scroll-marker-group', 'revert', 'none'); + + test_computed_value('scroll-marker-group', 'none'); + test_computed_value('scroll-marker-group', 'before'); + test_computed_value('scroll-marker-group', 'after'); + + test(() => { + let style = getComputedStyle(document.getElementById('target')); + assert_not_equals(Array.from(style).indexOf('scroll-marker-group'), -1); + }, 'The scroll-marker-group property shows up in CSSStyleDeclaration enumeration'); + + test(() => { + let style = document.getElementById('target').style; + assert_not_equals(style.cssText.indexOf('scroll-marker-group'), -1); + }, 'The scroll-marker-group property shows up in CSSStyleDeclaration.cssText'); + +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-markers-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-markers-invalid.html new file mode 100644 index 0000000..5194d5a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-markers-invalid.html
@@ -0,0 +1,15 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Overflow: parsing scroll-marker-group with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-overflow-5/#scroll-marker-group-property"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +<div id="target"></div> +<script> + test_invalid_value('scroll-marker-group', '10'); + test_invalid_value('scroll-marker-group', 'true'); + test_invalid_value('scroll-marker-group', 'default'); + test_invalid_value('scroll-marker-group', 'set'); + test_invalid_value('scroll-marker-group', 'before, after'); +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-markers-valid.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-markers-valid.html new file mode 100644 index 0000000..760efc8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/parsing/parsing/scroll-markers-valid.html
@@ -0,0 +1,18 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Overflow: parsing scroll-marker-group with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-overflow-5/#scroll-marker-group-property"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +<div id="target"></div> +<script> + test_valid_value('scroll-marker-group', 'initial'); + test_valid_value('scroll-marker-group', 'inherit'); + test_valid_value('scroll-marker-group', 'unset'); + test_valid_value('scroll-marker-group', 'revert'); + + test_valid_value("scroll-marker-group", "none"); + test_valid_value("scroll-marker-group", "before"); + test_valid_value("scroll-marker-group", "after"); +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/initial-value-unit-arithmetic-expected.txt similarity index 87% rename from third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing-expected.txt rename to third_party/blink/web_tests/external/wpt/css/css-properties-values-api/initial-value-unit-arithmetic-expected.txt index 6d09c309..10b6b476 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/initial-value-unit-arithmetic-expected.txt
@@ -1,5 +1,4 @@ This is a testharness.js-based test. -Found 1 FAIL, 0 TIMEOUT, 0 NOTRUN. [FAIL] syntax:'<length>', initialValue:'calc(5px * 3px / 6px)' is valid Failed to execute 'registerProperty' on 'CSS': The initial value provided does not parse for the given syntax. Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/initial-value-unit-arithmetic.html b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/initial-value-unit-arithmetic.html new file mode 100644 index 0000000..0974e13 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/initial-value-unit-arithmetic.html
@@ -0,0 +1,10 @@ +<!DOCTYPE HTML> +<title>CSS Properties and Values API: Unit arithmetic in initial value</title> +<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-css-registerproperty" /> +<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#supported-syntax-strings" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="./resources/utils.js"></script> +<script> + test_initial_value_valid("<length>", "calc(5px * 3px / 6px)"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html index 793ef21..076eddb8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html +++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html
@@ -4,24 +4,11 @@ <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#supported-syntax-strings" /> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="./resources/utils.js"></script> <script> -test_count = 0; -function assert_valid(syntax, initialValue) { - // No actual assertions, this just shouldn't throw - test(function() { - var name = '--syntax-test-' + (test_count++); - CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false}); - }, "syntax:'" + syntax + "', initialValue:'" + initialValue + "' is valid"); -} - -function assert_invalid(syntax, initialValue) { - test(function(){ - var name = '--syntax-test-' + (test_count++); - assert_throws_dom("SyntaxError", - () => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})); - }, "syntax:'" + syntax + "', initialValue:'" + initialValue + "' is invalid"); -} +let assert_valid = test_initial_value_valid; +let assert_invalid = test_initial_value_invalid; assert_valid("*", "a"); assert_valid(" * ", "b"); @@ -47,7 +34,6 @@ assert_valid("<length>", "10px /*:)*/"); assert_valid("<length>", " calc(-2px)"); assert_valid("<length>", "calc(2px*4 + 10px)"); -assert_valid("<length>", "calc(5px * 3px / 6px)"); assert_valid("<length>", "7.1e-4cm"); assert_valid("<length>", "calc(7in - 12px)"); assert_valid("<length>", "calc(15px + (sign(100vh - 10px) * 5px))");
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/resources/utils.js b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/resources/utils.js index a952a4fe..b850e61 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/resources/utils.js +++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/resources/utils.js
@@ -243,3 +243,19 @@ assert_equals(getComputedStyle(target).getPropertyValue(customProperty), options.to, "Element has the expected final value"); }, description); }; + +function test_initial_value_valid(syntax, initialValue) { + // No actual assertions, this just shouldn't throw + test(() => { + var name = generate_name(); + CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false}); + }, "syntax:'" + syntax + "', initialValue:'" + initialValue + "' is valid"); +} + +function test_initial_value_invalid(syntax, initialValue) { + test(() =>{ + var name = generate_name(); + assert_throws_dom("SyntaxError", + () => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})); + }, "syntax:'" + syntax + "', initialValue:'" + initialValue + "' is invalid"); +} \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/fetch.any.js b/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/fetch.any.js index fc81fcc..4840451 100644 --- a/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/fetch.any.js +++ b/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/fetch.any.js
@@ -1,10 +1,5 @@ // META: global=window,dedicatedworker,sharedworker - -// Given `{ digest: "...", body: "...", cors: true, type: "..." }`: -function resourceURL(data) { - let params = new URLSearchParams(data); - return "./resource.py?" + params.toString(); -} +// META: script=helper.js // A canonically validly signed response, generated using the steps at // https://wicg.github.io/signature-based-sri/#examples, relying on the test @@ -27,19 +22,12 @@ // {"hello": "world"} // ``` -// Test key from https://www.rfc-editor.org/rfc/rfc9421.html#name-example-ed25519-test-key. -const kValidKey = "JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs="; - -// A key with the right length that cannot be used to verify the HTTP response -// above. -const kInvalidKey = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; - // Metadata from the response above: const kRequestWithValidSignature = { body: `{"hello": "world"}`, digest: `sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:`, signature: `signature=:TUznBT2ikFq6VrtoZeC5znRtZugu1U8OHJWoBkOLDTJA2FglSR34QY9j+BwN79PT4H0p8aIosnv4rXSKfIZVDA==:`, - signatureInput: `signature=("identity-digest";sf);alg="ed25519";keyid="JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=";tag="sri"` + signatureInput: `signature=("identity-digest";sf);alg="ed25519";keyid="${kValidKeys['rfc']}";tag="sri"` }; // Metadata from the response above, but with an incorrect signature: @@ -47,83 +35,48 @@ body: `{"hello": "world"}`, digest: `sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:`, signature: `signature=:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==:`, - signatureInput: `signature=("identity-digest";sf);alg="ed25519";keyid="JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=";tag="sri"` + signatureInput: `signature=("identity-digest";sf);alg="ed25519";keyid="${kValidKeys['rfc']}";tag="sri"` }; -const EXPECT_BLOCKED = "block"; -const EXPECT_LOADED = "loaded"; +generate_fetch_test({}, "", EXPECT_LOADED, + "No signature, no integrity check: loads."); -function generate_test(request_data, integrity, expectation, description) { - promise_test(test => { - const url = resourceURL(request_data); - let options = {}; - if (integrity != "") { - options.integrity = integrity; - } +generate_fetch_test({}, `ed25519-!!!`, EXPECT_LOADED, + "No signature, malformed integrity check: loads."); - let fetcher = fetch(url, options); - if (expectation == EXPECT_LOADED) { - return fetcher.then(r => { - assert_equals(r.status, 200, "Response status is 200."); - - // Verify `accept-signatures`: if the invalid key is present, both a valid and invalid - // key were set. If just the valid key is present, that's the only key we should see - // in the header. - if (integrity.includes(`ed25519-${kInvalidKey}`)) { - assert_equals(r.headers.get('accept-signatures'), - `sig0=("identity-digest";sf);keyid="${kInvalidKey}";tag="sri", sig1=("identity-digest";sf);keyid="${kValidKey}";tag="sri"`, - "`accept-signatures` was set."); - } else if (integrity.includes(`ed25519-${kValidKey}`)) { - assert_equals(r.headers.get('accept-signatures'), - `sig0=("identity-digest";sf);keyid="${kValidKey}";tag="sri"`, - "`accept-signatures` was set."); - } - }); - } else { - return promise_rejects_js(test, TypeError, fetcher); - } - }, description); -} - -generate_test({}, "", EXPECT_LOADED, - "No signature, no integrity check: loads."); - -generate_test({}, `ed25519-!!!`, EXPECT_LOADED, - "No signature, malformed integrity check: loads."); - -generate_test({}, `ed25519-${kValidKey}`, EXPECT_BLOCKED, - "No signature, valid integrity check: blocked."); +generate_fetch_test({}, `ed25519-${kValidKeys['rfc']}`, EXPECT_BLOCKED, + "No signature, valid integrity check: blocked."); // Valid signatures depend upon integrity checks. -generate_test(kRequestWithValidSignature, "", EXPECT_LOADED, - "Valid signature, no integrity check: loads."); +generate_fetch_test(kRequestWithValidSignature, "", EXPECT_LOADED, + "Valid signature, no integrity check: loads."); -generate_test(kRequestWithValidSignature, "ed25519-???", EXPECT_LOADED, - "Valid signature, malformed integrity check: loads."); +generate_fetch_test(kRequestWithValidSignature, "ed25519-???", EXPECT_LOADED, + "Valid signature, malformed integrity check: loads."); -generate_test(kRequestWithValidSignature, `ed25519-${kValidKey}`, EXPECT_LOADED, - "Valid signature, matching integrity check: loads."); +generate_fetch_test(kRequestWithValidSignature, `ed25519-${kValidKeys['rfc']}`, EXPECT_LOADED, + "Valid signature, matching integrity check: loads."); -generate_test(kRequestWithValidSignature, `ed25519-${kInvalidKey}`, EXPECT_BLOCKED, - "Valid signature, mismatched integrity check: blocked."); +generate_fetch_test(kRequestWithValidSignature, `ed25519-${kInvalidKey}`, EXPECT_BLOCKED, + "Valid signature, mismatched integrity check: blocked."); -generate_test(kRequestWithValidSignature, - `ed25519-${kValidKey} ed25519-${kInvalidKey}`, EXPECT_LOADED, - "Valid signature, one valid integrity check: loads."); +generate_fetch_test(kRequestWithValidSignature, + `ed25519-${kValidKeys['rfc']} ed25519-${kInvalidKey}`, EXPECT_LOADED, + "Valid signature, one valid integrity check: loads."); // Invalid signatures are all blocked. -generate_test(kRequestWithInvalidSignature, "", EXPECT_BLOCKED, - "Invalid signature, no integrity check: blocked."); +generate_fetch_test(kRequestWithInvalidSignature, "", EXPECT_BLOCKED, + "Invalid signature, no integrity check: blocked."); -generate_test(kRequestWithInvalidSignature, "ed25519-???", EXPECT_BLOCKED, - "Invalid signature, malformed integrity check: blocked."); +generate_fetch_test(kRequestWithInvalidSignature, "ed25519-???", EXPECT_BLOCKED, + "Invalid signature, malformed integrity check: blocked."); -generate_test(kRequestWithInvalidSignature, `ed25519-${kValidKey}`, EXPECT_BLOCKED, - "Invalid signature, matching integrity check: blocked."); +generate_fetch_test(kRequestWithInvalidSignature, `ed25519-${kValidKeys['rfc']}`, EXPECT_BLOCKED, + "Invalid signature, matching integrity check: blocked."); -generate_test(kRequestWithInvalidSignature, `ed25519-${kInvalidKey}`, EXPECT_BLOCKED, - "Invalid signature, mismatched integrity check: blocked."); +generate_fetch_test(kRequestWithInvalidSignature, `ed25519-${kInvalidKey}`, EXPECT_BLOCKED, + "Invalid signature, mismatched integrity check: blocked."); -generate_test(kRequestWithInvalidSignature, - `ed25519-${kValidKey} ed25519-${kInvalidKey}`, EXPECT_BLOCKED, - "Invalid signature, one valid integrity check: blocked."); +generate_fetch_test(kRequestWithInvalidSignature, + `ed25519-${kValidKeys['rfc']} ed25519-${kInvalidKey}`, EXPECT_BLOCKED, + "Invalid signature, one valid integrity check: blocked.");
diff --git a/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/helper.js b/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/helper.js new file mode 100644 index 0000000..c13c6c4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/helper.js
@@ -0,0 +1,92 @@ +// +// Exciting constants we'll use for test cases below: +// +const kValidKeys = { + // https://www.rfc-editor.org/rfc/rfc9421.html#name-example-ed25519-test-key + rfc: "JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=", + + // Randomly generated key: + // + // { + // "crv": "Ed25519", + // "d": "MTodZiTA9CBsuIvSfO679TThkG3b7ce6R3sq_CdyVp4", + // "ext": true, + // "kty": "OKP", + // "x": "xDnP380zcL4rJ76rXYjeHlfMyPZEOqpJYjsjEppbuXE" + // } + // + arbitrary: "xDnP380zcL4rJ76rXYjeHlfMyPZEOqpJYjsjEppbuXE=" +}; + +// A key with the right length that cannot be used to verify the HTTP response +// above. +const kInvalidKey = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + +// Generated test expectations are more readable if we're using something +// other than a boolean. +const EXPECT_BLOCKED = "block"; +const EXPECT_LOADED = "loaded"; + + +// Given `{ digest: "...", body: "...", cors: true, type: "..." }`, generates +// the URL to a script resource that has the given characteristics. +let counter = 0; +function resourceURL(data) { + counter++; + data.type ??= "application/javascript"; + data.counter = counter; + let params = new URLSearchParams(data); + return "./resource.py?" + params.toString(); +} + +function generate_fetch_test(request_data, integrity, expectation, description) { + promise_test(test => { + const url = resourceURL(request_data); + let options = {}; + if (integrity != "") { + options.integrity = integrity; + } + + let fetcher = fetch(url, options); + if (expectation == EXPECT_LOADED) { + return fetcher.then(r => { + assert_equals(r.status, 200, "Response status is 200."); + + // Verify `accept-signatures`: if the invalid key is present, both a valid and invalid + // key were set. If just the valid key is present, that's the only key we should see + // in the header. + if (integrity.includes(`ed25519-${kInvalidKey}`)) { + assert_equals(r.headers.get('accept-signatures'), + `sig0=("identity-digest";sf);keyid="${kInvalidKey}";tag="sri", sig1=("identity-digest";sf);keyid="${kValidKeys['rfc']}";tag="sri"`, + "`accept-signatures` was set."); + } else if (integrity.includes(`ed25519-${kValidKeys['rfc']}`)) { + assert_equals(r.headers.get('accept-signatures'), + `sig0=("identity-digest";sf);keyid="${kValidKeys['rfc']}";tag="sri"`, + "`accept-signatures` was set."); + } + }); + } else { + return promise_rejects_js(test, TypeError, fetcher); + } + }, "`fetch()`: " + description); +} + +function generate_script_test(request_data, integrity, expectation, description) { + async_test(t => { + let s = document.createElement('script'); + s.src = resourceURL(request_data); + s.integrity = integrity; + if (expectation == EXPECT_BLOCKED) { + s.onerror = t.step_func_done(e => { + assert_equals("error", e.type); + }); + s.onload = t.unreached_func("Script should not execute."); + } else { + s.onload = t.step_func_done(e => { + assert_equals("load", e.type); + }); + s.onerror = t.unreached_func("Script should not fail."); + } + document.body.appendChild(s); + }, "`<script>`: " + description); +}
diff --git a/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/path.window.js b/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/path.window.js new file mode 100644 index 0000000..37a6c04 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/path.window.js
@@ -0,0 +1,83 @@ +// META: script=helper.js + +// The following tests validate the behavior of the `@path` derived component. +// They'll all be rooted in the following response, generated using the steps at +// https://wicg.github.io/signature-based-sri/#examples, relying on the test +// key from https://www.rfc-editor.org/rfc/rfc9421.html#name-example-ed25519-test-key: +// +// ``` +// NOTE: '\' line wrapping per RFC 8792 +// +// HTTP/1.1 200 OK +// Date: Tue, 20 Apr 2021 02:07:56 GMT +// Content-Type: application/json +// Identity-Digest: sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=: +// Content-Length: 18 +// Signature-Input: signature=("identity-digest";sf "@path";req);alg="ed25519"; \ +// keyid="JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs="; \ +// tag="sri" +// Signature: signature=:oVQ+s/OqXLAVdfvgZ3HaPiyzkpNXZSit9l6e1FB/gOOL3t8FOrIRDV \ +// CkcIEcJjd3MA1mROn39/WQShTmnKmlDg==: +// +// +// {"hello": "world"} +// ``` +// +// TODO: When we remove the `tentative` label from the path, we'll need to +// regenerate the expected signatures below, as the signature base will change. + +// Metadata from the response above: +const kRequestsWithValidSignature = [ + // `identity-digest` then `@path`, with the following signature base: + // + // ``` + // "identity-digest";sf: sha-256=:PZJ+9CdAAIacg7wfUe4t/RkDQJVKM0mCZ2K7qiRhHFc=: + // "@path";req: /subresource-integrity/signatures/tentative/resource.py + // "@signature-params": ("identity-digest";sf "@path";req);alg="ed25519";keyid="JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=";tag="sri" + // ``` + { + body: "window.hello = `world`;", + digest: "sha-256=:PZJ+9CdAAIacg7wfUe4t/RkDQJVKM0mCZ2K7qiRhHFc=:", + signature: `signature=:AEW2XbDmmBK71KBle0Dx1JAWAO7B4QdEH2Tw71c9nntjUmx8xF5t8xbsETRHFwULrvJ4STBFtdMVm5a7QIw5Cw==:`, + signatureInput: `signature=("identity-digest";sf "@path";req);alg="ed25519";keyid="${kValidKeys['rfc']}";tag="sri"` + }, + // `@path` then `identity-digest`, with the following signature base: + // + // ``` + // "@path";req: /subresource-integrity/signatures/tentative/resource.py + // "identity-digest";sf: sha-256=:PZJ+9CdAAIacg7wfUe4t/RkDQJVKM0mCZ2K7qiRhHFc=: + // "@signature-params": ("@path";req "identity-digest";sf);alg="ed25519";keyid="JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=";tag="sri" + // ``` + { + body: "window.hello = `world`;", + digest: "sha-256=:PZJ+9CdAAIacg7wfUe4t/RkDQJVKM0mCZ2K7qiRhHFc=:", + signature: `signature=:NEmnhhW1aKxO+ReWQmmSF17i49ZEdtDC4lRI2CJDw2E/rz9j2a8f8kIwVk7W/BIuQ6kejTAQ2FReGmmkREXPDg==:`, + signatureInput: `signature=("@path";req "identity-digest";sf);alg="ed25519";keyid="${kValidKeys['rfc']}";tag="sri"` + } +]; + +// Valid signatures depend upon integrity checks. +// +// We're testing our handling of malformed and multiple keys generally in +// `fetch.any.js` and `script.window.js`. Here we'll just focus on ensuring +// that responses with `@path` components load at all (no integrity check), +// load when integrity checks match, and fail when integrity checks mismatch. +for (const request of kRequestsWithValidSignature) { + // fetch(): + generate_fetch_test(request, "", EXPECT_LOADED, + `Valid signature (${request.signature}), no integrity check: loads.`); + + generate_fetch_test(request, `ed25519-${kValidKeys['rfc']}`, EXPECT_LOADED, + `Valid signature (${request.signature}), matching integrity check: loads.`); + + generate_fetch_test(request, `ed25519-${kInvalidKey}`, EXPECT_BLOCKED, + `Valid signature (${request.signature}), mismatched integrity check: blocked.`); + + // <script>: + generate_script_test(request, "", EXPECT_LOADED, + `Valid signature (${request.signature}), no integrity check: loads.`); + generate_script_test(request, `ed25519-${kValidKeys['rfc']}`, EXPECT_LOADED, + `Valid signature (${request.signature}), matching integrity check: loads.`); + generate_script_test(request, `ed25519-${kInvalidKey}`, EXPECT_BLOCKED, + `Valid signature (${request.signature}), mismatched integrity check: blocked.`); +}
diff --git a/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/script.window.js b/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/script.window.js index 89f2403..c9ccee3 100644 --- a/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/script.window.js +++ b/third_party/blink/web_tests/external/wpt/subresource-integrity/signatures/tentative/script.window.js
@@ -1,31 +1,10 @@ +// META: script=helper.js + // // Validate signature-based SRI's interaction between signed script responses // and `<script integrity>` assertions. // -// -// Exciting constants we'll use for test cases below: -// -const kValidKeys = { - // https://www.rfc-editor.org/rfc/rfc9421.html#name-example-ed25519-test-key - rfc: "JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=", - - // Randomly generated key: - // - // { - // "crv": "Ed25519", - // "d": "MTodZiTA9CBsuIvSfO679TThkG3b7ce6R3sq_CdyVp4", - // "ext": true, - // "kty": "OKP", - // "x": "xDnP380zcL4rJ76rXYjeHlfMyPZEOqpJYjsjEppbuXE" - // } - // - arbitrary: "xDnP380zcL4rJ76rXYjeHlfMyPZEOqpJYjsjEppbuXE=" -}; - -// A key with the right length that cannot be used to verify the HTTP response -// above. -const kInvalidKey = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; const kScriptToExecute = { body: "window.hello = `world`;", @@ -69,49 +48,16 @@ // Equally exciting helper functions // -// Given `{ digest: "...", body: "...", cors: true, type: "..." }`, generates -// the URL to a script resource that has the given characteristics. -let counter = 0; -function resourceURL(data) { - counter++; - data.type = "application/javascript"; - data.counter = counter; - let params = new URLSearchParams(data); - return "./resource.py?" + params.toString(); -} - -const EXPECT_BLOCKED = "block"; -const EXPECT_LOADED = "loaded"; - -function generate_test(request_data, integrity, expectation, description) { - async_test(t => { - let s = document.createElement('script'); - s.src = resourceURL(request_data); - s.integrity = integrity; - if (expectation == EXPECT_BLOCKED) { - s.onerror = t.step_func_done(e => { - assert_equals("error", e.type); - }); - s.onload = t.unreached_func("Script should not execute."); - } else { - s.onload = t.step_func_done(e => { - assert_equals("load", e.type); - }); - s.onerror = t.unreached_func("Script should not fail."); - } - document.body.appendChild(s); - }, description); -} // Executable: unsigned. const kUnsigned = { body: kScriptToExecute['body'] }; -generate_test(kUnsigned, "", EXPECT_LOADED, - "No signature, no integrity check: loads."); +generate_script_test(kUnsigned, "", EXPECT_LOADED, + "No signature, no integrity check: loads."); -generate_test(kUnsigned, "ed25519-???", EXPECT_LOADED, - "No signature, malformed integrity check: loads."); +generate_script_test(kUnsigned, "ed25519-???", EXPECT_LOADED, + "No signature, malformed integrity check: loads."); -generate_test(kUnsigned, `ed25519-${kValidKeys['rfc']}`, EXPECT_BLOCKED, - "No signature, valid integrity check: loads."); +generate_script_test(kUnsigned, `ed25519-${kValidKeys['rfc']}`, EXPECT_BLOCKED, + "No signature, valid integrity check: loads."); // Executable and non-executable scripts signed with RFC's test key. const kSignedShouldExecute = { @@ -128,18 +74,18 @@ }; // Should load: -generate_test(kSignedShouldExecute, "", EXPECT_LOADED, - "Valid signature, no integrity check: loads."); -generate_test(kSignedShouldExecute, "ed25519-???", EXPECT_LOADED, - "Valid signature, malformed integrity check: loads."); -generate_test(kSignedShouldExecute, `ed25519-${kValidKeys['rfc']}`, EXPECT_LOADED, - "Valid signature, valid integrity check: loads."); -generate_test(kSignedShouldExecute, `ed25519-${kValidKeys['rfc']} ed25519-${kValidKeys['arbitrary']}`, EXPECT_LOADED, - "Valid signature, one matching integrity check: loads."); +generate_script_test(kSignedShouldExecute, "", EXPECT_LOADED, + "Valid signature, no integrity check: loads."); +generate_script_test(kSignedShouldExecute, "ed25519-???", EXPECT_LOADED, + "Valid signature, malformed integrity check: loads."); +generate_script_test(kSignedShouldExecute, `ed25519-${kValidKeys['rfc']}`, EXPECT_LOADED, + "Valid signature, valid integrity check: loads."); +generate_script_test(kSignedShouldExecute, `ed25519-${kValidKeys['rfc']} ed25519-${kValidKeys['arbitrary']}`, EXPECT_LOADED, + "Valid signature, one matching integrity check: loads."); // Should block: -generate_test(kSignedShouldBlock, `ed25519-${kValidKeys['arbitrary']}`, EXPECT_BLOCKED, - "Valid signature, mismatched integrity check: blocked."); +generate_script_test(kSignedShouldBlock, `ed25519-${kValidKeys['arbitrary']}`, EXPECT_BLOCKED, + "Valid signature, mismatched integrity check: blocked."); // Executable and non-executable scripts signed with RFC's test key and the arbitrary key: const kMultiplySignedShouldExecute = { @@ -158,17 +104,17 @@ signature: `signature1=:${kScriptToBlock['signatures']['rfc']}:, ` + `signature2=:${kScriptToBlock['signatures']['arbitrary']}:` }; -generate_test(kMultiplySignedShouldExecute, "", EXPECT_LOADED, - "Valid signatures, no integrity check: loads."); -generate_test(kMultiplySignedShouldExecute, "ed25519-???", EXPECT_LOADED, - "Valid signatures, malformed integrity check: loads."); -generate_test(kMultiplySignedShouldExecute, `ed25519-${kValidKeys['rfc']}`, EXPECT_LOADED, - "Valid signatures, integrity check matches one: loads."); -generate_test(kMultiplySignedShouldExecute, `ed25519-${kValidKeys['arbitrary']}`, EXPECT_LOADED, - "Valid signatures, integrity check matches the other: loads."); -generate_test(kMultiplySignedShouldExecute, `ed25519-${kValidKeys['rfc']} ed25519-${kValidKeys['arbitrary']}`, EXPECT_LOADED, - "Valid signatures, integrity check matches both: loads."); +generate_script_test(kMultiplySignedShouldExecute, "", EXPECT_LOADED, + "Valid signatures, no integrity check: loads."); +generate_script_test(kMultiplySignedShouldExecute, "ed25519-???", EXPECT_LOADED, + "Valid signatures, malformed integrity check: loads."); +generate_script_test(kMultiplySignedShouldExecute, `ed25519-${kValidKeys['rfc']}`, EXPECT_LOADED, + "Valid signatures, integrity check matches one: loads."); +generate_script_test(kMultiplySignedShouldExecute, `ed25519-${kValidKeys['arbitrary']}`, EXPECT_LOADED, + "Valid signatures, integrity check matches the other: loads."); +generate_script_test(kMultiplySignedShouldExecute, `ed25519-${kValidKeys['rfc']} ed25519-${kValidKeys['arbitrary']}`, EXPECT_LOADED, + "Valid signatures, integrity check matches both: loads."); // Should block: -generate_test(kMultiplySignedShouldBlock, `ed25519-${kInvalidKey}`, EXPECT_BLOCKED, - "Valid signatures, integrity check matches neither: blocked."); +generate_script_test(kMultiplySignedShouldBlock, `ed25519-${kInvalidKey}`, EXPECT_BLOCKED, + "Valid signatures, integrity check matches neither: blocked.");
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-expected.txt index 34b24773..5543707d 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-expected.txt
@@ -12,8 +12,6 @@ at uncaught-in-iframe.html:13:5 f @ uncaught-in-iframe.html:11 (anonymous) @ uncaught-in-iframe.html:13 -load -(anonymous) @ uncaught-in-iframe.html:2 uncaught-in-iframe.html:6 Uncaught Error: Exception in setTimeout callback. at bar (uncaught-in-iframe.html:6:23) at uncaught-in-iframe.html:8:13 @@ -22,6 +20,4 @@ setTimeout f @ uncaught-in-iframe.html:4 (anonymous) @ uncaught-in-iframe.html:13 -load -(anonymous) @ uncaught-in-iframe.html:2
diff --git a/third_party/blink/web_tests/http/tests/devtools/copy-network-request-expected.txt b/third_party/blink/web_tests/http/tests/devtools/copy-network-request-expected.txt index 19e0867b..cd29f03 100644 --- a/third_party/blink/web_tests/http/tests/devtools/copy-network-request-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/copy-network-request-expected.txt Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/shadowrealm/webexposed/global-interface-listing-shadow-realm-expected.txt b/third_party/blink/web_tests/http/tests/shadowrealm/webexposed/global-interface-listing-shadow-realm-expected.txt index bfd27c4..d68c8e8 100644 --- a/third_party/blink/web_tests/http/tests/shadowrealm/webexposed/global-interface-listing-shadow-realm-expected.txt +++ b/third_party/blink/web_tests/http/tests/shadowrealm/webexposed/global-interface-listing-shadow-realm-expected.txt
@@ -1,5 +1,180 @@ CONSOLE MESSAGE: This test logs exposed APIs from ShadowRealmGlobalScope CONSOLE MESSAGE: [INTERFACES] +CONSOLE MESSAGE: interface AbortController +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter signal +CONSOLE MESSAGE: method abort +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: interface AbortSignal : EventTarget +CONSOLE MESSAGE: static method abort +CONSOLE MESSAGE: static method any +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter aborted +CONSOLE MESSAGE: getter onabort +CONSOLE MESSAGE: getter reason +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method throwIfAborted +CONSOLE MESSAGE: setter onabort +CONSOLE MESSAGE: interface ByteLengthQueuingStrategy +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter highWaterMark +CONSOLE MESSAGE: getter size +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: interface CountQueuingStrategy +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter highWaterMark +CONSOLE MESSAGE: getter size +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: interface CustomEvent : Event +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter detail +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method initCustomEvent +CONSOLE MESSAGE: interface DOMException +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: attribute ABORT_ERR +CONSOLE MESSAGE: attribute DATA_CLONE_ERR +CONSOLE MESSAGE: attribute DOMSTRING_SIZE_ERR +CONSOLE MESSAGE: attribute HIERARCHY_REQUEST_ERR +CONSOLE MESSAGE: attribute INDEX_SIZE_ERR +CONSOLE MESSAGE: attribute INUSE_ATTRIBUTE_ERR +CONSOLE MESSAGE: attribute INVALID_ACCESS_ERR +CONSOLE MESSAGE: attribute INVALID_CHARACTER_ERR +CONSOLE MESSAGE: attribute INVALID_MODIFICATION_ERR +CONSOLE MESSAGE: attribute INVALID_NODE_TYPE_ERR +CONSOLE MESSAGE: attribute INVALID_STATE_ERR +CONSOLE MESSAGE: attribute NAMESPACE_ERR +CONSOLE MESSAGE: attribute NETWORK_ERR +CONSOLE MESSAGE: attribute NOT_FOUND_ERR +CONSOLE MESSAGE: attribute NOT_SUPPORTED_ERR +CONSOLE MESSAGE: attribute NO_DATA_ALLOWED_ERR +CONSOLE MESSAGE: attribute NO_MODIFICATION_ALLOWED_ERR +CONSOLE MESSAGE: attribute QUOTA_EXCEEDED_ERR +CONSOLE MESSAGE: attribute SECURITY_ERR +CONSOLE MESSAGE: attribute SYNTAX_ERR +CONSOLE MESSAGE: attribute TIMEOUT_ERR +CONSOLE MESSAGE: attribute TYPE_MISMATCH_ERR +CONSOLE MESSAGE: attribute URL_MISMATCH_ERR +CONSOLE MESSAGE: attribute VALIDATION_ERR +CONSOLE MESSAGE: attribute WRONG_DOCUMENT_ERR +CONSOLE MESSAGE: getter code +CONSOLE MESSAGE: getter message +CONSOLE MESSAGE: getter name +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: interface ErrorEvent : Event +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter colno +CONSOLE MESSAGE: getter error +CONSOLE MESSAGE: getter filename +CONSOLE MESSAGE: getter lineno +CONSOLE MESSAGE: getter message +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: interface Event +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: attribute AT_TARGET +CONSOLE MESSAGE: attribute BUBBLING_PHASE +CONSOLE MESSAGE: attribute CAPTURING_PHASE +CONSOLE MESSAGE: attribute NONE +CONSOLE MESSAGE: getter bubbles +CONSOLE MESSAGE: getter cancelBubble +CONSOLE MESSAGE: getter cancelable +CONSOLE MESSAGE: getter composed +CONSOLE MESSAGE: getter currentTarget +CONSOLE MESSAGE: getter defaultPrevented +CONSOLE MESSAGE: getter eventPhase +CONSOLE MESSAGE: getter returnValue +CONSOLE MESSAGE: getter srcElement +CONSOLE MESSAGE: getter target +CONSOLE MESSAGE: getter timeStamp +CONSOLE MESSAGE: getter type +CONSOLE MESSAGE: method composedPath +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method initEvent +CONSOLE MESSAGE: method preventDefault +CONSOLE MESSAGE: method stopImmediatePropagation +CONSOLE MESSAGE: method stopPropagation +CONSOLE MESSAGE: setter cancelBubble +CONSOLE MESSAGE: setter returnValue +CONSOLE MESSAGE: interface EventTarget +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: method addEventListener +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method dispatchEvent +CONSOLE MESSAGE: method removeEventListener +CONSOLE MESSAGE: method when +CONSOLE MESSAGE: interface Observable +CONSOLE MESSAGE: static method from +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: method catch +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method drop +CONSOLE MESSAGE: method every +CONSOLE MESSAGE: method filter +CONSOLE MESSAGE: method find +CONSOLE MESSAGE: method first +CONSOLE MESSAGE: method flatMap +CONSOLE MESSAGE: method forEach +CONSOLE MESSAGE: method inspect +CONSOLE MESSAGE: method last +CONSOLE MESSAGE: method map +CONSOLE MESSAGE: method reduce +CONSOLE MESSAGE: method some +CONSOLE MESSAGE: method subscribe +CONSOLE MESSAGE: method switchMap +CONSOLE MESSAGE: method take +CONSOLE MESSAGE: method takeUntil +CONSOLE MESSAGE: method toArray +CONSOLE MESSAGE: interface PromiseRejectionEvent : Event +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter promise +CONSOLE MESSAGE: getter reason +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: interface ReadableByteStreamController +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter byobRequest +CONSOLE MESSAGE: getter desiredSize +CONSOLE MESSAGE: method close +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method enqueue +CONSOLE MESSAGE: method error +CONSOLE MESSAGE: interface ReadableStream +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter locked +CONSOLE MESSAGE: method @@asyncIterator +CONSOLE MESSAGE: method cancel +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method getReader +CONSOLE MESSAGE: method pipeThrough +CONSOLE MESSAGE: method pipeTo +CONSOLE MESSAGE: method tee +CONSOLE MESSAGE: method values +CONSOLE MESSAGE: interface ReadableStreamBYOBReader +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter closed +CONSOLE MESSAGE: method cancel +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method read +CONSOLE MESSAGE: method releaseLock +CONSOLE MESSAGE: interface ReadableStreamBYOBRequest +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter view +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method respond +CONSOLE MESSAGE: method respondWithNewView +CONSOLE MESSAGE: interface ReadableStreamDefaultController +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter desiredSize +CONSOLE MESSAGE: method close +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method enqueue +CONSOLE MESSAGE: method error +CONSOLE MESSAGE: interface ReadableStreamDefaultReader +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter closed +CONSOLE MESSAGE: method cancel +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method read +CONSOLE MESSAGE: method releaseLock CONSOLE MESSAGE: interface ShadowRealm CONSOLE MESSAGE: attribute @@toStringTag CONSOLE MESSAGE: method constructor @@ -8,6 +183,110 @@ CONSOLE MESSAGE: interface ShadowRealmGlobalScope CONSOLE MESSAGE: attribute @@toStringTag CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: interface Subscriber +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter active +CONSOLE MESSAGE: getter signal +CONSOLE MESSAGE: method addTeardown +CONSOLE MESSAGE: method complete +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method error +CONSOLE MESSAGE: method next +CONSOLE MESSAGE: interface TransformStream +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter readable +CONSOLE MESSAGE: getter writable +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: interface TransformStreamDefaultController +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter desiredSize +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method enqueue +CONSOLE MESSAGE: method error +CONSOLE MESSAGE: method terminate +CONSOLE MESSAGE: interface URL +CONSOLE MESSAGE: static method canParse +CONSOLE MESSAGE: static method parse +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter hash +CONSOLE MESSAGE: getter host +CONSOLE MESSAGE: getter hostname +CONSOLE MESSAGE: getter href +CONSOLE MESSAGE: getter origin +CONSOLE MESSAGE: getter password +CONSOLE MESSAGE: getter pathname +CONSOLE MESSAGE: getter port +CONSOLE MESSAGE: getter protocol +CONSOLE MESSAGE: getter search +CONSOLE MESSAGE: getter searchParams +CONSOLE MESSAGE: getter username +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method toJSON +CONSOLE MESSAGE: method toString +CONSOLE MESSAGE: setter hash +CONSOLE MESSAGE: setter host +CONSOLE MESSAGE: setter hostname +CONSOLE MESSAGE: setter href +CONSOLE MESSAGE: setter password +CONSOLE MESSAGE: setter pathname +CONSOLE MESSAGE: setter port +CONSOLE MESSAGE: setter protocol +CONSOLE MESSAGE: setter search +CONSOLE MESSAGE: setter username +CONSOLE MESSAGE: interface URLPattern +CONSOLE MESSAGE: static method compareComponent +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter hasRegExpGroups +CONSOLE MESSAGE: getter hash +CONSOLE MESSAGE: getter hostname +CONSOLE MESSAGE: getter password +CONSOLE MESSAGE: getter pathname +CONSOLE MESSAGE: getter port +CONSOLE MESSAGE: getter protocol +CONSOLE MESSAGE: getter search +CONSOLE MESSAGE: getter username +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method exec +CONSOLE MESSAGE: method test +CONSOLE MESSAGE: interface URLSearchParams +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter size +CONSOLE MESSAGE: method @@iterator +CONSOLE MESSAGE: method append +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method delete +CONSOLE MESSAGE: method entries +CONSOLE MESSAGE: method forEach +CONSOLE MESSAGE: method get +CONSOLE MESSAGE: method getAll +CONSOLE MESSAGE: method has +CONSOLE MESSAGE: method keys +CONSOLE MESSAGE: method set +CONSOLE MESSAGE: method sort +CONSOLE MESSAGE: method toString +CONSOLE MESSAGE: method values +CONSOLE MESSAGE: interface WritableStream +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter locked +CONSOLE MESSAGE: method abort +CONSOLE MESSAGE: method close +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method getWriter +CONSOLE MESSAGE: interface WritableStreamDefaultController +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter signal +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method error +CONSOLE MESSAGE: interface WritableStreamDefaultWriter +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter closed +CONSOLE MESSAGE: getter desiredSize +CONSOLE MESSAGE: getter ready +CONSOLE MESSAGE: method abort +CONSOLE MESSAGE: method close +CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: method releaseLock +CONSOLE MESSAGE: method write CONSOLE MESSAGE: [NAMESPACES] CONSOLE MESSAGE: namespace console CONSOLE MESSAGE: attribute @@toStringTag
diff --git a/third_party/blink/web_tests/inspector-protocol/debugger/async-stacks-for-load-and-error-events-expected.txt b/third_party/blink/web_tests/inspector-protocol/debugger/async-stacks-for-load-and-error-events-expected.txt index dbf126d..7c20bc9 100644 --- a/third_party/blink/web_tests/inspector-protocol/debugger/async-stacks-for-load-and-error-events-expected.txt +++ b/third_party/blink/web_tests/inspector-protocol/debugger/async-stacks-for-load-and-error-events-expected.txt
@@ -1,10 +1,10 @@ Tests async stacks for load and error events Test load event.. onScriptLoad at :7:6 ---load-- -(anonymous) at test.js:3:11 +--script-- +(anonymous) at test.js:1:26 Test error event.. onScriptError at :7:6 ---error-- -(anonymous) at test.js:3:11 +--script-- +(anonymous) at test.js:1:22
diff --git a/third_party/blink/web_tests/virtual/error-iserror-enabled/README.md b/third_party/blink/web_tests/virtual/error-iserror-enabled/README.md new file mode 100644 index 0000000..dbfa27d --- /dev/null +++ b/third_party/blink/web_tests/virtual/error-iserror-enabled/README.md
@@ -0,0 +1,5 @@ +Error.isError is a Stage 3 TC39 proposal. This test suite is used for any +tests requiring `--js-error-iserror` until V8 ships the proposal, after which +this test suite can be removed. + +See https://github.com/tc39/proposal-is-error
diff --git a/third_party/blink/web_tests/virtual/error-iserror-enabled/external/wpt/webidl/ecmascript-binding/es-exceptions/DOMException-is-error.any-expected.txt b/third_party/blink/web_tests/virtual/error-iserror-enabled/external/wpt/webidl/ecmascript-binding/es-exceptions/DOMException-is-error.any-expected.txt new file mode 100644 index 0000000..d2490db --- /dev/null +++ b/third_party/blink/web_tests/virtual/error-iserror-enabled/external/wpt/webidl/ecmascript-binding/es-exceptions/DOMException-is-error.any-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/error-iserror-enabled/external/wpt/webidl/ecmascript-binding/es-exceptions/DOMException-is-error.any.worker-expected.txt b/third_party/blink/web_tests/virtual/error-iserror-enabled/external/wpt/webidl/ecmascript-binding/es-exceptions/DOMException-is-error.any.worker-expected.txt new file mode 100644 index 0000000..d2490db --- /dev/null +++ b/third_party/blink/web_tests/virtual/error-iserror-enabled/external/wpt/webidl/ecmascript-binding/es-exceptions/DOMException-is-error.any.worker-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/webaudio/AudioContext/media-playback-while-not-visible-permission-policy-interrupt-when-hidden.html b/third_party/blink/web_tests/webaudio/AudioContext/media-playback-while-not-visible-permission-policy-interrupt-when-hidden.html new file mode 100644 index 0000000..e94aae90 --- /dev/null +++ b/third_party/blink/web_tests/webaudio/AudioContext/media-playback-while-not-visible-permission-policy-interrupt-when-hidden.html
@@ -0,0 +1,177 @@ +<!DOCTYPE html> +<title>Test the behavior of AudioContext with the media-playback-while-not-rendered permission policy</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<body> + <script> + // The tests in this file depend on + //resources/media-playback-while-not-visible-permission-policy-audiocontext-frame.html + internals.settings.setAutoplayPolicy('no-user-gesture-required'); + + // Sets up an iframe with an AudioContext with the + // media-playback-while-not-visible permission policy disabled, set the + // iframe source to + // resources/media-playback-while-not-visible-permission-policy-audiocontext-frame.html + // and sets the iframe's AudioContext initial state to + // `expected_initial_state`. + async function setUpIframeAudioContextInitialState(expected_initial_state) { + if (document.readyState !=='complete'){ + await new Promise(resolve => { + window.addEventListener('load', resolve) + }) + } + + let iframe = document.createElement('iframe'); + iframe.id = 'audio-context-frame'; + iframe.allow = "media-playback-while-not-visible 'none'; autoplay *" + iframe.src = 'resources/media-playback-while-not-visible-permission-policy-audiocontext-frame.html'; + document.body.appendChild(iframe); + await new Promise(resolve => { + iframe.addEventListener('load', resolve) + }) + + + let initial_state = await queryAudioContextState(iframe); + if (initial_state === 'closed') { + assert_unreached('AudioContext initial state is closed'); + } + + if (initial_state === expected_initial_state) { + return; + } + + if (expected_initial_state === 'running') { + await sendCommandToAudioContext(iframe, 'resume'); + assert_equals(await queryAudioContextState(iframe), 'running'); + } else if (expected_initial_state === 'suspended') { + await sendCommandToAudioContext(iframe, 'suspend'); + assert_equals(await queryAudioContextState(iframe), 'suspended'); + } + } + + // Returns a promise that resolves when the iframe's AudioContext emits a + // 'statechange' event. The promise resolves with the new state of the + // AudioContext. Moreover, the event listener is removed after the promise + // resolves or if the promise times out (after 500ms). + function expectIframeAudioContextStateChangeEvent() { + return new Promise(resolve => { + function expectStateChangeEvent(event) { + if (event.data.operation !== 'statechange') { + return; + } + window.removeEventListener('message', expectStateChangeEvent); + resolve(event.data.value); + } + + window.addEventListener('message', expectStateChangeEvent); + setTimeout(() => { + window.removeEventListener('message', expectStateChangeEvent); + resolve('no state change'); + }, 500); + }) + } + + // Sends a message to the iframe to query the state of the AudioContext and + // returns a promise that resolves with the state of the AudioContext. The + // event listener is removed after the promise resolves. + function queryAudioContextState(iframe) { + return new Promise((resolve, reject) => { + window.addEventListener( + 'message', + function expectStateQueryResponse(event) { + if (event.data.operation !== 'getState') { + return; + } + window.removeEventListener('message', expectStateQueryResponse); + resolve(event.data.value); + }); + iframe.contentWindow.postMessage('getState', '*'); + }) + } + + // Sends a message to the iframe with a command that should be performed on + // the AudioContext. Returns a promise that resolves when the operation is + // completed. The event listener is removed after the promise resolves. + function sendCommandToAudioContext(iframe, command) { + return new Promise((resolve, reject) => { + window.addEventListener( + 'message', + function expectCommandResponse(event) { + if (event.data.operation !== command) { + return; + } + window.removeEventListener('message', expectCommandResponse); + resolve(); + }); + iframe.contentWindow.postMessage(command, '*'); + }) + } + + promise_test(async t => { + await setUpIframeAudioContextInitialState('running'); + let iframe = document.getElementById('audio-context-frame'); + + let statechange_promise = expectIframeAudioContextStateChangeEvent(); + iframe.style.setProperty('display', 'none'); + assert_equals(await statechange_promise, 'interrupted'); + + statechange_promise = expectIframeAudioContextStateChangeEvent(); + iframe.style.setProperty('display', 'block'); + assert_equals(await statechange_promise, 'running'); + + t.add_cleanup(() => { + document.body.removeChild(iframe); + }); + }, 'Hide and show an iframe with a running AudioContext'); + + promise_test(async t => { + await setUpIframeAudioContextInitialState('suspended'); + let iframe = document.getElementById('audio-context-frame'); + + // No state change should be observed and `timeout_promise` should + // resolve first. + let statechange_promise = expectIframeAudioContextStateChangeEvent(); + iframe.style.setProperty('display', 'none'); + assert_equals(await statechange_promise, 'no state change'); + + // Likewise, no state change should be observed and `timeout_promise` + // should resolve first. + statechange_promise = expectIframeAudioContextStateChangeEvent(); + iframe.style.setProperty('display', 'block'); + assert_equals(await statechange_promise, 'no state change'); + + t.add_cleanup(() => { + document.body.removeChild(iframe); + }); + }, 'Hide and show an iframe with a suspended AudioContext'); + + promise_test(async t => { + await setUpIframeAudioContextInitialState('suspended'); + let iframe = document.getElementById('audio-context-frame'); + + // No state change should be observed and `timeout_promise` should + // resolve first. + let statechange_promise = expectIframeAudioContextStateChangeEvent(); + iframe.style.setProperty('display', 'none'); + assert_equals(await statechange_promise, 'no state change'); + + // Calling resume() on a suspended hidden iframe should throw an + // InvalidStateError exception and put the iframe's AudioContext in the + // 'interrupted' state. + statechange_promise = expectIframeAudioContextStateChangeEvent(); + resume_audiocontext_promise = sendCommandToAudioContext(iframe, 'resume'); + assert_equals(await statechange_promise, 'interrupted'); + await resume_audiocontext_promise + + // Showing the iframe should resume the AudioContext, putting it in the + // 'running state'. + statechange_promise = expectIframeAudioContextStateChangeEvent(); + iframe.style.setProperty('display', 'block'); + assert_equals(await statechange_promise, 'running'); + + t.add_cleanup(() => { + document.body.removeChild(iframe); + }); + }, 'While the iframe is hidden with a suspended AudioContext, resume the AudioContext'); + </script> +</body> \ No newline at end of file
diff --git a/third_party/blink/web_tests/webaudio/AudioContext/resources/media-playback-while-not-visible-permission-policy-audiocontext-frame.html b/third_party/blink/web_tests/webaudio/AudioContext/resources/media-playback-while-not-visible-permission-policy-audiocontext-frame.html new file mode 100644 index 0000000..aded5ad5 --- /dev/null +++ b/third_party/blink/web_tests/webaudio/AudioContext/resources/media-playback-while-not-visible-permission-policy-audiocontext-frame.html
@@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html> + <body> + <script> + // This file is used for the webtest + //../media-playback-while-not-visible-permission-policy-interrupt-when-hidden. + // This file describes a document that contains an AudioContext and that + // can communicate with its embedder by using `postMessage`. The embedder + // can send messages to the document to query the state of the + // AudioContext, to resume it or to suspend it. Likewise, this document + // can send messages to the embedder to notify it of state changes in the + // AudioContext. + let audioCtx = new AudioContext(); + audioCtx.addEventListener('statechange', () => { + if (window.parent !== window){ + window.parent.postMessage({ + operation: 'statechange', value: audioCtx.state + }, '*'); + } + }); + + window.addEventListener('message', (event) => { + if (event.data === 'getState') { + window.parent.postMessage({ + operation: 'getState', value: audioCtx.state + }, '*'); + } else if (event.data === 'resume') { + audioCtx.resume() + .then(() => { + window.parent.postMessage({operation: 'resume', value: null}, '*') + }).catch((e) => { + window.parent.postMessage({operation: 'resume', value: null}, '*'); + }); + } else if (event.data === 'suspend') { + audioCtx.suspend().then(() => { + window.parent.postMessage({operation: 'suspend', value: null}, '*'); + }); + } + }); + + const oscillator = audioCtx.createOscillator(); + oscillator.connect(audioCtx.destination); + oscillator.start(); + </script> + </body> +</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-markers-computed.tentative.html b/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-markers-computed.tentative.html deleted file mode 100644 index df297b3..0000000 --- a/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-markers-computed.tentative.html +++ /dev/null
@@ -1,41 +0,0 @@ -<!DOCTYPE html> -<html> - -<head> - <meta charset="utf-8"> - <title>CSS Overflow: scroll-marker-group computed values</title> - <link rel="help" href="https://github.com/w3c/csswg-drafts/pull/10243"> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <script src="/css/support/computed-testcommon.js"></script> -</head> - -<body> - <style> - #target { scroll-marker-group: before; } - </style> - <div id="target"></div> - <script> - test_computed_value('scroll-marker-group', 'initial', 'none'); - test_computed_value('scroll-marker-group', 'inherit', 'none'); - test_computed_value('scroll-marker-group', 'unset', 'none'); - test_computed_value('scroll-marker-group', 'revert', 'none'); - - test_computed_value('scroll-marker-group', 'none'); - test_computed_value('scroll-marker-group', 'before'); - test_computed_value('scroll-marker-group', 'after'); - - test(() => { - let style = getComputedStyle(document.getElementById('target')); - assert_not_equals(Array.from(style).indexOf('scroll-marker-group'), -1); - }, 'The scroll-marker-group property shows up in CSSStyleDeclaration enumeration'); - - test(() => { - let style = document.getElementById('target').style; - assert_not_equals(style.cssText.indexOf('scroll-marker-group'), -1); - }, 'The scroll-marker-group property shows up in CSSStyleDeclaration.cssText'); - - </script> -</body> - -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-markers-invalid.tentative.html b/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-markers-invalid.tentative.html deleted file mode 100644 index 641d97d..0000000 --- a/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-markers-invalid.tentative.html +++ /dev/null
@@ -1,24 +0,0 @@ -<!DOCTYPE html> -<html> - -<head> - <meta charset="utf-8"> - <title>CSS Overflow: parsing scroll-marker-group with invalid values</title> - <link rel="help" href="https://github.com/w3c/csswg-drafts/pull/10243"> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <script src="/css/support/parsing-testcommon.js"></script> -</head> - -<body> - <div id="target"></div> - <script> - test_invalid_value('scroll-marker-group', '10'); - test_invalid_value('scroll-marker-group', 'true'); - test_invalid_value('scroll-marker-group', 'default'); - test_invalid_value('scroll-marker-group', 'set'); - test_invalid_value('scroll-marker-group', 'before, after'); - </script> -</body> - -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-markers-valid.tentative.html b/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-markers-valid.tentative.html deleted file mode 100644 index 2856cb8..0000000 --- a/third_party/blink/web_tests/wpt_internal/css/css-overflow/parsing/scroll-markers-valid.tentative.html +++ /dev/null
@@ -1,27 +0,0 @@ -<!DOCTYPE html> -<html> - -<head> - <meta charset="utf-8"> - <title>CSS Overflow: parsing scroll-marker-group with valid values</title> - <link rel="help" href="https://github.com/w3c/csswg-drafts/pull/10243"> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <script src="/css/support/parsing-testcommon.js"></script> -</head> - -<body> - <div id="target"></div> - <script> - test_valid_value('scroll-marker-group', 'initial'); - test_valid_value('scroll-marker-group', 'inherit'); - test_valid_value('scroll-marker-group', 'unset'); - test_valid_value('scroll-marker-group', 'revert'); - - test_valid_value("scroll-marker-group", "none"); - test_valid_value("scroll-marker-group", "before"); - test_valid_value("scroll-marker-group", "after"); - </script> -</body> - -</html> \ No newline at end of file
diff --git a/third_party/boringssl/src b/third_party/boringssl/src index f49081b..59fc518 160000 --- a/third_party/boringssl/src +++ b/third_party/boringssl/src
@@ -1 +1 @@ -Subproject commit f49081b4ef4e99bae452e05170d8433807bd70e9 +Subproject commit 59fc5189630ab1409555647f361ece64930a50ca
diff --git a/third_party/catapult b/third_party/catapult index 452b85e..abd0e1e 160000 --- a/third_party/catapult +++ b/third_party/catapult
@@ -1 +1 @@ -Subproject commit 452b85ea51998d34386f3b7f8bd711ba12e5d4b7 +Subproject commit abd0e1e8ccd7f38681b8c9503bbf4c14220c86f3
diff --git a/third_party/chromium-variations b/third_party/chromium-variations index 57ea908..75345f6 160000 --- a/third_party/chromium-variations +++ b/third_party/chromium-variations
@@ -1 +1 @@ -Subproject commit 57ea908f6afb7ef24fc1d28158837173a641617d +Subproject commit 75345f6fdba14f81b63ccf0530c6fb5adfc9a103
diff --git a/third_party/closure_compiler/externs/virtual_keyboard_private.js b/third_party/closure_compiler/externs/virtual_keyboard_private.js index 8653bb66..b6e5fd8 100644 --- a/third_party/closure_compiler/externs/virtual_keyboard_private.js +++ b/third_party/closure_compiler/externs/virtual_keyboard_private.js
@@ -151,7 +151,7 @@ chrome.virtualKeyboardPrivate.getKeyboardConfig = function(callback) {}; /** - * Opens chrome://os-settings/osLanguages page. + * Opens chrome://os-settings/osLanguages/input page. */ chrome.virtualKeyboardPrivate.openSettings = function() {};
diff --git a/third_party/crossbench b/third_party/crossbench index ed3404ed..cdb37ea 160000 --- a/third_party/crossbench +++ b/third_party/crossbench
@@ -1 +1 @@ -Subproject commit ed3404ed0b31ef20837f60d2aef1e405284e9549 +Subproject commit cdb37eabb31cf3b1723a1692b9762158f197730a
diff --git a/third_party/dawn b/third_party/dawn index afc9c13..eaeba81 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit afc9c139de7ea3a911171da83ac6922a0089fe34 +Subproject commit eaeba81b24c7b6e0af1b621c3a3479bfb52a1fab
diff --git a/third_party/depot_tools b/third_party/depot_tools index cbead19..f548b21 160000 --- a/third_party/depot_tools +++ b/third_party/depot_tools
@@ -1 +1 @@ -Subproject commit cbead190e5a4badb427fda83c7a57868b634511e +Subproject commit f548b21cd3554d013ac0bc53a6cb1ae0de79e2f8
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 6551e43..7d0851a 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 6551e43966d7dd4d085ca6c0fc05a9ef2f3f4176 +Subproject commit 7d0851a8ce15f96e59c8c25fd2b5db32b0475d3d
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index bec79b4..1ce02d5 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-3-25-g59320b2d3 -Revision: 59320b2d3c2584ac01914ed0deff64bcc8fb23b2 +Version: VER-2-13-3-26-g38272bf85 +Revision: 38272bf85341348eb0a5162ba4e1c95d370f9bce CPEPrefix: cpe:/a:freetype:freetype:2.13.3 License: FTL License File: src/docs/FTL.TXT
diff --git a/third_party/freetype/src b/third_party/freetype/src index 59320b2..38272bf 160000 --- a/third_party/freetype/src +++ b/third_party/freetype/src
@@ -1 +1 @@ -Subproject commit 59320b2d3c2584ac01914ed0deff64bcc8fb23b2 +Subproject commit 38272bf85341348eb0a5162ba4e1c95d370f9bce
diff --git a/third_party/libc++abi/src b/third_party/libc++abi/src index 574b92b..77e59bec 160000 --- a/third_party/libc++abi/src +++ b/third_party/libc++abi/src
@@ -1 +1 @@ -Subproject commit 574b92bc1d7aa586ed30e4e9923041d1ec495017 +Subproject commit 77e59bec0fb93d9733378e1b6188bae0efdbc32e
diff --git a/third_party/llvm-libc/src b/third_party/llvm-libc/src index c8307c5..09341da 160000 --- a/third_party/llvm-libc/src +++ b/third_party/llvm-libc/src
@@ -1 +1 @@ -Subproject commit c8307c52cdf40133e725a3d0912e2fa60ef014b3 +Subproject commit 09341dae519a08cbb4b0c58f5409b722073d2eff
diff --git a/third_party/pdfium b/third_party/pdfium index bea1014..b69783f 160000 --- a/third_party/pdfium +++ b/third_party/pdfium
@@ -1 +1 @@ -Subproject commit bea10144d15d4f9f55d78095dcbf931c3d3b2813 +Subproject commit b69783fd189976dd4625c7dcd9c07921b94d4a3c
diff --git a/third_party/perfetto b/third_party/perfetto index 6361af2..5bf4e2a 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit 6361af291ce8ffd1f992fec3f44483c00bba124e +Subproject commit 5bf4e2a65d76d5a603ff175222d1513f71d28a0b
diff --git a/third_party/skia b/third_party/skia index 7fc6934..804042d 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit 7fc6934b20348e6609552918b9d09da0d6f03457 +Subproject commit 804042d752991d6753dd17f8585d6f8fe951492f
diff --git a/third_party/tflite/src b/third_party/tflite/src index 3ed58a7..b25df27 160000 --- a/third_party/tflite/src +++ b/third_party/tflite/src
@@ -1 +1 @@ -Subproject commit 3ed58a749e37e7e45f1771e9c60f0fffbf139d4c +Subproject commit b25df276c8e912c22f57263ffcae6ca8f4c64342
diff --git a/third_party/webrtc b/third_party/webrtc index 021cf5a..6ef206a 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit 021cf5ac3ef6c5ffd8b65c7365d0f6d7ff456b9c +Subproject commit 6ef206aa1a92ec09f936105bc19f50ece0ea297b
diff --git a/tools/clang/spanify/Spanifier.cpp b/tools/clang/spanify/Spanifier.cpp index f14c1095..049a2e03 100644 --- a/tools/clang/spanify/Spanifier.cpp +++ b/tools/clang/spanify/Spanifier.cpp
@@ -540,7 +540,7 @@ clang::SourceManager& source_manager = *result.SourceManager; const auto* array_variable = - result.Nodes.getNodeAs<clang::VarDecl>("array_variable"); + result.Nodes.getNodeAs<clang::VarDecl>("array_variable_rhs"); const std::string& array_variable_as_string = array_variable->getNameAsString(); @@ -572,6 +572,7 @@ Node n; n.replacement = replacement_directive; + n.is_deref_expr = true; return n; } @@ -1152,6 +1153,12 @@ return getNodeFromCallToExternalFunction(result); } + if (const auto* sizeof_array_expr = + result.Nodes.getNodeAs<clang::UnaryExprOrTypeTraitExpr>( + "sizeof_array_expr")) { + return getNodeFromSizeOfArrayExpr(sizeof_array_expr, result); + } + if (result.Nodes.getNodeAs<clang::VarDecl>("array_variable")) { return getNodeFromArrayType(result); } @@ -1167,12 +1174,6 @@ return getNodeFromPointerTypeLoc(type_loc, result); } - if (const auto* sizeof_array_expr = - result.Nodes.getNodeAs<clang::UnaryExprOrTypeTraitExpr>( - "sizeof_array_expr")) { - return getNodeFromSizeOfArrayExpr(sizeof_array_expr, result); - } - if (auto* rhs_array_var = result.Nodes.getNodeAs<clang::VarDecl>("array_variable")) { return getProxyVarNodeFromArrayVariable(rhs_array_var, result); @@ -1584,12 +1585,16 @@ arraySubscriptExpr(hasLHS(declRefExpr(to(array_variable))))))); match_finder_.addMatcher(buffer_expr2, &potential_nodes_); + auto c_style_array_var = varDecl(hasType(arrayType()), unless(exclusions), + unless(hasExternalFormalLinkage())); + // `sizeof(c_array)` is rewritten to // `std_array.size() * sizeof(element_size)`. - auto sizeof_array_expr = - traverse(clang::TK_IgnoreUnlessSpelledInSource, - sizeOfExpr(has(declRefExpr(to(array_variable)))) - .bind("sizeof_array_expr")); + auto sizeof_array_expr = traverse( + clang::TK_IgnoreUnlessSpelledInSource, + sizeOfExpr( + has(declRefExpr(to(c_style_array_var.bind("array_variable_rhs"))))) + .bind("sizeof_array_expr")); match_finder_.addMatcher(sizeof_array_expr, &potential_nodes_); auto deref_expression = traverse( @@ -1635,8 +1640,7 @@ // When passing c-style arrays to third_party functions as parameters, we // need to add `.data()` to extract the pointer and keep things compiling. - auto c_style_array_var = varDecl(hasType(arrayType()), unless(exclusions), - unless(hasExternalFormalLinkage())); + // // Functions that are annotated with UNSAFE_BUFFER_USAGE also get this // treatment because the annotation means it was left there intentionally. // And since they emit warnings we can easily find and spanify them later.
diff --git a/tools/clang/spanify/tests/array-external-call-expected.cc b/tools/clang/spanify/tests/array-external-call-expected.cc index 647efa5..d548ba5d 100644 --- a/tools/clang/spanify/tests/array-external-call-expected.cc +++ b/tools/clang/spanify/tests/array-external-call-expected.cc
@@ -6,6 +6,7 @@ #include <cstdint> #include <cstring> #include <iterator> +#include <string_view> void fct() { // Expected rewrite: @@ -57,3 +58,12 @@ std::ranges::find(data, 'a'); std::ignore = std::ranges::min(data); } + +void fct4() { + // Adding .data() works for std::string_view rewrites too. + // Expected rewrite: + // const std::string_view buf = "123456789"; + const std::string_view buf = "123456789"; + std::ignore = buf[1]; + std::ignore = memcmp(buf.data(), "xxx456789", 3); +}
diff --git a/tools/clang/spanify/tests/array-external-call-original.cc b/tools/clang/spanify/tests/array-external-call-original.cc index 7d67fa66..b4f589c2c 100644 --- a/tools/clang/spanify/tests/array-external-call-original.cc +++ b/tools/clang/spanify/tests/array-external-call-original.cc
@@ -56,3 +56,12 @@ std::ranges::find(data, 'a'); std::ignore = std::ranges::min(data); } + +void fct4() { + // Adding .data() works for std::string_view rewrites too. + // Expected rewrite: + // const std::string_view buf = "123456789"; + const char buf[] = "123456789"; + std::ignore = buf[1]; + std::ignore = memcmp(buf, "xxx456789", 3); +}
diff --git a/tools/clang/spanify/tests/array-tests-expected.cc b/tools/clang/spanify/tests/array-tests-expected.cc index be2dc30..192ed8df 100644 --- a/tools/clang/spanify/tests/array-tests-expected.cc +++ b/tools/clang/spanify/tests/array-tests-expected.cc
@@ -4,6 +4,7 @@ #include <array> #include <cstdint> +#include <cstring> #include <tuple> // No rewrite expected. @@ -90,3 +91,11 @@ std::ignore = sizeof *buf; std::ignore = sizeof buf[0]; } + +// Test for crbug.com/383424943. +void crbug_383424943() { + // No rewrite expected. + int buf[]{1}; + // Using sizeof was causing buf to be rewritten. + memset(buf, 'x', sizeof(buf)); +}
diff --git a/tools/clang/spanify/tests/array-tests-original.cc b/tools/clang/spanify/tests/array-tests-original.cc index 13e8ced..bb800fb 100644 --- a/tools/clang/spanify/tests/array-tests-original.cc +++ b/tools/clang/spanify/tests/array-tests-original.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <cstdint> +#include <cstring> #include <tuple> // No rewrite expected. @@ -89,3 +90,11 @@ std::ignore = sizeof *buf; std::ignore = sizeof buf[0]; } + +// Test for crbug.com/383424943. +void crbug_383424943() { + // No rewrite expected. + int buf[]{1}; + // Using sizeof was causing buf to be rewritten. + memset(buf, 'x', sizeof(buf)); +}
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 4fbed86..c58a7bf 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -18222,6 +18222,7 @@ <int value="-870120067" label="EnableSearchBoxSelection:enabled"/> <int value="-870118210" label="AutofillEnableCardBenefitsSync:enabled"/> <int value="-869690461" label="ShoppingListTrackByDefault:enabled"/> + <int value="-869149210" label="ProjectorUseDVSPlaybackEndpoint:enabled"/> <int value="-868138290" label="CrostiniPortForwarding:disabled"/> <int value="-868041476" label="OmniboxFocusTriggersSRPZeroSuggest:enabled"/> <int value="-867571486" label="PrivateStateTokens:disabled"/> @@ -18309,6 +18310,7 @@ <int value="-836123854" label="wallet-service-use-sandbox"/> <int value="-835672415" label="PointerEventV1SpecCapturing:disabled"/> <int value="-835627918" label="QuickSettingsNetworkRevamp:enabled"/> + <int value="-835487878" label="FedCmDelegation:enabled"/> <int value="-835331907" label="TabOutlinesInLowContrastThemes:disabled"/> <int value="-835242361" label="OmniboxAdaptiveSuggestionsCount:enabled"/> <int value="-834661509" label="ModalPermissionPrompts:disabled"/> @@ -20760,6 +20762,7 @@ <int value="147342055" label="ChromeHomeClearUrlOnOpen:disabled"/> <int value="147373243" label="enable-deferred-image-decoding"/> <int value="147645817" label="DnsHttpssvc:enabled"/> + <int value="147845068" label="ProjectorUseDVSPlaybackEndpoint:disabled"/> <int value="147982046" label="OfflineAutoFetch:enabled"/> <int value="148094867" label="IwaKeyDistributionComponent:enabled"/> <int value="148142535" label="ShortcutCustomization:disabled"/> @@ -22260,6 +22263,7 @@ <int value="743124458" label="OmniboxSuggestionAnswerMigration:disabled"/> <int value="743696247" label="RedInterstitialFacelift:enabled"/> <int value="743714331" label="HelpAppLauncherSearch:enabled"/> + <int value="744050521" label="FedCmDelegation:disabled"/> <int value="744050675" label="PrivacySandboxPrivacyGuideAdTopics:disabled"/> <int value="744342941" label="SafetyCheckChromeCleanerChild:enabled"/> <int value="745541471" label="PaintHolding:disabled"/> @@ -34232,6 +34236,7 @@ <int value="267" label="WindowControlsOverlay"/> <int value="268" label="FetchPriority"/> <int value="269" label="Highlight"/> + <int value="270" label="DRAFT_ErrorIsError"/> </enum> <!-- LINT.ThenChange(//third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom:WebDXFeature) -->
diff --git a/tools/metrics/histograms/metadata/accessibility/histograms.xml b/tools/metrics/histograms/metadata/accessibility/histograms.xml index 2a80bf2..b5c953f 100644 --- a/tools/metrics/histograms/metadata/accessibility/histograms.xml +++ b/tools/metrics/histograms/metadata/accessibility/histograms.xml
@@ -2119,7 +2119,7 @@ <histogram name="Accessibility.Performance.AXObjectCacheImpl.Incremental.{DataType}" - units="bytes" expires_after="2025-04-13"> + units="bytes" expires_after="2025-06-15"> <owner>kevers@chromium.org</owner> <owner>chrome-a11y-core@google.com</owner> <summary> @@ -2948,7 +2948,7 @@ </histogram> <histogram name="Accessibility.ScreenAI.OCR.Time.PDF" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>rhalavati@chromium.org</owner> <owner>chrome-a11y-core@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index a13ca76..88d2fe1 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -375,7 +375,7 @@ </histogram> <histogram name="Android.AdaptiveToolbarButton.Variant.OnPageLoad" - enum="AdaptiveToolbarButtonVariant" expires_after="2025-04-13"> + enum="AdaptiveToolbarButtonVariant" expires_after="2025-06-15"> <owner>shaktisahu@chromium.org</owner> <owner>chrome-segmentation-platform@google.com</owner> <summary> @@ -624,7 +624,7 @@ </histogram> <histogram name="Android.BackgroundTaskScheduler.TaskFinished.{TaskType}" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>nyquist@chromium.org</owner> <owner>shaktisahu@chromium.org</owner> <summary> @@ -4884,7 +4884,7 @@ </histogram> <histogram name="Android.TabMultiSelectV2.BookmarkTabsCount" units="count" - expires_after="2025-01-30"> + expires_after="2025-06-30"> <owner>ckitagawa@chromium.org</owner> <owner>bjfong@google.com</owner> <owner>fredmello@chromium.org</owner> @@ -4896,7 +4896,7 @@ </histogram> <histogram name="Android.TabMultiSelectV2.SharingState" - enum="TabListEditorShareActionState" expires_after="2025-01-30"> + enum="TabListEditorShareActionState" expires_after="2025-06-30"> <owner>ckitagawa@chromium.org</owner> <owner>bjfong@google.com</owner> <owner>fredmello@chromium.org</owner> @@ -4907,7 +4907,7 @@ </histogram> <histogram name="Android.TabMultiSelectV2.TimeSinceLastShown" units="ms" - expires_after="2025-01-30"> + expires_after="2025-06-30"> <owner>ckitagawa@chromium.org</owner> <owner>fredmello@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml index 7474b8f..6fb0288 100644 --- a/tools/metrics/histograms/metadata/apps/histograms.xml +++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -2072,7 +2072,7 @@ </histogram> <histogram name="Apps.AppListPlayStoreQueryState" - enum="AppListPlayStoreQueryState" expires_after="2025-04-13"> + enum="AppListPlayStoreQueryState" expires_after="2025-06-15"> <owner>tby@chromium.org</owner> <owner>ypitsishin@google.com</owner> <owner>chrome-knowledge-eng@google.com</owner> @@ -2189,7 +2189,7 @@ </histogram> <histogram name="Apps.AppsCountPerInstallReason.{AppType}.{InstallReason}" - units="Apps" expires_after="2025-04-13"> + units="Apps" expires_after="2025-06-15"> <owner>ovn@google.com</owner> <owner>cros-web-apps-team@google.com</owner> <component>1389907</component> @@ -2329,7 +2329,7 @@ </histogram> <histogram name="Apps.DefaultAppLaunch{DefaultAppLaunchSource}" - enum="DefaultAppName" expires_after="2025-04-13"> + enum="DefaultAppName" expires_after="2025-06-15"> <owner>ovn@google.com</owner> <owner>cros-web-apps-team@google.com</owner> <owner>cros-device-enablement@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml index cc681f5..64d1ee0 100644 --- a/tools/metrics/histograms/metadata/arc/histograms.xml +++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -838,7 +838,7 @@ <histogram name="Arc.CloudDpc{TimedCloudDpcOp}.TimeDelta{SuccessFailure}{ArcUserTypes}" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>batoon@google.com</owner> <owner>mhasank@google.com</owner> <owner>arc-commercial@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/ash/enums.xml b/tools/metrics/histograms/metadata/ash/enums.xml index 40d975f9..c6178fd 100644 --- a/tools/metrics/histograms/metadata/ash/enums.xml +++ b/tools/metrics/histograms/metadata/ash/enums.xml
@@ -2378,6 +2378,8 @@ <int value="56" label="Copy Image To Clipboard Action"/> <int value="57" label="Capture Mode Text Copied"/> <int value="58" label="Coral Saved Groups Limit Max"/> + <int value="59" label="Scanner Action Success"/> + <int value="60" label="Scanner Action Failure"/> </enum> <enum name="TogglePickerAction">
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 9e2ca2e..62762ee7 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -6838,7 +6838,7 @@ </histogram> <histogram name="Ash.Overview.DeskBarInitLatency" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>esum@google.com</owner> <owner>cros-sw-perf@google.com</owner> <summary> @@ -8950,7 +8950,7 @@ </histogram> <histogram name="Ash.Smoothness.PercentDroppedFrames_1sWindow2{Stage}" - units="%" expires_after="2025-04-13"> + units="%" expires_after="2025-06-15"> <owner>xiyuan@chromium.org</owner> <owner>cros-sw-perf@google.com</owner> <summary> @@ -10074,7 +10074,7 @@ </histogram> <histogram name="Ash.Wallpaper.Type" enum="WallpaperType" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>kuscher@google.com</owner> <owner>cros-p13n-eng@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml b/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml index feb9d620..637d13cc 100644 --- a/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml +++ b/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml
@@ -1576,7 +1576,7 @@ </histogram> <histogram name="Conversions.{ReportType}.ReportRetriesTillSuccessOrFailure" - enum="ConversionReportSendRetryCount" expires_after="2025-04-13"> + enum="ConversionReportSendRetryCount" expires_after="2025-06-15"> <owner>tquintanilla@chromium.org</owner> <owner>johnidel@chromium.org</owner> <owner>measurement-api-dev+metrics@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index 2e76a181..3614933 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -794,7 +794,7 @@ </histogram> <histogram name="Autofill.AddressesSuppressedForDisuse" units="addresses" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary> @@ -819,7 +819,7 @@ </histogram> <histogram name="Autofill.AddressProfileImportRequirements" - enum="AutofillAddressProfileImportRequirement" expires_after="2025-04-13"> + enum="AutofillAddressProfileImportRequirement" expires_after="2025-06-15"> <owner>koerber@google.com</owner> <owner>battre@chromium.org</owner> <summary> @@ -2291,7 +2291,7 @@ </histogram> <histogram name="Autofill.EditedAutofilledFieldAtSubmission2.Aggregate" - enum="AutofilledFieldUserEditingStatus" expires_after="2025-04-13"> + enum="AutofilledFieldUserEditingStatus" expires_after="2025-06-15"> <owner>koerber@google.com</owner> <owner>battre@google.com</owner> <summary> @@ -2303,7 +2303,7 @@ <histogram name="Autofill.EditedAutofilledFieldAtSubmission2.ByFieldType" enum="AutofilledFieldUserEditingStatusByFieldType" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>koerber@google.com</owner> <owner>battre@google.com</owner> <summary> @@ -2570,7 +2570,7 @@ <histogram name="Autofill.FieldPredictionQuality.Aggregate{AutofillFieldPredictionSource}" - enum="AutofillFieldPredictionQuality" expires_after="2025-04-13"> + enum="AutofillFieldPredictionQuality" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary> @@ -2586,7 +2586,7 @@ <histogram name="Autofill.FieldPredictionQuality.ByFieldType{AutofillFieldPredictionSource}" - enum="AutofillFieldPredictionQualityByFieldType" expires_after="2025-04-13"> + enum="AutofillFieldPredictionQualityByFieldType" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary> @@ -2742,7 +2742,7 @@ </histogram> <histogram name="Autofill.FormEvents.{AddressFormType}" - enum="AutofillFormEvent" expires_after="2025-04-13"> + enum="AutofillFormEvent" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>koerber@google.com</owner> <owner>chrome-autofill-alerts@google.com</owner> @@ -2979,7 +2979,7 @@ </histogram> <histogram name="Autofill.Funnel.FillAfterSuggestion.{FormType}" - enum="BooleanAutofillFillAfterSuggestion" expires_after="2025-04-13"> + enum="BooleanAutofillFillAfterSuggestion" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary> @@ -3073,7 +3073,7 @@ </histogram> <histogram name="Autofill.Funnel.SuggestionAfterInteraction.{FormType}" - enum="BooleanAutofillSuggestionAfterInteraction" expires_after="2025-04-13"> + enum="BooleanAutofillSuggestionAfterInteraction" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary> @@ -3366,7 +3366,7 @@ </histogram> <histogram name="Autofill.KeyMetrics.FillingAcceptance.{FormType}" - enum="BooleanAutofillFillingAcceptance" expires_after="2025-04-13"> + enum="BooleanAutofillFillingAcceptance" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary> @@ -3379,7 +3379,7 @@ </histogram> <histogram name="Autofill.KeyMetrics.FillingAssistance.{FormType}" - enum="BooleanAutofillFillingAssistance" expires_after="2025-04-13"> + enum="BooleanAutofillFillingAssistance" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary> @@ -3395,7 +3395,7 @@ </histogram> <histogram name="Autofill.KeyMetrics.FillingCorrectness.{FormType}" - enum="BooleanAutofillFillingCorrectness" expires_after="2025-04-13"> + enum="BooleanAutofillFillingCorrectness" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary> @@ -3406,7 +3406,7 @@ </histogram> <histogram name="Autofill.KeyMetrics.FillingReadiness.{FormType}" - enum="BooleanAutofillFillingReadiness" expires_after="2025-04-13"> + enum="BooleanAutofillFillingReadiness" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary> @@ -3421,7 +3421,7 @@ </histogram> <histogram name="Autofill.KeyMetrics.FormSubmission.Autofilled.{FormType}" - enum="BooleanAutofillSubmission" expires_after="2025-04-13"> + enum="BooleanAutofillSubmission" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary> @@ -3437,7 +3437,7 @@ </histogram> <histogram name="Autofill.KeyMetrics.FormSubmission.NotAutofilled.{FormType}" - enum="BooleanAutofillSubmission" expires_after="2025-04-13"> + enum="BooleanAutofillSubmission" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary> @@ -5217,7 +5217,7 @@ </histogram> <histogram name="Autofill.ScanCreditCard.Completed" enum="BooleanCompleted" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> <summary>Whether a credit card scan was completed or cancelled.</summary> @@ -5238,7 +5238,7 @@ </histogram> <histogram name="Autofill.ScanCreditCardPrompt" - enum="AutofillScanCreditCardPrompt" expires_after="2025-04-13"> + enum="AutofillScanCreditCardPrompt" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>koerber@chromium.org</owner> <owner>chrome-autofill-alerts@google.com</owner> @@ -6919,7 +6919,7 @@ </histogram> <histogram name="Autofill.WebView.AutofillSession" enum="AutofillSessionStates" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary>Records the state of an autofill session.</summary> @@ -7104,7 +7104,7 @@ </histogram> <histogram name="Autofill.WebView.PrefillRequestState" - enum="AndroidAutofillPrefillRequestState" expires_after="2025-04-13"> + enum="AndroidAutofillPrefillRequestState" expires_after="2025-06-15"> <owner>jkeitel@google.com</owner> <owner>jihadghanna@google.com</owner> <owner>elabadysayed@chromium.org</owner> @@ -7162,7 +7162,7 @@ </histogram> <histogram name="Autofill.WebView.SubmissionSource" - enum="AutofillSubmissionSource" expires_after="2025-04-13"> + enum="AutofillSubmissionSource" expires_after="2025-06-15"> <owner>battre@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary>Records the source of form submission.</summary>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml index ba7cea8..61fd1b6 100644 --- a/tools/metrics/histograms/metadata/blink/histograms.xml +++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -661,7 +661,7 @@ </histogram> <histogram base="true" name="Blink.CompositingCommit.UpdateTime" - units="microseconds" expires_after="2025-04-13"> + units="microseconds" expires_after="2025-06-15"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimeSuffixes" --> <owner>pdr@chromium.org</owner> @@ -2341,7 +2341,7 @@ </histogram> <histogram base="true" name="Blink.ForcedStyleAndLayout.UpdateTime" - units="microseconds" expires_after="2025-04-13"> + units="microseconds" expires_after="2025-06-15"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimeSuffixes" --> <owner>pdr@chromium.org</owner> @@ -2835,7 +2835,7 @@ </histogram> <histogram base="true" name="Blink.IntersectionObservation.UpdateTime" - units="microseconds" expires_after="2025-04-13"> + units="microseconds" expires_after="2025-06-15"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimeSuffixes" --> <owner>pdr@chromium.org</owner> @@ -2955,7 +2955,7 @@ <histogram name="Blink.Layout.InlineNode.ShapeText.TotalTime.InOutermostMainFrame3" - units="microseconds" expires_after="2025-04-13"> + units="microseconds" expires_after="2025-06-15"> <owner>chikamune@chromium.org</owner> <owner> src/third_party/blink/renderer/core/lcp_critical_path_predictor/OWNERS @@ -2969,18 +2969,8 @@ </summary> </histogram> -<histogram name="Blink.Layout.RebuildFragmentTreeSpine" units="microseconds" - expires_after="2025-01-26"> - <owner>tkent@chromium.org</owner> - <owner>layout-dev@chromium.org</owner> - <summary> - Time spent to rebuild container physical fragments, recorded on sub-tree - root layout. - </summary> -</histogram> - <histogram name="Blink.Layout.SVGImage.Count.InOutermostMainFrame" - units="count" expires_after="2025-01-26"> + units="count" expires_after="2025-12-01"> <owner>chikamune@chromium.org</owner> <owner> src/third_party/blink/renderer/core/lcp_critical_path_predictor/OWNERS @@ -3024,7 +3014,7 @@ </histogram> <histogram base="true" name="Blink.Layout.UpdateTime" units="microseconds" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimeSuffixes" --> <owner>pdr@chromium.org</owner> @@ -3203,7 +3193,7 @@ </histogram> <histogram name="Blink.LCPP.LCPElementLocatorSize" units="bytes" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>kouhei@chromium.org</owner> <owner> src/third_party/blink/renderer/core/lcp_critical_path_predictor/OWNERS @@ -3687,7 +3677,7 @@ </histogram> <histogram base="true" name="Blink.MainFrame.UpdateTime" units="microseconds" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimeSuffixes" --> <owner>pdr@chromium.org</owner> @@ -3946,7 +3936,7 @@ </histogram> <histogram base="true" name="Blink.Paint.UpdateTime" units="microseconds" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimeSuffixes" --> <owner>pdr@chromium.org</owner> @@ -4667,7 +4657,7 @@ </histogram> <histogram name="Blink.UpdateViewportIntersection.UpdateTime" - units="microseconds" expires_after="2025-04-13"> + units="microseconds" expires_after="2025-06-15"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimeSuffixes" --> <owner>pdr@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/bookmarks/histograms.xml b/tools/metrics/histograms/metadata/bookmarks/histograms.xml index 025091b..1df27b9e 100644 --- a/tools/metrics/histograms/metadata/bookmarks/histograms.xml +++ b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
@@ -260,7 +260,7 @@ </histogram> <histogram name="Bookmarks.IdsReassigned.OnProfileLoad{BookmarksFileType}" - enum="BooleanReassigned" expires_after="2025-04-13"> + enum="BooleanReassigned" expires_after="2025-06-15"> <owner>mastiz@chromium.org</owner> <owner>arthurmilchior@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml index 96fdc015..1f1ddaa2 100644 --- a/tools/metrics/histograms/metadata/browser/histograms.xml +++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -651,7 +651,7 @@ </histogram> <histogram name="Browser.MainThreadsCongestion{UsageScenario}" units="janks" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>pmonette@chromium.org</owner> <owner>catan-team@chromium.org</owner> <summary> @@ -994,7 +994,7 @@ </histogram> <histogram name="Browser.Tabs.TabSwitchResult3{TabSwitchingType}" - enum="TabSwitchResult2" expires_after="2025-04-13"> + enum="TabSwitchResult2" expires_after="2025-06-15"> <owner>fdoray@chromium.org</owner> <owner>joenotcharles@google.com</owner> <owner>catan-team@chromium.org</owner> @@ -1020,7 +1020,7 @@ </histogram> <histogram name="Browser.Tabs.TotalSwitchDuration3{TabSwitchingType}" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>jonross@chromium.org</owner> <owner>joenotcharles@google.com</owner> <owner>catan-team@chromium.org</owner> @@ -1034,7 +1034,7 @@ </histogram> <histogram name="Browser.WindowCount.Guest" units="units" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>rhalavati@chromium.org</owner> <owner>chrome-privacy-core@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/chrome/histograms.xml b/tools/metrics/histograms/metadata/chrome/histograms.xml index 3ad1c1f..ff9876c 100644 --- a/tools/metrics/histograms/metadata/chrome/histograms.xml +++ b/tools/metrics/histograms/metadata/chrome/histograms.xml
@@ -358,7 +358,7 @@ </histogram> <histogram name="ChromeColors.ColorType" enum="ChromeColorType" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>tiborg@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml index a0b4f98..3dcee3c4 100644 --- a/tools/metrics/histograms/metadata/chromeos/histograms.xml +++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -1706,7 +1706,7 @@ </histogram> <histogram name="ChromeOS.HardwareVerifier.Report.IsCompliant" enum="Boolean" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>itspeter@chromium.org</owner> <owner>stimim@chromium.org</owner> <owner>chromeos-runtime-probe@google.com</owner> @@ -1714,7 +1714,7 @@ </histogram> <histogram name="ChromeOS.HardwareVerifier.TimeToFinish" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>itspeter@chromium.org</owner> <owner>stimim@chromium.org</owner> <owner>chromeos-runtime-probe@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/commerce/histograms.xml b/tools/metrics/histograms/metadata/commerce/histograms.xml index 61f72191..f3415ca 100644 --- a/tools/metrics/histograms/metadata/commerce/histograms.xml +++ b/tools/metrics/histograms/metadata/commerce/histograms.xml
@@ -875,7 +875,7 @@ </histogram> <histogram name="Commerce.Subscriptions.TrackResult" - enum="ShoppingSubscriptionsRequestStatus" expires_after="2025-04-13"> + enum="ShoppingSubscriptionsRequestStatus" expires_after="2025-06-15"> <owner>mdjones@chromium.org</owner> <owner>ayman@chromium.org</owner> <owner>chrome-shopping@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/cookie/histograms.xml b/tools/metrics/histograms/metadata/cookie/histograms.xml index f852fee..f0e3a31d 100644 --- a/tools/metrics/histograms/metadata/cookie/histograms.xml +++ b/tools/metrics/histograms/metadata/cookie/histograms.xml
@@ -632,7 +632,7 @@ </histogram> <histogram name="Cookie.LoadProblem" enum="CookieLoadProblem" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>morlovich@chromium.org</owner> <owner>src/net/cookies/OWNERS</owner> <summary> @@ -1073,7 +1073,7 @@ </histogram> <histogram name="Cookie.TimeBlockedOnLoad" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>wfh@chromium.org</owner> <summary> The amount of time (ms) between the cookie store load starting and
diff --git a/tools/metrics/histograms/metadata/cras/histograms.xml b/tools/metrics/histograms/metadata/cras/histograms.xml index 012dd11..c889c380 100644 --- a/tools/metrics/histograms/metadata/cras/histograms.xml +++ b/tools/metrics/histograms/metadata/cras/histograms.xml
@@ -178,7 +178,7 @@ </summary> </histogram> -<histogram name="Cras.BusyloopLength" units="units" expires_after="2025-04-13"> +<histogram name="Cras.BusyloopLength" units="units" expires_after="2025-06-15"> <owner>yuhsuan@chromium.org</owner> <owner>chromeos-audio@google.com</owner> <summary> @@ -639,7 +639,7 @@ </histogram> <histogram name="Cras.InternalSoundcardStatus{Second}" - enum="InternalSoundcardStatus" expires_after="2025-04-13"> + enum="InternalSoundcardStatus" expires_after="2025-06-15"> <owner>yuhsuan@chromium.org</owner> <owner>chromeos-audio@google.com</owner> <summary> @@ -977,7 +977,7 @@ </histogram> <histogram name="Cras.StreamConnectStatus" enum="CrasStreamConnectStatus" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>yuhsuan@chromium.org</owner> <owner>hychao@chromium.org</owner> <owner>chromeos-audio@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/cros_federated/histograms.xml b/tools/metrics/histograms/metadata/cros_federated/histograms.xml index 8644127..44c07fb2 100644 --- a/tools/metrics/histograms/metadata/cros_federated/histograms.xml +++ b/tools/metrics/histograms/metadata/cros_federated/histograms.xml
@@ -42,7 +42,7 @@ </histogram> <histogram name="FederatedService.StorageEvent" enum="FederatedStorageEvent" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>alanlxl@chromium.org</owner> <owner>amoylan@chromium.org</owner> <owner>cros-federated-team@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/event/histograms.xml b/tools/metrics/histograms/metadata/event/histograms.xml index 54ad9d9c..18ff5f5 100644 --- a/tools/metrics/histograms/metadata/event/histograms.xml +++ b/tools/metrics/histograms/metadata/event/histograms.xml
@@ -610,7 +610,7 @@ </histogram> <histogram name="Event.ScrollJank.MissedVsyncs{Operator}.FixedWindow2" - units="counts" expires_after="2025-04-13"> + units="counts" expires_after="2025-06-15"> <owner>jonross@chromium.org</owner> <owner>woa-performance-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml index 9b337de..27d5910 100644 --- a/tools/metrics/histograms/metadata/extensions/histograms.xml +++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -245,7 +245,7 @@ </histogram> <histogram name="Extensions.ActiveScriptController.DeniedExtensions" - units="Extension Count" expires_after="2025-04-13"> + units="Extension Count" expires_after="2025-06-15"> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary> @@ -1215,7 +1215,7 @@ </histogram> <histogram name="Extensions.DeclarativeNetRequest.RequestHeaderChanged" - enum="WebRequest.RequestHeader" expires_after="2024-12-22"> + enum="WebRequest.RequestHeader" expires_after="2025-12-01"> <owner>rdevlin.cronin@chromium.org</owner> <owner>kelvinjiang@chromium.org</owner> <owner>src/extensions/OWNERS</owner> @@ -1227,7 +1227,7 @@ </histogram> <histogram name="Extensions.DeclarativeNetRequest.RequestHeaderRemoved" - enum="WebRequest.RequestHeader" expires_after="2024-12-12"> + enum="WebRequest.RequestHeader" expires_after="2025-12-01"> <owner>rdevlin.cronin@chromium.org</owner> <owner>kelvinjiang@chromium.org</owner> <owner>src/extensions/OWNERS</owner> @@ -1239,7 +1239,7 @@ </histogram> <histogram name="Extensions.DeclarativeNetRequest.ResponseHeaderAdded" - enum="WebRequest.ResponseHeader" expires_after="2024-12-22"> + enum="WebRequest.ResponseHeader" expires_after="2025-12-01"> <owner>rdevlin.cronin@chromium.org</owner> <owner>kelvinjiang@chromium.org</owner> <owner>src/extensions/OWNERS</owner> @@ -1251,7 +1251,7 @@ </histogram> <histogram name="Extensions.DeclarativeNetRequest.ResponseHeaderChanged" - enum="WebRequest.ResponseHeader" expires_after="2024-12-22"> + enum="WebRequest.ResponseHeader" expires_after="2025-12-01"> <owner>rdevlin.cronin@chromium.org</owner> <owner>kelvinjiang@chromium.org</owner> <owner>src/extensions/OWNERS</owner> @@ -1263,7 +1263,7 @@ </histogram> <histogram name="Extensions.DeclarativeNetRequest.ResponseHeaderRemoved" - enum="WebRequest.ResponseHeader" expires_after="2024-12-22"> + enum="WebRequest.ResponseHeader" expires_after="2025-12-01"> <owner>rdevlin.cronin@chromium.org</owner> <owner>kelvinjiang@chromium.org</owner> <owner>src/extensions/OWNERS</owner> @@ -4142,7 +4142,7 @@ </histogram> <histogram name="Extensions.NewTabPageOverrides2" units="units" - expires_after="2024-09-15"> + expires_after="2025-12-01"> <owner>rdevlin.cronin@chromium.org</owner> <owner>kelvinjiang@chromium.org</owner> <summary> @@ -4637,7 +4637,7 @@ <histogram name="Extensions.ServiceWorkerBackground.ProcessManagerFinishedExternalRequestResultWithSuccessfulStart" - enum="ServiceWorkerExternalRequestResult" expires_after="2024-10-06"> + enum="ServiceWorkerExternalRequestResult" expires_after="2025-12-01"> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary> @@ -4651,7 +4651,7 @@ <histogram name="Extensions.ServiceWorkerBackground.ProcessManagerFinishedExternalRequestResultWithUnsuccessfulStart" - enum="ServiceWorkerExternalRequestResult" expires_after="2024-10-06"> + enum="ServiceWorkerExternalRequestResult" expires_after="2025-12-01"> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/facilitated_payments/histograms.xml b/tools/metrics/histograms/metadata/facilitated_payments/histograms.xml index c6b43a0..256ea36 100644 --- a/tools/metrics/histograms/metadata/facilitated_payments/histograms.xml +++ b/tools/metrics/histograms/metadata/facilitated_payments/histograms.xml
@@ -42,6 +42,23 @@ </variants> <histogram + name="FacilitatedPayments.Ewallet.GetClientToken.{Result}.Latency.{Scheme}" + units="ms" expires_after="2025-07-01"> + <owner>junhuihe@google.com</owner> + <owner>qihuizhao@google.com</owner> + <owner>rouslan@google.com</owner> + <owner>payments-autofill-team@google.com</owner> + <summary> + Latency for the call to fetch the client token. The client token is fetched + from the platform specific payment library in preparation for facilitating + the payment using Google Pay. Logged when an eWallet payflow is triggered. + {Result} is the token fetch result. The payment is supported by {Scheme}. + </summary> + <token key="Result" variants="BooleanResult"/> + <token key="Scheme" variants="EwalletScheme"/> +</histogram> + +<histogram name="FacilitatedPayments.Ewallet.InitiatePayment.{Result}.Latency.{Scheme}" units="ms" expires_after="2025-07-01"> <owner>junhuihe@google.com</owner> @@ -122,22 +139,6 @@ </summary> </histogram> -<histogram name="FacilitatedPayments.Pix.GetClientToken.{Result}.Latency" - units="ms" expires_after="2025-07-01"> - <owner>siashah@google.com</owner> - <owner>vishwasuppoor@google.com</owner> - <owner>rouslan@google.com</owner> - <owner>payments-autofill-team@google.com</owner> - <summary> - Latency for the call to fetch the client token. The client token is fetched - from the platform specific payment library in preparation for facilitating - the payment using Google Pay. {Result} is the token fetch result. - [Frequency] Logged at most once per Pix payflow. [Trigger] Page is loaded - and the main frame contains a valid payment code for Pix. - </summary> - <token key="Result" variants="BooleanResult"/> -</histogram> - <histogram name="FacilitatedPayments.Pix.InitiatePayment.Attempt" enum="BooleanAttempted" expires_after="2025-07-01"> <owner>siashah@google.com</owner> @@ -291,6 +292,25 @@ </histogram> <histogram + name="FacilitatedPayments.{FacilitatedPaymentsType}.GetClientToken.{Result}.Latency" + units="ms" expires_after="2025-07-01"> + <owner>siashah@google.com</owner> + <owner>vishwasuppoor@google.com</owner> + <owner>rouslan@google.com</owner> + <owner>payments-autofill-team@google.com</owner> + <summary> + Latency for the call to fetch the client token. The client token is fetched + from the platform specific payment library in preparation for facilitating + the payment using Google Pay. {Result} is the token fetch result. + [Frequency] Logged at most once per {FacilitatedPaymentsType} payflow. + [Trigger] Page is loaded and the main frame contains a valid payment code + for {FacilitatedPaymentsType}. + </summary> + <token key="FacilitatedPaymentsType" variants="FacilitatedPaymentsTypes"/> + <token key="Result" variants="BooleanResult"/> +</histogram> + +<histogram name="FacilitatedPayments.{FacilitatedPaymentsType}.InitiatePayment.{Result}.Latency" units="ms" expires_after="2025-07-01"> <owner>siashah@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml index 38506dcc6..bc415824 100644 --- a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml +++ b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
@@ -659,7 +659,7 @@ </histogram> <histogram name="InProductHelp.DismissalReason.iOS" - enum="InProductHelpDismissalReason" expires_after="2025-04-13"> + enum="InProductHelpDismissalReason" expires_after="2025-06-15"> <owner>lpromero@google.com</owner> <owner>gambard@chromium.org</owner> <summary> @@ -668,7 +668,7 @@ </histogram> <histogram name="InProductHelp.Gestural.DismissalReason.iOS" - enum="InProductHelpDismissalReason" expires_after="2025-04-13"> + enum="InProductHelpDismissalReason" expires_after="2025-06-15"> <owner>ginnyhuang@chromium.org</owner> <owner>adamta@google.com</owner> <summary> @@ -700,7 +700,7 @@ </histogram> <histogram name="InProductHelp.ShownTime.{IPHFeature}" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>lpromero@google.com</owner> <owner>gambard@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml index 293cace..fee3192e 100644 --- a/tools/metrics/histograms/metadata/gpu/histograms.xml +++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -1038,7 +1038,7 @@ </histogram> <histogram name="Gpu.GrShaderCacheLoadHitInCache" enum="Boolean" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>geofflang@chromium.org</owner> <owner>chrome-gpu-metric-alerts@chromium.org</owner> <summary> @@ -1476,7 +1476,7 @@ </histogram> <histogram name="GPU.TransferCache.ReusedTimes" units="Reuses" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>boliu@chromium.org</owner> <owner>chrome-gpu-metric-alerts@chromium.org</owner> <summary> @@ -1725,7 +1725,7 @@ </histogram> <histogram name="GPU.{GraphiteDawnOrWebGPU}.{Cacheable}.CacheMiss" - units="microseconds" expires_after="2025-04-13"> + units="microseconds" expires_after="2025-06-15"> <owner>lokokung@google.com</owner> <owner>mdb.webgpu-dev-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/hang_watcher/histograms.xml b/tools/metrics/histograms/metadata/hang_watcher/histograms.xml index f6b6644..21aea71 100644 --- a/tools/metrics/histograms/metadata/hang_watcher/histograms.xml +++ b/tools/metrics/histograms/metadata/hang_watcher/histograms.xml
@@ -62,7 +62,7 @@ </variants> <histogram name="HangWatcher.IsThreadHung.{BrowserProcessAndThreadType}" - enum="BooleanHung" expires_after="2025-04-13"> + enum="BooleanHung" expires_after="2025-06-15"> <owner>olivierli@chromium.org</owner> <owner>catan-team@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/history/histograms.xml b/tools/metrics/histograms/metadata/history/histograms.xml index 9a67d80..044e279 100644 --- a/tools/metrics/histograms/metadata/history/histograms.xml +++ b/tools/metrics/histograms/metadata/history/histograms.xml
@@ -2668,7 +2668,7 @@ </histogram> <histogram name="History.VisitedLinks.HashTableLengthOnReaderInit" - units="entries" expires_after="2025-04-13"> + units="entries" expires_after="2025-06-15"> <owner>kyraseevers@chromium.org</owner> <owner>brgoldstein@google.com</owner> <summary> @@ -2679,7 +2679,7 @@ </histogram> <histogram name="History.VisitedLinks.HashTableSizeOnTableCreate" units="MB" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>kyraseevers@chromium.org</owner> <owner>brgoldstein@google.com</owner> <summary> @@ -2689,7 +2689,7 @@ </histogram> <histogram name="History.VisitedLinks.HashTableUsageOnLinkAdded" - units="fingerprints" expires_after="2025-04-13"> + units="fingerprints" expires_after="2025-06-15"> <owner>kyraseevers@chromium.org</owner> <owner>brgoldstein@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/language/histograms.xml b/tools/metrics/histograms/metadata/language/histograms.xml index 9251c4f3..57ae12c2 100644 --- a/tools/metrics/histograms/metadata/language/histograms.xml +++ b/tools/metrics/histograms/metadata/language/histograms.xml
@@ -151,7 +151,7 @@ </histogram> <histogram name="LanguageDetection.TFLiteModel.WasModelAvailableForDetection" - enum="BooleanAvailable" expires_after="2025-04-13"> + enum="BooleanAvailable" expires_after="2025-06-15"> <owner>mcrouse@chromium.org</owner> <owner>chrome-language@google.com</owner> <summary> @@ -197,7 +197,7 @@ </histogram> <histogram name="LanguageSettings.AppLanguagePrompt.Action" - enum="LanguageSettingsAppLanguagePromptAction" expires_after="2025-04-13"> + enum="LanguageSettingsAppLanguagePromptAction" expires_after="2025-06-15"> <owner>perrier@chromium.org</owner> <owner>chrome-language@google.com</owner> <summary> @@ -276,7 +276,7 @@ </histogram> <histogram name="LanguageSettings.AppLanguagePrompt.TopULPMatchStatus" - enum="ULPTopLanguageMatch" expires_after="2025-04-13"> + enum="ULPTopLanguageMatch" expires_after="2025-06-15"> <owner>perrier@chromium.org</owner> <owner>chrome-language@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index d3447c1..6aa4b9f1 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -3890,7 +3890,7 @@ </histogram> <histogram name="Media.HLS.MultivariantPlaylist" enum="Boolean" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>tmathmeyer@chromium.org</owner> <owner>media-dev-uma@chromium.org</owner> <summary> @@ -5626,7 +5626,7 @@ <histogram name="Media.Ui.GetDisplayMedia.BasicFlow.UserInteraction" enum="MediaUiGetDisplayMediaBasicFlowUserInteraction" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>eladalon@chromium.org</owner> <owner>fbeaufort@chromium.org</owner> <summary> @@ -7224,7 +7224,7 @@ </histogram> <histogram name="MediaRouter.Cast.Channel.Error" - enum="MediaRouterCastChannelError" expires_after="2025-04-13"> + enum="MediaRouterCastChannelError" expires_after="2025-06-15"> <owner>mfoltz@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/memory/histograms.xml b/tools/metrics/histograms/metadata/memory/histograms.xml index 4c6ef32..f63e15af 100644 --- a/tools/metrics/histograms/metadata/memory/histograms.xml +++ b/tools/metrics/histograms/metadata/memory/histograms.xml
@@ -94,7 +94,7 @@ </variants> <histogram name="HeapProfiling.InProcess.Enabled{Process}" - enum="BooleanEnabled" expires_after="2025-04-13"> + enum="BooleanEnabled" expires_after="2025-06-15"> <owner>joenotcharles@google.com</owner> <owner>chrome-memory@google.com</owner> <summary> @@ -171,7 +171,7 @@ </histogram> <histogram name="HeapProfiling.InProcess.SamplesPerSnapshot{Process}" - units="samples" expires_after="2025-04-13"> + units="samples" expires_after="2025-06-15"> <owner>joenotcharles@google.com</owner> <owner>chrome-memory@google.com</owner> <summary> @@ -1635,7 +1635,7 @@ </histogram> <histogram name="Memory.ParkableString.Read.Latency" units="microseconds" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>lizeb@chromium.org</owner> <owner>pasko@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml index ed904c1..9c76a4ff 100644 --- a/tools/metrics/histograms/metadata/navigation/histograms.xml +++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -1446,7 +1446,7 @@ </histogram> <histogram name="Navigation.MainFrameProfileType2" enum="BrowserProfileType" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>rhalavati@chromium.org</owner> <owner>chrome-privacy-core@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml index af629de..e97bf20a 100644 --- a/tools/metrics/histograms/metadata/net/histograms.xml +++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -446,7 +446,7 @@ </histogram> <histogram name="HttpCache.Pattern" enum="HttpCachePattern" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>morlovich@chromium.org</owner> <owner>jkarlin@chromium.org</owner> <summary>For each http cache transaction, the recorded pattern.</summary> @@ -3604,7 +3604,7 @@ <histogram name="Net.QuicSession.ConnectionCloseErrorCode{Closer}{ServerType}{HandshakeType}" - enum="QuicErrorCodes" expires_after="2025-04-13"> + enum="QuicErrorCodes" expires_after="2025-06-15"> <owner>dschinazi@chromium.org</owner> <owner>src/net/quic/OWNERS</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml index da0afc620..fef408d 100644 --- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml +++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -1593,7 +1593,7 @@ </histogram> <histogram name="NewTabPage.WallpaperSearch.Status" - enum="NtpWallpaperSearchStatus" expires_after="2025-04-13"> + enum="NtpWallpaperSearchStatus" expires_after="2025-06-15"> <owner>pauladedeji@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>rtatum@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/omnibox/histograms.xml b/tools/metrics/histograms/metadata/omnibox/histograms.xml index 27395f2..a6bc90e 100644 --- a/tools/metrics/histograms/metadata/omnibox/histograms.xml +++ b/tools/metrics/histograms/metadata/omnibox/histograms.xml
@@ -2043,7 +2043,7 @@ </histogram> <histogram name="Omnibox.SuggestionUsed.URL.NavigationToFirstContentfulPaint" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>jdonnelly@chromium.org</owner> <owner>mpearson@chromium.org</owner> <owner>chrome-omnibox-team@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index 58e7930..80edffea 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -2947,7 +2947,7 @@ </histogram> <histogram name="ClientHints.AcceptCHFrame" enum="AcceptCHFrameRestart" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>victortan@chromium.org</owner> <owner>miketaylr@chromium.org</owner> <owner>katabolism-finch@google.com</owner> @@ -4858,7 +4858,7 @@ </histogram> <histogram name="FetchKeepAlive.RequestOutliveDuration" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>mych@chromium.org</owner> <owner>chrome-bfcache@google.com</owner> <summary> @@ -4898,7 +4898,7 @@ <histogram name="FetchKeepAlive.Requests2.{RequestState}.IsContextDetached.{Process}" - enum="Boolean" expires_after="2025-04-13"> + enum="Boolean" expires_after="2025-06-15"> <owner>mych@chromium.org</owner> <owner>chrome-bfcache@google.com</owner> <summary> @@ -6292,7 +6292,7 @@ </histogram> <histogram name="MPArch.ChildProcessLaunchSubsequent" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>pasko@chromium.org</owner> <owner>yfriedman@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml index 62f31592..32936c9 100644 --- a/tools/metrics/histograms/metadata/page/histograms.xml +++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -1279,7 +1279,7 @@ <histogram name="PageLoad.Clients.GoogleSearch.NavigationTiming.NavigationStartToFinalLoaderCallback" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>nidhijaju@chromium.org</owner> <owner>chrome-loading@google.com</owner> <summary> @@ -1293,7 +1293,7 @@ <histogram name="PageLoad.Clients.GoogleSearch.NavigationTiming.NavigationStartToFinalRequestStart" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>nidhijaju@chromium.org</owner> <owner>chrome-loading@google.com</owner> <summary> @@ -1307,7 +1307,7 @@ <histogram name="PageLoad.Clients.GoogleSearch.NavigationTiming.NavigationStartToFinalResponseStart" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>nidhijaju@chromium.org</owner> <owner>chrome-loading@google.com</owner> <summary> @@ -1321,7 +1321,7 @@ <histogram name="PageLoad.Clients.GoogleSearch.NavigationTiming.NavigationStartToFirstLoaderCallback" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>kouhei@chromium.org</owner> <owner>chrome-loading@google.com</owner> <summary> @@ -1335,7 +1335,7 @@ <histogram name="PageLoad.Clients.GoogleSearch.NavigationTiming.NavigationStartToFirstRequestStart" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>kouhei@chromium.org</owner> <owner>chrome-loading@google.com</owner> <summary> @@ -1349,7 +1349,7 @@ <histogram name="PageLoad.Clients.GoogleSearch.NavigationTiming.NavigationStartToFirstResponseStart" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>kouhei@chromium.org</owner> <owner>chrome-loading@google.com</owner> <summary> @@ -1482,7 +1482,7 @@ <histogram name="PageLoad.Clients.GoogleSearch{Granularity}.PaintTiming.NavigationToLargestContentfulPaint{SafeSitesFilter}" - units="ms" expires_after="2025-06-08"> + units="ms" expires_after="2025-06-15"> <owner>spelchat@chromium.org</owner> <owner>chrome-brapp-loading@google.com</owner> <summary> @@ -1522,7 +1522,7 @@ <histogram name="PageLoad.Clients.LCPP.PaintTiming.NavigationToFirstContentfulPaint" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>kouhei@chromium.org</owner> <owner> src/third_party/blink/renderer/core/lcp_critical_path_predictor/OWNERS @@ -1536,7 +1536,7 @@ <histogram name="PageLoad.Clients.LCPP.PaintTiming.NavigationToLargestContentfulPaint" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>kouhei@chromium.org</owner> <owner> src/third_party/blink/renderer/core/lcp_critical_path_predictor/OWNERS @@ -1564,7 +1564,7 @@ </histogram> <histogram name="PageLoad.Clients.LCPP.PaintTiming.PredictLCPResult" - enum="LcppPredictResult" expires_after="2025-04-13"> + enum="LcppPredictResult" expires_after="2025-06-15"> <owner>yoichio@chromium.org</owner> <owner> src/third_party/blink/renderer/core/lcp_critical_path_predictor/OWNERS @@ -2042,7 +2042,7 @@ <histogram name="PageLoad.Clients.ThirdParty.Frames.Opaque.NavigationToLargestContentfulPaint" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>awillia@chromium.org</owner> <owner>djmitche@chromium.org</owner> <summary> @@ -3317,7 +3317,7 @@ <histogram name="PageLoad.InteractiveTiming.{NormalizedResponsivenessMetric}.{UserInteractionLatency}{PageLoadType}" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>iclelland@chromium.org</owner> <owner>speed-metrics-dev@chromium.org</owner> <summary> @@ -3583,7 +3583,7 @@ </histogram> <histogram name="PageLoad.LayoutInstability.CumulativeShiftScore" - units="scorex10" expires_after="2025-04-13"> + units="scorex10" expires_after="2025-06-15"> <owner>bmcquade@chromium.org</owner> <owner>skobes@chromium.org</owner> <summary> @@ -4013,7 +4013,7 @@ <histogram name="PageLoad.PaintTiming.NavigationToLargestContentfulPaint2.CrossSiteSubFrame" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>sisidovski@google.com</owner> <owner>kouhei@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml index 2d3cb46..9e666e3 100644 --- a/tools/metrics/histograms/metadata/password/histograms.xml +++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -460,7 +460,7 @@ </histogram> <histogram name="PasswordGeneration.PopupShown" - enum="PasswordGenerationPopupShown" expires_after="2025-04-13"> + enum="PasswordGenerationPopupShown" expires_after="2025-06-15"> <owner>kazinova@google.com</owner> <owner>vasilii@chromium.org</owner> <summary>Records an entry if (and only if) a popup was shown.</summary> @@ -490,7 +490,7 @@ </histogram> <histogram name="PasswordGeneration.UserDecision" - enum="PasswordGenerationUserEvent" expires_after="2025-04-13"> + enum="PasswordGenerationUserEvent" expires_after="2025-06-15"> <owner>ioanap@chromium.org</owner> <owner>vasilii@chromium.org</owner> <summary> @@ -2832,7 +2832,7 @@ </histogram> <histogram name="PasswordManager.PasswordReuse.TotalPasswords" - units="credentials" expires_after="2025-04-13"> + units="credentials" expires_after="2025-06-15"> <owner>nwokedi@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> @@ -3949,7 +3949,7 @@ </histogram> <histogram name="PasswordManager.SuccessfulSubmissionIndicatorEvent" - enum="SubmissionIndicatorEvent" expires_after="2025-04-13"> + enum="SubmissionIndicatorEvent" expires_after="2025-06-15"> <owner>kazinova@google.com</owner> <owner>vasilii@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/pdf/histograms.xml b/tools/metrics/histograms/metadata/pdf/histograms.xml index 3fe612f..9c76734 100644 --- a/tools/metrics/histograms/metadata/pdf/histograms.xml +++ b/tools/metrics/histograms/metadata/pdf/histograms.xml
@@ -23,7 +23,7 @@ <histograms> <histogram name="PDF.Actions" enum="ChromePDFViewerActions" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>andyphan@chromium.org</owner> <owner>thestig@chromium.org</owner> <summary> @@ -143,7 +143,7 @@ </summary> </histogram> -<histogram name="PDF.PageCount" units="pages" expires_after="2025-04-13"> +<histogram name="PDF.PageCount" units="pages" expires_after="2025-06-15"> <owner>andyphan@chromium.org</owner> <owner>thestig@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/permissions/histograms.xml b/tools/metrics/histograms/metadata/permissions/histograms.xml index f37bafb..3a8b519 100644 --- a/tools/metrics/histograms/metadata/permissions/histograms.xml +++ b/tools/metrics/histograms/metadata/permissions/histograms.xml
@@ -188,7 +188,7 @@ </histogram> <histogram name="Permissions.Action.WithDisposition.{DispositionType}" - enum="PermissionAction" expires_after="2025-04-13"> + enum="PermissionAction" expires_after="2025-06-15"> <owner>andypaicu@chromium.org</owner> <owner>engedy@chromium.org</owner> <owner>hkamila@chromium.org</owner> @@ -967,7 +967,7 @@ </histogram> <histogram name="Permissions.Prompt.Shown" enum="PermissionRequestType" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>engedy@chromium.org</owner> <owner>src/components/permissions/PERMISSIONS_OWNERS</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml index f123678..4ab30b3e 100644 --- a/tools/metrics/histograms/metadata/power/histograms.xml +++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -197,7 +197,7 @@ </variants> <histogram name="PerformanceMonitor.AverageCPU8.Total{UsageScenario}" - units="1/100 %" expires_after="2025-04-13"> + units="1/100 %" expires_after="2025-06-15"> <owner>fdoray@chromium.org</owner> <owner>pmonette@chromium.org</owner> <owner>catan-team@chromium.org</owner> @@ -209,7 +209,7 @@ </histogram> <histogram name="PerformanceMonitor.AverageCPU8.{ProcessName}" units="1/100 %" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>fdoray@chromium.org</owner> <owner>pmonette@chromium.org</owner> <owner>catan-team@chromium.org</owner> @@ -699,7 +699,7 @@ <histogram name="Power.BatteryDischargeRateMilliwatts6{UsageScenario}{IntervalType}{BatterySaverMode}" - units="milliwatts" expires_after="2025-04-13"> + units="milliwatts" expires_after="2025-06-15"> <owner>etiennep@chromium.org</owner> <owner>olivierli@chromium.org</owner> <owner>lgrey@chromium.org</owner> @@ -726,7 +726,7 @@ <histogram name="Power.BatteryDischargeRatePreciseMilliwatts{UsageScenario}{IntervalType}{BatterySaverMode}" - units="milliwatts" expires_after="2025-04-13"> + units="milliwatts" expires_after="2025-06-15"> <owner>pmonette@chromium.org</owner> <owner>catan-team@chromium.org</owner> <summary> @@ -755,7 +755,7 @@ <histogram name="Power.BatteryDischargeRateRelative5{UsageScenario}{IntervalType}{BatterySaverMode}" - units="hundredth of percent" expires_after="2025-04-13"> + units="hundredth of percent" expires_after="2025-06-15"> <owner>etiennep@chromium.org</owner> <owner>olivierli@chromium.org</owner> <owner>lgrey@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/preloading/histograms.xml b/tools/metrics/histograms/metadata/preloading/histograms.xml index 8962af5..cd4705a6 100644 --- a/tools/metrics/histograms/metadata/preloading/histograms.xml +++ b/tools/metrics/histograms/metadata/preloading/histograms.xml
@@ -272,7 +272,7 @@ <histogram name="Preloading.{PreloadingType}.Attempt.{PreloadingPredictor}.Recall" - enum="PredictorConfusionMatrix" expires_after="2025-04-13"> + enum="PredictorConfusionMatrix" expires_after="2025-06-15"> <owner>isaboori@google.com</owner> <owner>spelchat@chromium.org</owner> <owner>sreejakshetty@chromium.org</owner> @@ -293,7 +293,7 @@ <histogram name="Preloading.{PreloadingType}.Attempt.{PreloadingPredictor}.TriggeringOutcome" - enum="PreloadingTriggeringOutcome" expires_after="2025-04-13"> + enum="PreloadingTriggeringOutcome" expires_after="2025-06-15"> <owner>spelchat@chromium.org</owner> <owner>sreejakshetty@chromium.org</owner> <owner>jbroman@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/privacy/histograms.xml b/tools/metrics/histograms/metadata/privacy/histograms.xml index e9bb7396..7a1038c 100644 --- a/tools/metrics/histograms/metadata/privacy/histograms.xml +++ b/tools/metrics/histograms/metadata/privacy/histograms.xml
@@ -1240,7 +1240,7 @@ </histogram> <histogram name="PrivacySandbox.Attestations.IsSiteAttestedStatus" - enum="PrivacySandboxApiAllowed" expires_after="2025-04-13"> + enum="PrivacySandboxApiAllowed" expires_after="2025-06-15"> <owner>shivanisha@chromium.org</owner> <owner>xiaochenzh@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/readaloud/histograms.xml b/tools/metrics/histograms/metadata/readaloud/histograms.xml index 52961fdc..0315df6 100644 --- a/tools/metrics/histograms/metadata/readaloud/histograms.xml +++ b/tools/metrics/histograms/metadata/readaloud/histograms.xml
@@ -168,7 +168,7 @@ </histogram> <histogram name="ReadAloud.IsPageReadabilitySuccessful" enum="BooleanSuccess" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -180,7 +180,7 @@ </histogram> <histogram name="ReadAloud.IsPageReadable" enum="BooleanEligible" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -198,7 +198,7 @@ </histogram> <histogram name="ReadAloud.IsTabPlaybackCreationSuccessful" - enum="BooleanSuccess" expires_after="2025-04-13"> + enum="BooleanSuccess" expires_after="2025-06-15"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/renderer4/histograms.xml b/tools/metrics/histograms/metadata/renderer4/histograms.xml index bebafa57..af586cc 100644 --- a/tools/metrics/histograms/metadata/renderer4/histograms.xml +++ b/tools/metrics/histograms/metadata/renderer4/histograms.xml
@@ -126,7 +126,7 @@ <histogram base="true" name="Renderer4.ImageDecodeTaskDurationUs{ImageOrTaskType}.{DecodeType}" - units="microseconds" expires_after="2025-04-13"> + units="microseconds" expires_after="2025-06-15"> <owner>cblume@chromium.org</owner> <owner>vmpstr@chromium.org</owner> <owner>sashamcintosh@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/sb_client/histograms.xml b/tools/metrics/histograms/metadata/sb_client/histograms.xml index 02158e5..a2b117c 100644 --- a/tools/metrics/histograms/metadata/sb_client/histograms.xml +++ b/tools/metrics/histograms/metadata/sb_client/histograms.xml
@@ -459,7 +459,7 @@ </histogram> <histogram name="SBClientDownload.{Encryption}DeepScanEvent3" - enum="SBDeepScanEvent" expires_after="2025-04-13"> + enum="SBDeepScanEvent" expires_after="2025-06-15"> <owner>drubery@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> @@ -885,7 +885,7 @@ </histogram> <histogram name="SBClientPhishing.PhishingImageEmbeddingResult" - enum="ClientSidePhishingImageEmbeddingResult" expires_after="2025-04-13"> + enum="ClientSidePhishingImageEmbeddingResult" expires_after="2025-06-15"> <owner>andysjlim@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/scheduler/histograms.xml b/tools/metrics/histograms/metadata/scheduler/histograms.xml index f79394f9..7753c51f 100644 --- a/tools/metrics/histograms/metadata/scheduler/histograms.xml +++ b/tools/metrics/histograms/metadata/scheduler/histograms.xml
@@ -122,7 +122,7 @@ </histogram> <histogram name="Scheduling.MessagePumpTimeKeeper.{NamedThread}" - enum="MessagePumpPhases" expires_after="2025-04-13"> + enum="MessagePumpPhases" expires_after="2025-06-15"> <owner>gab@chromium.org</owner> <owner>fdoray@chromium.org</owner> <owner>spvw@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml index a00e5f6..870d4d6 100644 --- a/tools/metrics/histograms/metadata/security/histograms.xml +++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -203,7 +203,7 @@ </histogram> <histogram name="Security.HttpsFirstMode.InterstitialReason" - enum="HttpsFirstModeInterstitialReason" expires_after="2025-04-13"> + enum="HttpsFirstModeInterstitialReason" expires_after="2025-06-15"> <owner>meacer@chromium.org</owner> <owner>trusty-transport@chromium.org</owner> <summary> @@ -213,7 +213,7 @@ </histogram> <histogram name="Security.HttpsFirstMode.NavigationEvent" - enum="HttpsFirstModeNavigationEvent" expires_after="2025-04-13"> + enum="HttpsFirstModeNavigationEvent" expires_after="2025-06-15"> <owner>cthomp@chromium.org</owner> <owner>trusty-transport@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/service/histograms.xml b/tools/metrics/histograms/metadata/service/histograms.xml index e3319f7..8b1457e0 100644 --- a/tools/metrics/histograms/metadata/service/histograms.xml +++ b/tools/metrics/histograms/metadata/service/histograms.xml
@@ -698,7 +698,7 @@ <histogram name="ServiceWorker.LoadTiming.MainFrame.MainResource.FetchHandlerStartToFetchHandlerEnd{EmbeddedWorkerInitialStatus}" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>yyanagisawa@chromium.org</owner> <owner>chrome-worker@google.com</owner> <summary> @@ -777,7 +777,7 @@ <histogram name="ServiceWorker.LoadTiming.MainFrame.MainResource.ForwardServiceWorkerToWorkerReady2{EmbeddedWorkerInitialStatus}{NavigationType}" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>yyanagisawa@chromium.org</owner> <owner>chrome-worker@google.com</owner> <summary> @@ -1522,7 +1522,7 @@ </histogram> <histogram name="ServiceWorker.StartWorker.Status" - enum="ServiceWorkerStatusCode" expires_after="2025-04-13"> + enum="ServiceWorkerStatusCode" expires_after="2025-06-15"> <owner>yyanagisawa@chromium.org</owner> <owner>chikamune@chromium.org</owner> <owner>chrome-worker@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/session/histograms.xml b/tools/metrics/histograms/metadata/session/histograms.xml index 63e14b60..dd937ea 100644 --- a/tools/metrics/histograms/metadata/session/histograms.xml +++ b/tools/metrics/histograms/metadata/session/histograms.xml
@@ -35,7 +35,7 @@ </histogram> <histogram name="Session.Background.TotalDuration" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>asvitkine@chromium.org</owner> <owner>src/base/metrics/OWNERS</owner> <summary> @@ -995,7 +995,7 @@ </histogram> <histogram name="Session.WebStates.NativeRestoreSession" enum="BooleanSuccess" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>justincohen@chromium.org</owner> <owner>michaeldo@chromium.org</owner> <summary> @@ -1006,7 +1006,7 @@ </histogram> <histogram name="Session.WebStates.NativeRestoreSessionFromCache" - enum="BooleanSuccess" expires_after="2025-04-13"> + enum="BooleanSuccess" expires_after="2025-06-15"> <owner>justincohen@chromium.org</owner> <owner>michaeldo@chromium.org</owner> <summary> @@ -1017,7 +1017,7 @@ </histogram> <histogram name="Session.WebStates.NativeRestoreSessionFromCacheHasData" - enum="BooleanHasData" expires_after="2025-04-13"> + enum="BooleanHasData" expires_after="2025-06-15"> <owner>justincohen@chromium.org</owner> <owner>michaeldo@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/sharing/histograms.xml b/tools/metrics/histograms/metadata/sharing/histograms.xml index bc621c4..50de0d7 100644 --- a/tools/metrics/histograms/metadata/sharing/histograms.xml +++ b/tools/metrics/histograms/metadata/sharing/histograms.xml
@@ -268,7 +268,7 @@ </histogram> <histogram name="Sharing.DefaultSharesheetAndroid.Opened" enum="ShareOrigin" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>wenyufu@chromium.org</owner> <owner>sophey@chromium.org</owner> <owner>src/chrome/browser/share/OWNERS</owner> @@ -442,7 +442,7 @@ </histogram> <histogram name="Sharing.SharingHubAndroid.Opened" enum="ShareOrigin" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>wenyufu@chromium.org</owner> <owner>sophey@chromium.org</owner> <owner>src/chrome/browser/share/OWNERS</owner>
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml index e36c92e..d11de42e 100644 --- a/tools/metrics/histograms/metadata/signin/histograms.xml +++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -550,7 +550,7 @@ </histogram> <histogram base="true" name="Signin.AndroidGetAccountsTime" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>alexilin@chromium.org</owner> <owner>bsazonov@chromium.org</owner> <summary> @@ -979,7 +979,7 @@ </histogram> <histogram name="Signin.CctAccountMismatchNoticeSuppressed" - enum="SuppressedReason" expires_after="2025-04-13"> + enum="SuppressedReason" expires_after="2025-06-15"> <owner>samarchehade@google.com</owner> <owner>chrome-signin-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml index 47d81a7..83acac8 100644 --- a/tools/metrics/histograms/metadata/startup/histograms.xml +++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -674,7 +674,7 @@ </histogram> <histogram name="Startup.BrowserMessageLoopFirstIdle" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>gab@chromium.org</owner> <owner>etienneb@chromium.org</owner> <summary> @@ -1020,7 +1020,7 @@ </histogram> <histogram name="Startup.GPU.LoadTime.ApplicationStartToGpuInitialized" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>spvw@chromium.org</owner> <owner>etienneb@chromium.org</owner> <summary> @@ -1057,7 +1057,7 @@ </histogram> <histogram name="Startup.GPU.LoadTime.ProcessCreationToGpuInitialized" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-06-15"> <owner>spvw@chromium.org</owner> <owner>etienneb@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/structured_metrics/histograms.xml b/tools/metrics/histograms/metadata/structured_metrics/histograms.xml index 2aec1c3..8a9c88c4 100644 --- a/tools/metrics/histograms/metadata/structured_metrics/histograms.xml +++ b/tools/metrics/histograms/metadata/structured_metrics/histograms.xml
@@ -9,7 +9,7 @@ <histograms> <histogram name="StructuredMetrics.ExternalMetricsDropped" units="count" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>andrewbregger@google.com</owner> <owner>jongahn@google.com</owner> <owner>chromeos-data-eng@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml index d941ef6..e145a14 100644 --- a/tools/metrics/histograms/metadata/sync/histograms.xml +++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -439,7 +439,7 @@ </histogram> <histogram name="Sync.ConfigureDataTypes" enum="SyncDataTypes" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>mastiz@chromium.org</owner> <owner>treib@chromium.org</owner> <summary> @@ -1641,7 +1641,7 @@ </histogram> <histogram name="Sync.SyncablePrefValueChanged" enum="SyncablePref" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>ankushkush@google.com</owner> <owner>treib@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml index bd438d5b..0d88e8b 100644 --- a/tools/metrics/histograms/metadata/tab/histograms.xml +++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -770,7 +770,7 @@ </histogram> <histogram name="TabGroups.NumberOfRootIdsFixed" units="groups" - expires_after="2025-01-26"> + expires_after="2025-06-26"> <owner>ckitagawa@chromium.org</owner> <owner>clank-tab-dev@chromium.org</owner> <summary> @@ -3385,7 +3385,7 @@ </histogram> <histogram name="Tabs.TabState.SaveTime{Schema}" units="ms" - expires_after="2025-04-12"> + expires_after="2025-06-15"> <owner>nyquist@chromium.org</owner> <owner>dtrainor@chromium.org</owner> <owner>davidjm@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/toasts/histograms.xml b/tools/metrics/histograms/metadata/toasts/histograms.xml index bdcf0588..0e8cfd5 100644 --- a/tools/metrics/histograms/metadata/toasts/histograms.xml +++ b/tools/metrics/histograms/metadata/toasts/histograms.xml
@@ -32,7 +32,7 @@ </histogram> <histogram name="Toast.{ToastName}.Dismissed" enum="ToastCloseReason" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>agale@chromium.org</owner> <owner>stluong@chromium.org</owner> <owner>chrome-performance-ui-sea@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/translate/histograms.xml b/tools/metrics/histograms/metadata/translate/histograms.xml index d48ec8d..2e929505 100644 --- a/tools/metrics/histograms/metadata/translate/histograms.xml +++ b/tools/metrics/histograms/metadata/translate/histograms.xml
@@ -178,7 +178,7 @@ </histogram> <histogram name="Translate.HrefHint.Status" enum="HrefTranslateStatus" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>sclittle@google.com</owner> <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner> @@ -212,7 +212,7 @@ </histogram> <histogram name="Translate.LanguageDetection.LanguageVerification" - enum="TranslateLanguageVerification" expires_after="2025-04-13"> + enum="TranslateLanguageVerification" expires_after="2025-06-15"> <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -386,7 +386,7 @@ </histogram> <histogram name="Translate.PageLoad.FinalState" enum="TranslateState" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -450,7 +450,7 @@ </histogram> <histogram name="Translate.PageLoad.InitialTargetLanguage" - enum="LocaleCodeISO639" expires_after="2025-04-13"> + enum="LocaleCodeISO639" expires_after="2025-06-15"> <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -565,7 +565,7 @@ </histogram> <histogram name="Translate.PageLoad.TriggerDecision" - enum="TranslateTriggerDecision" expires_after="2025-04-13"> + enum="TranslateTriggerDecision" expires_after="2025-06-15"> <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -583,7 +583,7 @@ </histogram> <histogram name="Translate.PartialTranslation.HttpResponseCode" - enum="HttpResponseCode" expires_after="2025-04-13"> + enum="HttpResponseCode" expires_after="2025-06-15"> <owner>basiaz@google.com</owner> <owner>cuianthony@google.com</owner> <summary> @@ -645,7 +645,7 @@ </histogram> <histogram name="Translate.PartialTranslation.TranslationStatus" - enum="PartialTranslateTranslationStatus" expires_after="2025-04-13"> + enum="PartialTranslateTranslationStatus" expires_after="2025-06-15"> <owner>cuianthony@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -691,7 +691,7 @@ </histogram> <histogram name="Translate.Translation.SourceLanguage" enum="LocaleCodeISO639" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -703,7 +703,7 @@ </histogram> <histogram name="Translate.Translation.Status" enum="TranslationStatus" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -722,7 +722,7 @@ </histogram> <histogram name="Translate.Translation.TargetLanguage" enum="LocaleCodeISO639" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner> <summary> @@ -781,7 +781,7 @@ </histogram> <histogram name="Translate.Translation.Type" enum="TranslationType" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/uma/histograms.xml b/tools/metrics/histograms/metadata/uma/histograms.xml index c7b39d7..e424595 100644 --- a/tools/metrics/histograms/metadata/uma/histograms.xml +++ b/tools/metrics/histograms/metadata/uma/histograms.xml
@@ -652,7 +652,7 @@ </histogram> <histogram name="UMA.PersistentAllocator.{PersistentAllocatorType}.UsedPct" - units="%" expires_after="2025-04-13"> + units="%" expires_after="2025-06-15"> <owner>asvitkine@chromium.org</owner> <owner>src/base/metrics/OWNERS</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/v8/histograms.xml b/tools/metrics/histograms/metadata/v8/histograms.xml index ca2c0199..e1b25a2c 100644 --- a/tools/metrics/histograms/metadata/v8/histograms.xml +++ b/tools/metrics/histograms/metadata/v8/histograms.xml
@@ -41,7 +41,7 @@ </histogram> <histogram name="V8.AsmjsInstantiateResult" enum="AsmJsInstantiateResult" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>ahaas@chromium.org</owner> <owner>ecmziegler@chromium.org</owner> <owner>wasm-v8@google.com</owner> @@ -462,7 +462,7 @@ </histogram> <histogram name="V8.GC.Cycle{Priority}.CollectionRate.Full" units="%" - expires_after="M136"> + expires_after="2025-06-15"> <owner>nikolaos@chromium.org</owner> <owner>v8-memory-sheriffs@google.com</owner> <summary> @@ -496,7 +496,7 @@ </histogram> <histogram name="V8.GC.Cycle{Priority}.CollectionRate.Young" units="%" - expires_after="M136"> + expires_after="2025-06-15"> <owner>nikolaos@chromium.org</owner> <owner>v8-memory-sheriffs@google.com</owner> <summary> @@ -685,7 +685,8 @@ </token> </histogram> -<histogram name="V8.GC.Cycle{Priority}.Full" units="ms" expires_after="M136"> +<histogram name="V8.GC.Cycle{Priority}.Full" units="ms" + expires_after="2025-06-15"> <owner>nikolaos@chromium.org</owner> <owner>v8-memory-sheriffs@google.com</owner> <summary> @@ -797,7 +798,7 @@ </histogram> <histogram name="V8.GC.Cycle{Priority}.Full.Sweep.Cpp" units="ms" - expires_after="M136"> + expires_after="2025-06-15"> <owner>omerkatz@chromium.org</owner> <owner>v8-memory-sheriffs@google.com</owner> <summary> @@ -846,7 +847,7 @@ </histogram> <histogram name="V8.GC.Cycle{Priority}.MainThread.Full" units="ms" - expires_after="M136"> + expires_after="2025-06-15"> <owner>nikolaos@chromium.org</owner> <owner>v8-memory-sheriffs@google.com</owner> <summary> @@ -1230,7 +1231,7 @@ </histogram> <histogram name="V8.GC.Cycle{Priority}.MainThread.Full.Sweep.Cpp" units="ms" - expires_after="M136"> + expires_after="2025-06-15"> <owner>omerkatz@chromium.org</owner> <owner>v8-memory-sheriffs@google.com</owner> <summary> @@ -1281,7 +1282,7 @@ </histogram> <histogram name="V8.GC.Cycle{Priority}.MainThread.Young" units="ms" - expires_after="M136"> + expires_after="2025-06-15"> <owner>nikolaos@chromium.org</owner> <owner>v8-memory-sheriffs@google.com</owner> <summary> @@ -1457,7 +1458,8 @@ </token> </histogram> -<histogram name="V8.GC.Cycle{Priority}.Young" units="ms" expires_after="M136"> +<histogram name="V8.GC.Cycle{Priority}.Young" units="ms" + expires_after="2025-06-15"> <owner>nikolaos@chromium.org</owner> <owner>v8-memory-sheriffs@google.com</owner> <summary> @@ -2217,7 +2219,7 @@ </histogram> <histogram name="V8.WasmCodeCaching" enum="WasmCodeCaching" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>ahaas@chromium.org</owner> <owner>clemensb@chromium.org</owner> <owner>wasm-runtime@google.com</owner> @@ -2355,7 +2357,7 @@ </histogram> <histogram name="V8.WasmDeserializationTimeMilliSeconds" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>ahaas@chromium.org</owner> <owner>clemensb@chromium.org</owner> <owner>ecmziegler@chromium.org</owner> @@ -2572,7 +2574,7 @@ </histogram> <histogram name="V8.WasmModuleSizeBytes" units="bytes" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>ecmziegler@chromium.org</owner> <owner>adamk@chromium.org</owner> <owner>ahaas@chromium.org</owner> @@ -2607,7 +2609,7 @@ </histogram> <histogram name="V8.WasmSerializationTimeMilliSeconds" units="ms" - expires_after="2025-04-13"> + expires_after="2025-06-15"> <owner>ahaas@chromium.org</owner> <owner>clemensb@chromium.org</owner> <owner>ecmziegler@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/webauthn/enums.xml b/tools/metrics/histograms/metadata/webauthn/enums.xml index c7786eb1..de4955b 100644 --- a/tools/metrics/histograms/metadata/webauthn/enums.xml +++ b/tools/metrics/histograms/metadata/webauthn/enums.xml
@@ -74,6 +74,18 @@ <int value="4" label="prepareGetCredential request failed."/> </enum> +<enum name="GPMGetAssertionEvents"> + <int value="0" label="Started - GPM passkey selected"/> + <int value="1" label="Success - Authentication complete"/> + <int value="2" label="Failure - Error dialog shown"/> +</enum> + +<enum name="GPMMakeCredentialEvents"> + <int value="0" label="Started - Create GPM passkey dialog shown"/> + <int value="1" label="Success - Passkey saved"/> + <int value="2" label="Failure - Error dialog shown"/> +</enum> + <enum name="OnboardingEvents"> <int value="0" label="Started (Create GPM passkey dialog shown)"/> <int value="1" label="Succeeded (GPM passkey created)"/> @@ -304,6 +316,16 @@ <int value="17" label="Other Failure"/> </enum> +<enum name="WebAuthenticationPinRenewalEvent"> + <int value="0" label="Considered renewing the PIN"/> + <int value="1" label="No PIN to renew"/> + <int value="2" label="Another renewal was running concurrently"/> + <int value="3" label="Not yet time to renew"/> + <int value="4" label="Started renewal"/> + <int value="5" label="Successful renewal"/> + <int value="6" label="Renewal failed"/> +</enum> + <enum name="WebAuthenticationRequestMode"> <int value="0" label="WebAuthn Modal Request"/> <int value="1" label="WebAuthn Conditional UI Request"/>
diff --git a/tools/metrics/histograms/metadata/webauthn/histograms.xml b/tools/metrics/histograms/metadata/webauthn/histograms.xml index 52cf45c0..8ddf272 100644 --- a/tools/metrics/histograms/metadata/webauthn/histograms.xml +++ b/tools/metrics/histograms/metadata/webauthn/histograms.xml
@@ -307,6 +307,28 @@ </summary> </histogram> +<histogram name="WebAuthentication.GPM.GetAssertion" + enum="GPMGetAssertionEvents" expires_after="2025-09-17"> + <owner>natiahlyi@google.com</owner> + <owner>chrome-webauthn@google.com</owner> + <summary> + Records start, success, and failure events for Google Password Manager (GPM) + passkey authentication attempts (GetAssertion calls). Each event is emitted + immediately after it occurs. See GPMGetAssertionEvents enum for details. + </summary> +</histogram> + +<histogram name="WebAuthentication.GPM.MakeCredential" + enum="GPMMakeCredentialEvents" expires_after="2025-09-17"> + <owner>natiahlyi@google.com</owner> + <owner>chrome-webauthn@google.com</owner> + <summary> + Records start, success, and failure events for Google Password Manager (GPM) + passkey creation attempts (MakeCredential calls). Each event is emitted + immediately after it occurs. See GPMMakeCredentialEvents enum for details. + </summary> +</histogram> + <histogram name="WebAuthentication.IsUVPlatformAuthenticatorAvailable2" enum="Boolean" expires_after="2025-06-08"> <owner>kenrb@chromium.org</owner> @@ -366,6 +388,13 @@ </summary> </histogram> +<histogram name="WebAuthentication.PinRenewalEvent" + enum="WebAuthenticationPinRenewalEvent" expires_after="2025-05-11"> + <owner>agl@google.com</owner> + <owner>kenrb@chromium.org</owner> + <summary>Records events related to GPM PIN renewals</summary> +</histogram> + <histogram name="WebAuthentication.SignalAllAcceptedCredentialsRemovedGPMPasskey" enum="SignalAllAcceptedCredentialsResult" expires_after="2025-09-17">
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index ba792ee..66b713b 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,28 +1,28 @@ { "trace_processor_shell": { "linux_arm64": { - "hash": "4a488010ab1427a327f1b9fd4045dd0f3bc813ff", - "full_remote_path": "perfetto-luci-artifacts/76778cdf92dd1795698ce9d4742484645e06074b/linux-arm64/trace_processor_shell" + "hash": "1839ff51215f9b27b4e4524dd2075e512e30a27a", + "full_remote_path": "perfetto-luci-artifacts/5bf4e2a65d76d5a603ff175222d1513f71d28a0b/linux-arm64/trace_processor_shell" }, "win": { - "hash": "8cc6b5adcb8a549b89df25699bab0ab17d8cb376", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/076d3983da9bbbe312f1c8d5fb77867e9a41779d/trace_processor_shell.exe" + "hash": "12ad3c9f266de117858859f1f5b5dee2694bf0ba", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/5bf4e2a65d76d5a603ff175222d1513f71d28a0b/trace_processor_shell.exe" }, "linux_arm": { - "hash": "296798e193cbca9d79cbe293f93ab8acf194bec1", - "full_remote_path": "perfetto-luci-artifacts/76778cdf92dd1795698ce9d4742484645e06074b/linux-arm/trace_processor_shell" + "hash": "e250187786aa190a66288bc9443a5e1f5888f8d7", + "full_remote_path": "perfetto-luci-artifacts/5bf4e2a65d76d5a603ff175222d1513f71d28a0b/linux-arm/trace_processor_shell" }, "mac": { "hash": "f5d83eca972747f7c3db9f35c07ed57902418e8c", "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/881ad50c05049ca13d4b34e4f92f4167de5ac52a/trace_processor_shell" }, "mac_arm64": { - "hash": "ab2319a0ae7ca06fa899436b0a477e26d2329ede", - "full_remote_path": "perfetto-luci-artifacts/76778cdf92dd1795698ce9d4742484645e06074b/mac-arm64/trace_processor_shell" + "hash": "cf5cd094ca2e4424fb59f6e9c872130feb1e3462", + "full_remote_path": "perfetto-luci-artifacts/5bf4e2a65d76d5a603ff175222d1513f71d28a0b/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "c01f98651b2164002c7818d8096e13a04255e11b", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/6361af291ce8ffd1f992fec3f44483c00bba124e/trace_processor_shell" + "hash": "6732a9390a195cdf1573174c41c79892bd862c87", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/5bf4e2a65d76d5a603ff175222d1513f71d28a0b/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/android/java/src/org/chromium/ui/AsyncViewProvider.java b/ui/android/java/src/org/chromium/ui/AsyncViewProvider.java index 7587e87..8f96de3 100644 --- a/ui/android/java/src/org/chromium/ui/AsyncViewProvider.java +++ b/ui/android/java/src/org/chromium/ui/AsyncViewProvider.java
@@ -4,27 +4,29 @@ package org.chromium.ui; -import android.view.View; +import static org.chromium.build.NullUtil.assumeNonNull; -import androidx.annotation.Nullable; +import android.view.View; import org.chromium.base.Callback; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * A provider that encapsulates a {@link View} that is in the view hierarchy to be inflated by * an {@link AsyncViewStub}. * @param <T> type of the {@link View} that this provider encapsulates. */ +@NullMarked public class AsyncViewProvider<T extends View> implements Callback<View>, ViewProvider<T> { private int mResId; // Exactly one of mView and mViewStub is non-null at any point. - private T mView; - private AsyncViewStub mViewStub; + private @Nullable T mView; + private @Nullable AsyncViewStub mViewStub; private boolean mDestroyed; private AsyncViewProvider(AsyncViewStub viewStub, int resId) { - assert viewStub != null; mResId = resId; mViewStub = viewStub; } @@ -45,8 +47,9 @@ */ public static <E extends View> AsyncViewProvider<E> of(AsyncViewStub viewStub, int resId) { ThreadUtils.assertOnUiThread(); - if (viewStub.getInflatedView() != null) { - return new AsyncViewProvider<>(viewStub.getInflatedView().findViewById(resId)); + View inflatedView = viewStub.getInflatedView(); + if (inflatedView != null) { + return new AsyncViewProvider<>(inflatedView.findViewById(resId)); } AsyncViewProvider<E> provider = new AsyncViewProvider<>(viewStub, resId); viewStub.addOnInflateListener(provider); @@ -85,8 +88,7 @@ * @return the {@link View} encapsulated by this provider or null (if the view has not been * inflated yet). */ - @Nullable - public T get() { + public @Nullable T get() { return mView; } @@ -101,12 +103,12 @@ if (mView != null) { return new AsyncViewProvider<>(mView.findViewById(resId)); } - return of(mViewStub, resId); + return of(assumeNonNull(mViewStub), resId); } @Override public void inflate() { - mViewStub.inflate(); + assumeNonNull(mViewStub).inflate(); } @Override @@ -117,25 +119,19 @@ // fire right now if view already inflated. callback.onResult(mView); } else { - mViewStub.addOnInflateListener( - (View view) -> { - if (mDestroyed) return; - // listeners are called in order so mView should be set correctly at this - // point. - callback.onResult(mView); - }); + assumeNonNull(mViewStub) + .addOnInflateListener( + (View view) -> { + if (mDestroyed) return; + // listeners are called in order so mView should be set correctly at + // this + // point. + callback.onResult(assumeNonNull(mView)); + }); } } /** - * Destroy the provider making sure that all queued up after inflate callbacks are no longer - * called. - */ - public void destroy() { - destroy(null); - } - - /** * Same as {@link #destroy()} but takes a callback that is ensured to be run (either immediately * if the view is already inflated or after inflation of the {@link AsyncViewStub})). */ @@ -148,7 +144,7 @@ if (mViewStub != null) { mViewStub.addOnInflateListener( (View view) -> { - destroyCallback.onResult(mView); + destroyCallback.onResult(assumeNonNull(mView)); }); mViewStub = null; }
diff --git a/ui/android/java/src/org/chromium/ui/AsyncViewStub.java b/ui/android/java/src/org/chromium/ui/AsyncViewStub.java index 69848d0..0efa95bc 100644 --- a/ui/android/java/src/org/chromium/ui/AsyncViewStub.java +++ b/ui/android/java/src/org/chromium/ui/AsyncViewStub.java
@@ -14,13 +14,14 @@ import android.view.ViewGroup; import android.view.ViewParent; -import androidx.annotation.NonNull; import androidx.asynclayoutinflater.view.AsyncLayoutInflater; import org.chromium.base.Callback; import org.chromium.base.ObserverList; import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * An implementation of ViewStub that inflates the view in a background thread. Callbacks are still @@ -28,9 +29,10 @@ * * <p>TODO(crbug.com/40937701): Deprecate AsyncViewStub or make it per activity. */ +@NullMarked public class AsyncViewStub extends View implements AsyncLayoutInflater.OnInflateFinishedListener { private int mLayoutResource; - private View mInflatedView; + private @Nullable View mInflatedView; private AsyncLayoutInflater mAsyncLayoutInflater; @@ -72,7 +74,8 @@ protected void dispatchDraw(Canvas canvas) {} @Override - public void onInflateFinished(@NonNull View view, int resId, ViewGroup parent) { + public void onInflateFinished(View view, int resId, @Nullable ViewGroup parent) { + assert parent != null; mInflatedView = view; replaceSelfWithView(view, parent); callListeners(view); @@ -135,6 +138,7 @@ /** * @return the inflated view or null if inflation is not complete yet. */ + @Nullable View getInflatedView() { return mInflatedView; }
diff --git a/ui/android/java/src/org/chromium/ui/DeferredViewStubInflationProvider.java b/ui/android/java/src/org/chromium/ui/DeferredViewStubInflationProvider.java index 7da9d9d..85666008 100644 --- a/ui/android/java/src/org/chromium/ui/DeferredViewStubInflationProvider.java +++ b/ui/android/java/src/org/chromium/ui/DeferredViewStubInflationProvider.java
@@ -9,12 +9,14 @@ import org.chromium.base.Callback; import org.chromium.base.Promise; +import org.chromium.build.annotations.NullMarked; /** * View provider that inflates a ViewStub. This does not support inflation on a background thread, * therefore {@link AsyncViewProvider} should be preferred. * @param <T> The view type. */ +@NullMarked public class DeferredViewStubInflationProvider<T extends View> implements ViewProvider<T> { private final ViewStub mViewStub; private Promise<T> mViewPromise = new Promise<>();
diff --git a/ui/android/java/src/org/chromium/ui/DropdownAdapter.java b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java index 62d08675..230d80a 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownAdapter.java +++ b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java
@@ -4,6 +4,8 @@ package org.chromium.ui; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.graphics.Color; import android.graphics.Typeface; @@ -22,10 +24,15 @@ import androidx.core.view.MarginLayoutParamsCompat; import androidx.core.view.ViewCompat; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; + import java.util.List; import java.util.Set; /** Dropdown item adapter for DropdownPopupWindow. */ +@NullMarked public class DropdownAdapter extends ArrayAdapter<DropdownItem> { private final Context mContext; private final Set<Integer> mSeparators; @@ -51,7 +58,7 @@ private boolean checkAreAllItemsEnabled() { for (int i = 0; i < getCount(); i++) { - DropdownItem item = getItem(i); + DropdownItem item = assumeNonNull(getItem(i)); if (item.isEnabled() && !item.isGroupHeader()) { return false; } @@ -59,8 +66,9 @@ return true; } + @NullUnmarked @Override - public View getView(int position, View convertView, ViewGroup parent) { + public View getView(int position, @Nullable View convertView, ViewGroup parent) { View layout = convertView; if (convertView == null) { LayoutInflater inflater = @@ -88,7 +96,7 @@ divider.setDividerColor(dividerColor); } - DropdownItem item = getItem(position); + DropdownItem item = assumeNonNull(getItem(position)); // Note: trying to set the height of the root LinearLayout breaks accessibility, // so we have to adjust the height of this LinearLayout that wraps the TextViews instead. @@ -179,7 +187,7 @@ @Override public boolean isEnabled(int position) { if (position < 0 || position >= getCount()) return false; - DropdownItem item = getItem(position); + DropdownItem item = assumeNonNull(getItem(position)); return item.isEnabled() && !item.isGroupHeader(); } }
diff --git a/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java b/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java index 7002ac01..8adfae6 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java +++ b/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java
@@ -11,18 +11,22 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** A drawable divider to be used by dropdown adapters. */ +@NullMarked public class DropdownDividerDrawable extends Drawable { private final Paint mPaint; private final Rect mDividerRect; - private final Integer mBackgroundColor; + private final @Nullable Integer mBackgroundColor; /** * Creates a drawable to draw a divider line that separates the list of {@link DropdownItem} * and, optionally, paints the rectangular canvas. * @param backgroundColor Popup background color. If {@code null}, does not paint the canvas. */ - public DropdownDividerDrawable(Integer backgroundColor) { + public DropdownDividerDrawable(@Nullable Integer backgroundColor) { mPaint = new Paint(); mDividerRect = new Rect(); mBackgroundColor = backgroundColor; @@ -51,7 +55,7 @@ public void setAlpha(int alpha) {} @Override - public void setColorFilter(ColorFilter cf) {} + public void setColorFilter(@Nullable ColorFilter cf) {} @Override public int getOpacity() {
diff --git a/ui/android/java/src/org/chromium/ui/DropdownItem.java b/ui/android/java/src/org/chromium/ui/DropdownItem.java index 133f892..26b897c1 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownItem.java +++ b/ui/android/java/src/org/chromium/ui/DropdownItem.java
@@ -6,16 +6,18 @@ import android.graphics.drawable.Drawable; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.url.GURL; /** Dropdown item interface used to access all the information needed to show the item. */ +@NullMarked public interface DropdownItem { // A stand in for a resource ID which indicates no icon should be shown. public static final int NO_ICON = 0; /** Returns the first part of the first line that should be shown in the dropdown. */ + @Nullable String getLabel(); /** Returns the second part of the first line that should be shown in the dropdown. */ @@ -23,6 +25,7 @@ String getSecondaryLabel(); /** Returns the first part of the second line that should be shown in the dropdown. */ + @Nullable String getSublabel(); /** Returns the second part of the second line that should be shown in the dropdown. */ @@ -30,6 +33,7 @@ String getSecondarySublabel(); /** Returns the item tag that should be shown in the dropdown. */ + @Nullable String getItemTag(); /** @@ -43,6 +47,7 @@ * Returns the url for the icon to be downloaded. If present, the downloaded icon should be * preferred over the resource id returned by getIconId(). */ + @Nullable GURL getCustomIconUrl(); /**
diff --git a/ui/android/java/src/org/chromium/ui/DropdownItemBase.java b/ui/android/java/src/org/chromium/ui/DropdownItemBase.java index 1089a64..672a5216 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownItemBase.java +++ b/ui/android/java/src/org/chromium/ui/DropdownItemBase.java
@@ -6,37 +6,38 @@ import android.graphics.drawable.Drawable; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.url.GURL; /** * Base implementation of DropdownItem which is used to get default settings to * show the item. */ +@NullMarked public class DropdownItemBase implements DropdownItem { @Override - public String getLabel() { + public @Nullable String getLabel() { return null; } @Override - public String getSecondaryLabel() { + public @Nullable String getSecondaryLabel() { return null; } @Override - public String getSublabel() { + public @Nullable String getSublabel() { return null; } @Override - public String getSecondarySublabel() { + public @Nullable String getSecondarySublabel() { return null; } @Override - public String getItemTag() { + public @Nullable String getItemTag() { return null; } @@ -101,13 +102,12 @@ } @Override - public GURL getCustomIconUrl() { + public @Nullable GURL getCustomIconUrl() { return null; } @Override - @Nullable - public Drawable getIconDrawable() { + public @Nullable Drawable getIconDrawable() { return null; } }
diff --git a/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java b/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java index 81a2c23..541ab6c 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java +++ b/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java
@@ -11,13 +11,14 @@ import android.widget.ListView; import android.widget.PopupWindow; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.widget.AnchoredPopupWindow; import org.chromium.ui.widget.RectProvider; // TODO(crbug.com/40250394): This class is a noop now, so we should remove it. /** The dropdown popup window that decides what widget should be used for the popup. */ +@NullMarked public class DropdownPopupWindow { private DropdownPopupWindowInterface mPopup;
diff --git a/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java b/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java index 141c888..1d39210 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java +++ b/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java
@@ -15,9 +15,10 @@ import android.widget.ListView; import android.widget.PopupWindow; -import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.widget.AnchoredPopupWindow; import org.chromium.ui.widget.RectProvider; import org.chromium.ui.widget.ViewRectProvider; @@ -26,6 +27,7 @@ * The dropdown popup window for use on Lollipop+. Internally uses an AnchoredPopupWindow * anchored to a view to display a list of options. */ +@NullMarked class DropdownPopupWindowImpl implements AnchoredPopupWindow.LayoutObserver, DropdownPopupWindowInterface { private final Context mContext; @@ -33,9 +35,9 @@ private boolean mRtl; private int mInitialSelection = -1; private OnLayoutChangeListener mLayoutChangeListener; - private CharSequence mDescription; + private @Nullable CharSequence mDescription; private AnchoredPopupWindow mAnchoredPopupWindow; - ListAdapter mAdapter; + @Nullable ListAdapter mAdapter; private final ListView mListView; private Drawable mBackground;
diff --git a/ui/android/java/src/org/chromium/ui/DropdownPopupWindowInterface.java b/ui/android/java/src/org/chromium/ui/DropdownPopupWindowInterface.java index 0ea20fe..6aaeea04 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownPopupWindowInterface.java +++ b/ui/android/java/src/org/chromium/ui/DropdownPopupWindowInterface.java
@@ -9,7 +9,10 @@ import android.widget.ListView; import android.widget.PopupWindow; +import org.chromium.build.annotations.NullMarked; + /** The interface for dropdown popup window. */ +@NullMarked public interface DropdownPopupWindowInterface { /** * Sets the adapter that provides the data and the views to represent the data
diff --git a/ui/android/java/src/org/chromium/ui/ElidedUrlTextView.java b/ui/android/java/src/org/chromium/ui/ElidedUrlTextView.java index 088992d..ddf5768 100644 --- a/ui/android/java/src/org/chromium/ui/ElidedUrlTextView.java +++ b/ui/android/java/src/org/chromium/ui/ElidedUrlTextView.java
@@ -4,24 +4,31 @@ package org.chromium.ui; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.text.Layout; import android.util.AttributeSet; import androidx.appcompat.widget.AppCompatTextView; +import org.chromium.build.annotations.NullMarked; + /** * A TextView which truncates and displays a URL such that the origin is always visible. * The URL can be expanded by clicking on the it. */ +@NullMarked public class ElidedUrlTextView extends AppCompatTextView { // The number of lines to display when the URL is truncated. This number // should still allow the origin to be displayed. NULL before // setUrlAfterLayout() is called. + @SuppressWarnings("NullAway.Init") private Integer mTruncatedUrlLinesToDisplay; // The number of lines to display when the URL is expanded. This should be enough to display // at most two lines of the fragment if there is one in the URL. + @SuppressWarnings("NullAway.Init") private Integer mFullLinesToDisplay; // If true, the text view will show the truncated text. If false, it @@ -50,7 +57,7 @@ * a given index. */ private int getLineForIndex(int index) { - Layout layout = getLayout(); + Layout layout = assumeNonNull(getLayout()); int endLine = 0; while (endLine < layout.getLineCount() && layout.getLineEnd(endLine) < index) { endLine++;
diff --git a/ui/android/java/src/org/chromium/ui/HorizontalListDividerDrawable.java b/ui/android/java/src/org/chromium/ui/HorizontalListDividerDrawable.java index 308509c1..443e404 100644 --- a/ui/android/java/src/org/chromium/ui/HorizontalListDividerDrawable.java +++ b/ui/android/java/src/org/chromium/ui/HorizontalListDividerDrawable.java
@@ -10,12 +10,15 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; +import org.chromium.build.annotations.NullMarked; + /** * Draws a horizontal list divider line at the bottom of its drawing area. * * Because ?android:attr/listDivider may be a 9-patch, there's no way to achieve this drawing * effect with the platform Drawable classes; hence this custom Drawable. */ +@NullMarked public class HorizontalListDividerDrawable extends LayerDrawable { /** * Create a horizontal list divider drawable.
diff --git a/ui/android/java/src/org/chromium/ui/InsetObserver.java b/ui/android/java/src/org/chromium/ui/InsetObserver.java index 90a1fd60..cf26c5e 100644 --- a/ui/android/java/src/org/chromium/ui/InsetObserver.java +++ b/ui/android/java/src/org/chromium/ui/InsetObserver.java
@@ -8,8 +8,6 @@ import android.view.View; import androidx.annotation.IntDef; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.core.graphics.Insets; import androidx.core.view.DisplayCutoutCompat; import androidx.core.view.OnApplyWindowInsetsListener; @@ -22,6 +20,8 @@ import org.chromium.base.ResettersForTesting; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.InsetObserver.WindowInsetsConsumer.InsetConsumerSource; import org.chromium.ui.base.ImmutableWeakReference; @@ -32,6 +32,7 @@ /** * The purpose of this class is to store the system window insets (OSK, status bar) for later use. */ +@NullMarked public class InsetObserver implements OnApplyWindowInsetsListener { private final Rect mWindowInsets; private final Rect mCurrentSafeArea; @@ -41,7 +42,7 @@ private final WindowInsetsAnimationCompat.Callback mWindowInsetsAnimationProxyCallback; private final ObserverList<WindowInsetsAnimationListener> mWindowInsetsAnimationListeners = new ObserverList<>(); - private final WindowInsetsConsumer[] mInsetsConsumers = + private final @Nullable WindowInsetsConsumer[] mInsetsConsumers = new WindowInsetsConsumer[InsetConsumerSource.COUNT]; private final ImmutableWeakReference<View> mRootViewReference; @@ -50,7 +51,7 @@ private final Rect mDisplayCutoutRect; // Cached state - private WindowInsetsCompat mLastSeenRawWindowInset; + private @Nullable WindowInsetsCompat mLastSeenRawWindowInset; private static @Nullable WindowInsetsCompat sInitialRawWindowInsetsForTesting; /** Allows observing changes to the window insets from Android system UI. */ @@ -126,17 +127,16 @@ * dispatched to the subtree. See {@link WindowInsetsAnimationCompat.Callback} for more. */ public interface WindowInsetsAnimationListener { - void onPrepare(@NonNull WindowInsetsAnimationCompat animation); + void onPrepare(WindowInsetsAnimationCompat animation); void onStart( - @NonNull WindowInsetsAnimationCompat animation, - @NonNull WindowInsetsAnimationCompat.BoundsCompat bounds); + WindowInsetsAnimationCompat animation, + WindowInsetsAnimationCompat.BoundsCompat bounds); void onProgress( - @NonNull WindowInsetsCompat windowInsetsCompat, - @NonNull List<WindowInsetsAnimationCompat> list); + WindowInsetsCompat windowInsetsCompat, List<WindowInsetsAnimationCompat> list); - void onEnd(@NonNull WindowInsetsAnimationCompat animation); + void onEnd(WindowInsetsAnimationCompat animation); } private static class KeyboardInsetObservableSupplier extends ObservableSupplierImpl<Integer> @@ -165,7 +165,7 @@ new WindowInsetsAnimationCompat.Callback( WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP) { @Override - public void onPrepare(@NonNull WindowInsetsAnimationCompat animation) { + public void onPrepare(WindowInsetsAnimationCompat animation) { for (WindowInsetsAnimationListener listener : mWindowInsetsAnimationListeners) { listener.onPrepare(animation); @@ -173,11 +173,9 @@ super.onPrepare(animation); } - @NonNull @Override public BoundsCompat onStart( - @NonNull WindowInsetsAnimationCompat animation, - @NonNull BoundsCompat bounds) { + WindowInsetsAnimationCompat animation, BoundsCompat bounds) { for (WindowInsetsAnimationListener listener : mWindowInsetsAnimationListeners) { listener.onStart(animation, bounds); @@ -186,7 +184,7 @@ } @Override - public void onEnd(@NonNull WindowInsetsAnimationCompat animation) { + public void onEnd(WindowInsetsAnimationCompat animation) { for (WindowInsetsAnimationListener listener : mWindowInsetsAnimationListeners) { listener.onEnd(animation); @@ -194,11 +192,10 @@ super.onEnd(animation); } - @NonNull @Override public WindowInsetsCompat onProgress( - @NonNull WindowInsetsCompat windowInsetsCompat, - @NonNull List<WindowInsetsAnimationCompat> list) { + WindowInsetsCompat windowInsetsCompat, + List<WindowInsetsAnimationCompat> list) { for (WindowInsetsAnimationListener listener : mWindowInsetsAnimationListeners) { listener.onProgress(windowInsetsCompat, list); @@ -235,13 +232,13 @@ * order of a pre-defined priority value. */ public void addInsetsConsumer( - @NonNull WindowInsetsConsumer insetConsumer, @InsetConsumerSource int source) { + WindowInsetsConsumer insetConsumer, @InsetConsumerSource int source) { assert mInsetsConsumers[source] == null : "Inset consumer source has already been added."; mInsetsConsumers[source] = insetConsumer; } /** Remove a consumer of window insets. */ - public void removeInsetsConsumer(@NonNull WindowInsetsConsumer insetConsumer) { + public void removeInsetsConsumer(WindowInsetsConsumer insetConsumer) { for (int i = 0; i < mInsetsConsumers.length; i++) { if (mInsetsConsumers[i] == insetConsumer) { mInsetsConsumers[i] = null; @@ -251,13 +248,12 @@ } /** Add a listener for inset animations. */ - public void addWindowInsetsAnimationListener(@NonNull WindowInsetsAnimationListener listener) { + public void addWindowInsetsAnimationListener(WindowInsetsAnimationListener listener) { mWindowInsetsAnimationListeners.addObserver(listener); } /** Remove a listener for inset animations. */ - public void removeWindowInsetsAnimationListener( - @NonNull WindowInsetsAnimationListener listener) { + public void removeWindowInsetsAnimationListener(WindowInsetsAnimationListener listener) { mWindowInsetsAnimationListeners.removeObserver(listener); } @@ -277,8 +273,7 @@ * This should only be used for clients interested in reading a specific type of the insets; * otherwise, the client should be registered as a {@link WindowInsetsConsumer}. */ - @Nullable - public WindowInsetsCompat getLastRawWindowInsets() { + public @Nullable WindowInsetsCompat getLastRawWindowInsets() { return mLastSeenRawWindowInset; } @@ -294,10 +289,8 @@ return mWindowInsetsAnimationProxyCallback; } - @NonNull @Override - public WindowInsetsCompat onApplyWindowInsets( - @NonNull View view, @NonNull WindowInsetsCompat insets) { + public WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) { mLastSeenRawWindowInset = insets; updateDisplayCutoutRect(insets); @@ -415,7 +408,7 @@ ResettersForTesting.register(() -> sInitialRawWindowInsetsForTesting = null); } - private View getRootView() { + private @Nullable View getRootView() { return mRootViewReference.get(); } }
diff --git a/ui/android/java/src/org/chromium/ui/InsetsRectProvider.java b/ui/android/java/src/org/chromium/ui/InsetsRectProvider.java index 908ae6f..423197a 100644 --- a/ui/android/java/src/org/chromium/ui/InsetsRectProvider.java +++ b/ui/android/java/src/org/chromium/ui/InsetsRectProvider.java
@@ -11,12 +11,13 @@ import android.view.View; import android.view.WindowInsets; -import androidx.annotation.NonNull; import androidx.core.graphics.Insets; import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat.Type.InsetsType; import org.chromium.base.ObserverList; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.InsetObserver.WindowInsetsConsumer; import org.chromium.ui.util.WindowInsetsUtils; @@ -37,6 +38,7 @@ * <li>1. Android version is at least R. * <li>2. WindowInsets of given type has insets from one side exactly. */ +@NullMarked public class InsetsRectProvider implements WindowInsetsConsumer { /** Observer interface that's interested in bounding rect updates. */ public interface Observer { @@ -50,7 +52,7 @@ private final ObserverList<Observer> mObservers = new ObserverList<>(); private final InsetObserver mInsetObserver; - private WindowInsetsCompat mCachedInsets; + private @Nullable WindowInsetsCompat mCachedInsets; private List<Rect> mBoundingRects; private Rect mWidestUnoccludedRect = new Rect(); @@ -65,7 +67,7 @@ * consumption. */ public InsetsRectProvider( - @NonNull InsetObserver insetObserver, + InsetObserver insetObserver, @InsetsType int insetType, WindowInsetsCompat initialInsets, @InsetConsumerSource int insetConsumerSource) { @@ -90,7 +92,6 @@ * is an area within the window insets that is not covered by the bounding rects of that window * insets. */ - @NonNull public Rect getWidestUnoccludedRect() { return mWidestUnoccludedRect; } @@ -126,10 +127,10 @@ } // Implements WindowInsetsConsumer - @NonNull + @Override public WindowInsetsCompat onApplyWindowInsets( - @NonNull View view, @NonNull WindowInsetsCompat windowInsetsCompat) { + View view, WindowInsetsCompat windowInsetsCompat) { // Ignore the input by version check. if (VERSION.SDK_INT < VERSION_CODES.R) { return windowInsetsCompat;
diff --git a/ui/android/java/src/org/chromium/ui/KeyboardUtils.java b/ui/android/java/src/org/chromium/ui/KeyboardUtils.java index 71999e4..5f94bf7 100644 --- a/ui/android/java/src/org/chromium/ui/KeyboardUtils.java +++ b/ui/android/java/src/org/chromium/ui/KeyboardUtils.java
@@ -15,10 +15,12 @@ import org.chromium.base.Log; import org.chromium.base.TraceEvent; +import org.chromium.build.annotations.NullMarked; import java.util.concurrent.atomic.AtomicInteger; /** Utility methods used for Android's software keyboard. */ +@NullMarked public final class KeyboardUtils { private static final String TAG = "KeyboardVisibility";
diff --git a/ui/android/java/src/org/chromium/ui/KeyboardVisibilityDelegate.java b/ui/android/java/src/org/chromium/ui/KeyboardVisibilityDelegate.java index 2275e92..5d7f283f 100644 --- a/ui/android/java/src/org/chromium/ui/KeyboardVisibilityDelegate.java +++ b/ui/android/java/src/org/chromium/ui/KeyboardVisibilityDelegate.java
@@ -8,11 +8,13 @@ import android.view.View; import org.chromium.base.ObserverList; +import org.chromium.build.annotations.NullMarked; /** * A delegate that can be overridden to change the methods to figure out and change the current * state of Android's soft keyboard. */ +@NullMarked public class KeyboardVisibilityDelegate { /** The delegate to determine keyboard visibility. */
diff --git a/ui/android/java/src/org/chromium/ui/LayoutInflaterUtils.java b/ui/android/java/src/org/chromium/ui/LayoutInflaterUtils.java index 43f72ab..53529e36 100644 --- a/ui/android/java/src/org/chromium/ui/LayoutInflaterUtils.java +++ b/ui/android/java/src/org/chromium/ui/LayoutInflaterUtils.java
@@ -10,9 +10,9 @@ import android.view.ViewGroup; import android.view.Window; -import androidx.annotation.Nullable; - import org.chromium.base.StrictModeContext; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * {@link LayoutInflater} wrapper class which suppresses strict mode violations. A helper class is @@ -21,6 +21,7 @@ * because we only want to suppress strict mode violations caused by Chromium usage of * LayoutInflater and not usage by embedders of Web Layer or Web View. */ +@NullMarked public class LayoutInflaterUtils { public static View inflate(Context context, int resource, @Nullable ViewGroup root) { return inflate(context, resource, root, root != null); @@ -46,7 +47,7 @@ } private static View inflateImpl( - LayoutInflater inflater, int resource, ViewGroup root, boolean attachToRoot) { + LayoutInflater inflater, int resource, @Nullable ViewGroup root, boolean attachToRoot) { // LayoutInflater may trigger accessing disk. try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) { return inflater.inflate(resource, root, attachToRoot);
diff --git a/ui/android/java/src/org/chromium/ui/ModalDialogWrapper.java b/ui/android/java/src/org/chromium/ui/ModalDialogWrapper.java index e127919..7e35912 100644 --- a/ui/android/java/src/org/chromium/ui/ModalDialogWrapper.java +++ b/ui/android/java/src/org/chromium/ui/ModalDialogWrapper.java
@@ -4,10 +4,14 @@ package org.chromium.ui; +import static org.chromium.build.NullUtil.assumeNonNull; + import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; @@ -15,11 +19,12 @@ import org.chromium.ui.modelutil.PropertyModel; @JNINamespace("ui") +@NullMarked public class ModalDialogWrapper implements ModalDialogProperties.Controller { /** The native-side counterpart of this class */ private final long mNativeDelegatePtr; - private final ModalDialogManager mModalDialogManager; + private final @Nullable ModalDialogManager mModalDialogManager; private final PropertyModel.Builder mPropertyModelBuilder; @@ -55,10 +60,11 @@ @Override public void onClick(PropertyModel model, int buttonType) { + ModalDialogManager modalDialogManager = assumeNonNull(mModalDialogManager); if (buttonType == ModalDialogProperties.ButtonType.POSITIVE) { - mModalDialogManager.dismissDialog(model, DialogDismissalCause.POSITIVE_BUTTON_CLICKED); + modalDialogManager.dismissDialog(model, DialogDismissalCause.POSITIVE_BUTTON_CLICKED); } else { - mModalDialogManager.dismissDialog(model, DialogDismissalCause.NEGATIVE_BUTTON_CLICKED); + modalDialogManager.dismissDialog(model, DialogDismissalCause.NEGATIVE_BUTTON_CLICKED); } }
diff --git a/ui/android/java/src/org/chromium/ui/MotionEventUtils.java b/ui/android/java/src/org/chromium/ui/MotionEventUtils.java index f0e716ecd..d43cae1 100644 --- a/ui/android/java/src/org/chromium/ui/MotionEventUtils.java +++ b/ui/android/java/src/org/chromium/ui/MotionEventUtils.java
@@ -7,9 +7,9 @@ import android.os.Build; import android.view.MotionEvent; -import androidx.annotation.Nullable; - import org.chromium.base.TraceEvent; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -19,9 +19,10 @@ * * <p>Not thread safe. */ +@NullMarked public class MotionEventUtils { - @Nullable private static Method sGetTimeNanoMethod; + private static @Nullable Method sGetTimeNanoMethod; private static boolean sFailedReflection; /** @@ -61,7 +62,7 @@ } private static boolean sFailedDoubleReflection; - private static Method sGetHistoricalEventTimeNanoMethod; + private static @Nullable Method sGetHistoricalEventTimeNanoMethod; /** * Returns the time in nanoseconds, but with precision to milliseconds, of the given
diff --git a/ui/android/java/src/org/chromium/ui/OverscrollRefreshHandler.java b/ui/android/java/src/org/chromium/ui/OverscrollRefreshHandler.java index b8b8652..521e6c7 100644 --- a/ui/android/java/src/org/chromium/ui/OverscrollRefreshHandler.java +++ b/ui/android/java/src/org/chromium/ui/OverscrollRefreshHandler.java
@@ -6,9 +6,11 @@ import org.jni_zero.CalledByNative; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.base.BackGestureEventSwipeEdge; /** Simple interface allowing customized response to an overscrolling pull input. */ +@NullMarked public interface OverscrollRefreshHandler { /** * Signals the start of an overscrolling pull.
diff --git a/ui/android/java/src/org/chromium/ui/UiSwitches.java b/ui/android/java/src/org/chromium/ui/UiSwitches.java index 583e730..91fa7d9 100644 --- a/ui/android/java/src/org/chromium/ui/UiSwitches.java +++ b/ui/android/java/src/org/chromium/ui/UiSwitches.java
@@ -4,10 +4,13 @@ package org.chromium.ui; +import org.chromium.build.annotations.NullMarked; + /** * Contains all of the command line switches that are specific to the ui/ portion of Chromium on * Android. */ +@NullMarked public abstract class UiSwitches { // Enables the screenshot mode, which disables certain UI elements (e.g. dialogs) to facilitate // more easily scripting screenshots of web content.
diff --git a/ui/android/java/src/org/chromium/ui/UiUtils.java b/ui/android/java/src/org/chromium/ui/UiUtils.java index 914febb..0841642c 100644 --- a/ui/android/java/src/org/chromium/ui/UiUtils.java +++ b/ui/android/java/src/org/chromium/ui/UiUtils.java
@@ -34,7 +34,6 @@ import androidx.annotation.ColorRes; import androidx.annotation.DimenRes; import androidx.annotation.DrawableRes; -import androidx.annotation.Nullable; import androidx.annotation.StyleableRes; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.graphics.Insets; @@ -44,6 +43,8 @@ import org.chromium.base.BuildInfo; import org.chromium.base.ContextUtils; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -55,6 +56,7 @@ * Utility functions for common Android UI tasks. * This class is not supposed to be instantiated. */ +@NullMarked public class UiUtils { private static final String TAG = "UiUtils"; @@ -140,7 +142,7 @@ * @param bitmapConfig Bitmap config for the generated screenshot (ARGB_8888 or RGB_565). * @return The screen bitmap of the view or null if a problem was encountered. */ - public static Bitmap generateScaledScreenshot( + public static @Nullable Bitmap generateScaledScreenshot( View currentView, int maximumDimension, Bitmap.Config bitmapConfig) { Bitmap screenshot = null; boolean drawingCacheEnabled = currentView.isDrawingCacheEnabled(); @@ -253,7 +255,7 @@ * height of all items stored at index 1. */ public static int[] computeListAdapterContentDimensions( - ListAdapter adapter, ViewGroup parentView) { + ListAdapter adapter, @Nullable ViewGroup parentView) { final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); AbsListView.LayoutParams params =
diff --git a/ui/android/java/src/org/chromium/ui/ViewProvider.java b/ui/android/java/src/org/chromium/ui/ViewProvider.java index e472b9a..1004eb8 100644 --- a/ui/android/java/src/org/chromium/ui/ViewProvider.java +++ b/ui/android/java/src/org/chromium/ui/ViewProvider.java
@@ -7,11 +7,13 @@ import android.view.View; import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; /** * Interface to support asynchronous inflation of views. * @param <T> The view type. */ +@NullMarked public interface ViewProvider<T> { /** Starts inflating the view. */ void inflate();
diff --git a/ui/android/java/src/org/chromium/ui/animation/AnimationHandler.java b/ui/android/java/src/org/chromium/ui/animation/AnimationHandler.java index 6ec0743..e315a96 100644 --- a/ui/android/java/src/org/chromium/ui/animation/AnimationHandler.java +++ b/ui/android/java/src/org/chromium/ui/animation/AnimationHandler.java
@@ -7,8 +7,8 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.Objects; @@ -16,6 +16,7 @@ * Keeps track of animations. Helps to ensure only one instance of this Animation is running at a * time. */ +@NullMarked public class AnimationHandler { private @Nullable Animator mCurrentAnimator; @@ -32,7 +33,7 @@ * Starts the animation. Ensures that the previous instance of the animation is complete prior * to starting said animation. */ - public void startAnimation(@NonNull Animator animation) { + public void startAnimation(Animator animation) { if (mCurrentAnimator != null) { forceFinishAnimation(); }
diff --git a/ui/android/java/src/org/chromium/ui/animation/AnimationPerformanceTracker.java b/ui/android/java/src/org/chromium/ui/animation/AnimationPerformanceTracker.java index 31dde681..7fbea27b 100644 --- a/ui/android/java/src/org/chromium/ui/animation/AnimationPerformanceTracker.java +++ b/ui/android/java/src/org/chromium/ui/animation/AnimationPerformanceTracker.java
@@ -6,14 +6,15 @@ import android.os.SystemClock; -import androidx.annotation.Nullable; - import org.chromium.base.ObserverList; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * Helper class for monitoring animation performance. Each {@link AnimationPerformanceTracker} can * track a single animation at a time and can supply results to multiple {@link Listeners}. */ +@NullMarked public class AnimationPerformanceTracker { /** Tracks metrics about animation performance. */ public static class AnimationMetrics {
diff --git a/ui/android/java/src/org/chromium/ui/animation/DrawableFadeInAnimatorFactory.java b/ui/android/java/src/org/chromium/ui/animation/DrawableFadeInAnimatorFactory.java index 53b51de..df4b22d3 100644 --- a/ui/android/java/src/org/chromium/ui/animation/DrawableFadeInAnimatorFactory.java +++ b/ui/android/java/src/org/chromium/ui/animation/DrawableFadeInAnimatorFactory.java
@@ -8,7 +8,10 @@ import android.animation.ValueAnimator; import android.graphics.drawable.Drawable; +import org.chromium.build.annotations.NullMarked; + /** Factory class for creating fade in animations for {@link Drawable} elements. */ +@NullMarked public class DrawableFadeInAnimatorFactory { /** * Creates an animation for fading a {@link Drawable} element in.
diff --git a/ui/android/java/src/org/chromium/ui/animation/DrawableTranslationAnimatorFactory.java b/ui/android/java/src/org/chromium/ui/animation/DrawableTranslationAnimatorFactory.java index 2641f22..c5c2f28 100644 --- a/ui/android/java/src/org/chromium/ui/animation/DrawableTranslationAnimatorFactory.java +++ b/ui/android/java/src/org/chromium/ui/animation/DrawableTranslationAnimatorFactory.java
@@ -10,7 +10,10 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; +import org.chromium.build.annotations.NullMarked; + /** Factory class for creating translation animations for {@link Drawable} elements. */ +@NullMarked public class DrawableTranslationAnimatorFactory { /** * Creates an animation for translations. The animator will begin at the maximum displacement
diff --git a/ui/android/java/src/org/chromium/ui/animation/EmptyAnimationListener.java b/ui/android/java/src/org/chromium/ui/animation/EmptyAnimationListener.java index 4c731fe..1203c8c 100644 --- a/ui/android/java/src/org/chromium/ui/animation/EmptyAnimationListener.java +++ b/ui/android/java/src/org/chromium/ui/animation/EmptyAnimationListener.java
@@ -7,7 +7,10 @@ import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; +import org.chromium.build.annotations.NullMarked; + /** Simple no-op default interface that allows subclasses to only implement methods as needed. */ +@NullMarked public interface EmptyAnimationListener extends AnimationListener { @Override default void onAnimationStart(Animation animation) {}
diff --git a/ui/android/java/src/org/chromium/ui/animation/PathAnimationUtils.java b/ui/android/java/src/org/chromium/ui/animation/PathAnimationUtils.java index 16f75cab..7274c35 100644 --- a/ui/android/java/src/org/chromium/ui/animation/PathAnimationUtils.java +++ b/ui/android/java/src/org/chromium/ui/animation/PathAnimationUtils.java
@@ -6,7 +6,10 @@ import android.graphics.RectF; +import org.chromium.build.annotations.NullMarked; + /** Utilities related to {@link android.graphics.Path} for animations */ +@NullMarked public class PathAnimationUtils { /** * Returns a RectF which represents the oval to perform Path#arcTo movements.
diff --git a/ui/android/java/src/org/chromium/ui/animation/TranslationAnimatorFactory.java b/ui/android/java/src/org/chromium/ui/animation/TranslationAnimatorFactory.java index 5f9120f5f..d42fa084 100644 --- a/ui/android/java/src/org/chromium/ui/animation/TranslationAnimatorFactory.java +++ b/ui/android/java/src/org/chromium/ui/animation/TranslationAnimatorFactory.java
@@ -7,7 +7,10 @@ import android.animation.Animator; import android.animation.ValueAnimator; +import org.chromium.build.annotations.NullMarked; + /** Factory class for creating animations for translations. */ +@NullMarked public class TranslationAnimatorFactory { @FunctionalInterface
diff --git a/ui/android/java/src/org/chromium/ui/base/ActivityIntentRequestTrackerDelegate.java b/ui/android/java/src/org/chromium/ui/base/ActivityIntentRequestTrackerDelegate.java index 7375d11..0cbe702 100644 --- a/ui/android/java/src/org/chromium/ui/base/ActivityIntentRequestTrackerDelegate.java +++ b/ui/android/java/src/org/chromium/ui/base/ActivityIntentRequestTrackerDelegate.java
@@ -10,11 +10,14 @@ import android.content.IntentSender; import android.content.IntentSender.SendIntentException; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.base.IntentRequestTracker.Delegate; import java.lang.ref.WeakReference; /** Chrome's implementation of the delegate of a IntentRequestTracker. */ +@NullMarked public class ActivityIntentRequestTrackerDelegate implements Delegate { // Just create one ImmutableWeakReference object to avoid gc churn. private final ImmutableWeakReference<Activity> mActivityWeakRefHolder; @@ -29,7 +32,7 @@ } @Override - public boolean startActivityForResult(Intent intent, int requestCode) { + public boolean startActivityForResult(@Nullable Intent intent, int requestCode) { Activity activity = mActivityWeakRefHolder.get(); if (activity == null) return false; try {
diff --git a/ui/android/java/src/org/chromium/ui/base/ActivityKeyboardVisibilityDelegate.java b/ui/android/java/src/org/chromium/ui/base/ActivityKeyboardVisibilityDelegate.java index 7c4550d8..3981e51 100644 --- a/ui/android/java/src/org/chromium/ui/base/ActivityKeyboardVisibilityDelegate.java +++ b/ui/android/java/src/org/chromium/ui/base/ActivityKeyboardVisibilityDelegate.java
@@ -4,14 +4,16 @@ package org.chromium.ui.base; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.app.Activity; import android.view.View; -import androidx.annotation.Nullable; - import org.chromium.base.Callback; import org.chromium.base.supplier.LazyOneshotSupplier; import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.KeyboardVisibilityDelegate; import java.lang.ref.WeakReference; @@ -22,14 +24,15 @@ * the layout or keyboard inset change is suspected to be related to a software keyboard changing * visibility. */ +@NullMarked public class ActivityKeyboardVisibilityDelegate extends KeyboardVisibilityDelegate implements View.OnLayoutChangeListener { private final Callback<Integer> mOnKeyboardInsetChanged = this::onKeyboardInsetChanged; private WeakReference<Activity> mActivity; - private LazyOneshotSupplier<ObservableSupplier<Integer>> mLazyKeyboardInsetSupplier; + private @Nullable LazyOneshotSupplier<ObservableSupplier<Integer>> mLazyKeyboardInsetSupplier; private boolean mIsKeyboardShowing; - private View mContentViewForTesting; + private @Nullable View mContentViewForTesting; /** * Creates a new delegate listening to the given activity. If the activity is destroyed, it will @@ -48,7 +51,7 @@ assert mLazyKeyboardInsetSupplier == null; mLazyKeyboardInsetSupplier = lazyKeyboardInsetSupplier; if (hasKeyboardVisibilityListeners()) { - mLazyKeyboardInsetSupplier.get().addObserver(mOnKeyboardInsetChanged); + assumeNonNull(lazyKeyboardInsetSupplier.get()).addObserver(mOnKeyboardInsetChanged); } } @@ -66,7 +69,7 @@ if (mLazyKeyboardInsetSupplier == null) return; - mLazyKeyboardInsetSupplier.get().addObserver(mOnKeyboardInsetChanged); + assumeNonNull(mLazyKeyboardInsetSupplier.get()).addObserver(mOnKeyboardInsetChanged); } @Override @@ -77,7 +80,7 @@ if (mLazyKeyboardInsetSupplier == null) return; - mLazyKeyboardInsetSupplier.get().removeObserver(mOnKeyboardInsetChanged); + assumeNonNull(mLazyKeyboardInsetSupplier.get()).removeObserver(mOnKeyboardInsetChanged); } @Override
diff --git a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java index 666a736..774d98e2 100644 --- a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
@@ -7,14 +7,13 @@ import android.app.Activity; import android.content.Context; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import org.chromium.base.ActivityState; import org.chromium.base.ApplicationStatus; import org.chromium.base.ContextUtils; import org.chromium.base.supplier.LazyOneshotSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.InsetObserver; import org.chromium.ui.permissions.ActivityAndroidPermissionDelegate; @@ -24,13 +23,14 @@ * The class provides the WindowAndroid's implementation which requires Activity Instance. Only * instantiate this class when you need the implemented features. */ +@NullMarked public class ActivityWindowAndroid extends WindowAndroid implements ApplicationStatus.ActivityStateListener, ApplicationStatus.WindowFocusChangedListener { private final boolean mListenToActivityState; // Just create one ImmutableWeakReference object to avoid gc churn. - private ImmutableWeakReference<Activity> mActivityWeakRefHolder; + private @Nullable ImmutableWeakReference<Activity> mActivityWeakRefHolder; /** * Creates an Activity-specific WindowAndroid with associated intent functionality. @@ -70,7 +70,7 @@ public ActivityWindowAndroid( Context context, boolean listenToActivityState, - @NonNull ActivityKeyboardVisibilityDelegate keyboardVisibilityDelegate, + ActivityKeyboardVisibilityDelegate keyboardVisibilityDelegate, IntentRequestTracker intentRequestTracker, InsetObserver insetObserver, boolean trackOcclusion) { @@ -100,7 +100,7 @@ ActivityAndroidPermissionDelegate activityAndroidPermissionDelegate, ActivityKeyboardVisibilityDelegate activityKeyboardVisibilityDelegate, IntentRequestTracker intentRequestTracker, - InsetObserver insetObserver, + @Nullable InsetObserver insetObserver, boolean trackOcclusion) { super(context, intentRequestTracker, insetObserver, trackOcclusion); Activity activity = ContextUtils.activityFromContext(context); @@ -116,7 +116,7 @@ activityKeyboardVisibilityDelegate.setLazyKeyboardInsetSupplier( LazyOneshotSupplier.fromSupplier( () -> { - if (getInsetObserver() == null) { + if (insetObserver == null) { // An InsetObserver can no longer be created. Stub this out so // calls continue to succeed. return new ObservableSupplierImpl<Integer>();
diff --git a/ui/android/java/src/org/chromium/ui/base/ApplicationViewportInsetSupplier.java b/ui/android/java/src/org/chromium/ui/base/ApplicationViewportInsetSupplier.java index e19a08d..388bf37 100644 --- a/ui/android/java/src/org/chromium/ui/base/ApplicationViewportInsetSupplier.java +++ b/ui/android/java/src/org/chromium/ui/base/ApplicationViewportInsetSupplier.java
@@ -8,6 +8,8 @@ import org.chromium.base.lifetime.Destroyable; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.mojom.VirtualKeyboardMode; /** @@ -41,14 +43,15 @@ * ObservableSupplier<ViewportInsets>} object. * </pre> */ +@NullMarked public class ApplicationViewportInsetSupplier extends ObservableSupplierImpl<ViewportInsets> implements Destroyable { /** Keyboard related suppliers */ - private ObservableSupplier<Integer> mKeyboardInsetSupplier; + private @Nullable ObservableSupplier<Integer> mKeyboardInsetSupplier; - private ObservableSupplier<Integer> mKeyboardAccessoryInsetSupplier; + private @Nullable ObservableSupplier<Integer> mKeyboardAccessoryInsetSupplier; - private ObservableSupplier<Integer> mBottomSheetInsetSupplier; + private @Nullable ObservableSupplier<Integer> mBottomSheetInsetSupplier; /** The observer that gets attached to all inset suppliers. */ private final Callback<Integer> mInsetSupplierObserver = (unused) -> computeInsets(); @@ -106,7 +109,7 @@ * * Pass null to unset the current supplier. */ - public void setKeyboardInsetSupplier(ObservableSupplier<Integer> insetSupplier) { + public void setKeyboardInsetSupplier(@Nullable ObservableSupplier<Integer> insetSupplier) { boolean didRemove = false; if (mKeyboardInsetSupplier != null) { @@ -130,7 +133,8 @@ * * Pass null to unset the current supplier. */ - public void setKeyboardAccessoryInsetSupplier(ObservableSupplier<Integer> insetSupplier) { + public void setKeyboardAccessoryInsetSupplier( + @Nullable ObservableSupplier<Integer> insetSupplier) { boolean didRemove = false; if (mKeyboardAccessoryInsetSupplier != null) { mKeyboardAccessoryInsetSupplier.removeObserver(mInsetSupplierObserver); @@ -203,7 +207,7 @@ super.set(newValues); } - private int intFromSupplier(ObservableSupplier<Integer> supplier) { + private int intFromSupplier(@Nullable ObservableSupplier<Integer> supplier) { if (supplier == null || supplier.get() == null) return 0; return supplier.get(); }
diff --git a/ui/android/java/src/org/chromium/ui/base/BytesFormatting.java b/ui/android/java/src/org/chromium/ui/base/BytesFormatting.java index 83a7f71..7b13df4c 100644 --- a/ui/android/java/src/org/chromium/ui/base/BytesFormatting.java +++ b/ui/android/java/src/org/chromium/ui/base/BytesFormatting.java
@@ -7,8 +7,11 @@ import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import org.chromium.build.annotations.NullMarked; + /** Java mirror of ui/base/text/bytes_formatting.h. */ @JNINamespace("ui") +@NullMarked public class BytesFormatting { /**
diff --git a/ui/android/java/src/org/chromium/ui/base/Clipboard.java b/ui/android/java/src/org/chromium/ui/base/Clipboard.java index 44c03fe..6d2ff02 100644 --- a/ui/android/java/src/org/chromium/ui/base/Clipboard.java +++ b/ui/android/java/src/org/chromium/ui/base/Clipboard.java
@@ -10,8 +10,6 @@ import android.content.Context; import android.net.Uri; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import org.jni_zero.CalledByNative; @@ -21,15 +19,18 @@ import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.url.GURL; /** Simple proxy that provides C++ code with an access pathway to the Android clipboard. */ @JNINamespace("ui") +@NullMarked public class Clipboard { private static final String TAG = "Clipboard"; @SuppressLint("StaticFieldLeak") - private static Clipboard sInstance; + private static @Nullable Clipboard sInstance; private long mNativeClipboard; @@ -63,7 +64,7 @@ * On Android O and O_MR1, URI is stored for revoking permissions later. * @param clipboardFileMetadata The metadata needs to be stored. */ - void storeLastCopiedImageMetadata(@NonNull ClipboardFileMetadata clipboardFileMetadata); + void storeLastCopiedImageMetadata(ClipboardFileMetadata clipboardFileMetadata); /** Get stored the last image uri and its timestamp. */ @Nullable @@ -129,7 +130,7 @@ */ @SuppressWarnings("javadoc") @CalledByNative - protected String getCoercedText() { + protected @Nullable String getCoercedText() { return null; } @@ -139,7 +140,7 @@ return false; } - public String clipDataToHtmlText(ClipData clipData) { + public @Nullable String clipDataToHtmlText(ClipData clipData) { return null; } @@ -150,7 +151,7 @@ * text or no entries on the primary clip. */ @CalledByNative - protected String getHTMLText() { + protected @Nullable String getHTMLText() { return null; } @@ -179,6 +180,7 @@ */ @CalledByNative @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + @Nullable String getUrl() { return null; } @@ -200,7 +202,7 @@ } @CalledByNative - protected String getImageUriString() { + protected @Nullable String getImageUriString() { return null; } @@ -212,7 +214,7 @@ * @return a byte array of PNG data if available, otherwise null. */ @CalledByNative - public byte[] getPng() { + public byte @Nullable [] getPng() { return null; } @@ -229,7 +231,7 @@ * optional display name which will be an empty string when unknown. */ @CalledByNative - protected String[][] getFilenames() { + protected String @Nullable [][] getFilenames() { return null; }
diff --git a/ui/android/java/src/org/chromium/ui/base/ClipboardImpl.java b/ui/android/java/src/org/chromium/ui/base/ClipboardImpl.java index 99355e9..7b8acf27 100644 --- a/ui/android/java/src/org/chromium/ui/base/ClipboardImpl.java +++ b/ui/android/java/src/org/chromium/ui/base/ClipboardImpl.java
@@ -25,8 +25,6 @@ import android.view.textclassifier.TextClassifier; import android.view.textclassifier.TextLinks; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.VisibleForTesting; @@ -41,6 +39,9 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.task.AsyncTask; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.components.url_formatter.UrlFormatter; import org.chromium.ui.R; import org.chromium.ui.widget.Toast; @@ -55,6 +56,7 @@ /** Simple proxy that provides C++ code with an access pathway to the Android clipboard. */ @JNINamespace("ui") +@NullMarked public class ClipboardImpl extends Clipboard implements ClipboardManager.OnPrimaryClipChangedListener { private static final float CONFIDENCE_THRESHOLD_FOR_URL_DETECTION = 0.99f; @@ -81,9 +83,9 @@ private ClipboardManager mClipboardManager; - private ImageFileProvider mImageFileProvider; + private @Nullable ImageFileProvider mImageFileProvider; - private ImageFileProvider.ClipboardFileMetadata mPendingCopiedImageMetadata; + private ImageFileProvider.@Nullable ClipboardFileMetadata mPendingCopiedImageMetadata; public ClipboardImpl(ClipboardManager clipboardManager) { mContext = ContextUtils.getApplicationContext(); @@ -91,8 +93,9 @@ mClipboardManager.addPrimaryClipChangedListener(this); } + @NullUnmarked @Override - protected String getCoercedText() { + protected @Nullable String getCoercedText() { // getPrimaryClip() has been observed to throw unexpected exceptions for some devices (see // crbug.com/654802 and b/31501780) try { @@ -135,8 +138,9 @@ return false; } + @NullUnmarked @Override - public String clipDataToHtmlText(ClipData clipData) { + public @Nullable String clipDataToHtmlText(@Nullable ClipData clipData) { ClipDescription description = clipData.getDescription(); if (description.hasMimeType(ClipDescription.MIMETYPE_TEXT_HTML)) { return clipData.getItemAt(0).getHtmlText(); @@ -154,7 +158,7 @@ } @Override - protected String getHTMLText() { + protected @Nullable String getHTMLText() { // getPrimaryClip() has been observed to throw unexpected exceptions for some devices (see // crbug/654802 and b/31501780) try { @@ -175,6 +179,7 @@ || description.hasMimeType(ClipDescription.MIMETYPE_TEXT_HTML); } + @NullUnmarked @Override boolean hasUrl() { // ClipDescription#getConfidenceScore is only available on Android S+, so before Android S, @@ -201,7 +206,9 @@ } } + @NullUnmarked @Override + @Nullable String getUrl() { if (!hasUrl()) return null; @@ -276,13 +283,14 @@ } @Override - protected String getImageUriString() { + protected @Nullable String getImageUriString() { Uri uri = getImageUri(); return uri == null ? null : uri.toString(); } + @NullUnmarked @Override - public byte[] getPng() { + public byte @Nullable [] getPng() { ThreadUtils.assertOnBackgroundThread(); Uri uri = getImageUri(); @@ -335,7 +343,7 @@ return hasImageMimeType(description); } - private static boolean hasImageMimeType(ClipDescription description) { + private static boolean hasImageMimeType(@Nullable ClipDescription description) { return (description != null) && (description.hasMimeType("image/*") || (sSkipImageMimeTypeCheckForTesting != null @@ -352,6 +360,7 @@ return description.getTimestamp(); } + @NullUnmarked @Override protected String[][] getFilenames() { // getPrimaryClip() has been observed to throw unexpected exceptions for some devices (see @@ -376,6 +385,7 @@ return uris.toArray(new String[][] {}); } + @NullUnmarked @Override public boolean hasFilenames() { // getPrimaryClip() has been observed to throw unexpected exceptions for some devices (see @@ -449,7 +459,7 @@ } @Override - protected void onPostExecute(ClipData clipData) { + protected void onPostExecute(@Nullable ClipData clipData) { if (setPrimaryClipNoException(clipData) && notifyOnSuccess) { showToastIfNeeded(R.string.image_copied); } @@ -535,8 +545,9 @@ } } + @NullUnmarked @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - boolean setPrimaryClipNoException(ClipData clip) { + boolean setPrimaryClipNoException(@Nullable ClipData clip) { final String manufacturer = Build.MANUFACTURER.toLowerCase(Locale.US); // See crbug.com/1123727, there are OEM devices having strict mode violations in their // Android framework code. Disabling strict mode for non-google devices. @@ -618,7 +629,7 @@ * individually. Note: Don't forget to revoke the permission once the clipboard is updated. */ @SuppressWarnings("QueryPermissionsNeeded") - private void grantUriPermission(@NonNull Uri uri) { + private void grantUriPermission(Uri uri) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P || mImageFileProvider == null) { return; } @@ -704,6 +715,7 @@ } } + @NullUnmarked private boolean hasStyledTextOnPreS() { CharSequence text; try {
diff --git a/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java b/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java index 26aca0b3..be25bf5f 100644 --- a/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java +++ b/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java
@@ -11,16 +11,27 @@ import org.jni_zero.CalledByNative; +import org.chromium.build.BuildConfig; import org.chromium.base.ContextUtils; import org.chromium.base.ResettersForTesting; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; import org.chromium.ui.display.DisplayAndroid; import org.chromium.ui.display.DisplayUtil; /** UI utilities for accessing form factor information. */ +@NullMarked public class DeviceFormFactor { /** + * Desktop form factor. + * + * <p>Identified by <code>isDesktop() == true</code>. + */ + public static final String DESKTOP = "Desktop"; + + /** * Phone form factor. * * <p>Identified by <code>isNonMultiDisplayContextOnTablet() == false</code>. @@ -47,7 +58,16 @@ private static final int SCREEN_BUCKET_LARGET_TABLET = 3; /** See {@link #setIsTabletForTesting(boolean)}. */ - private static Boolean sIsTabletForTesting; + private static @Nullable Boolean sIsTabletForTesting; + + /** + * Only devices built with IS_DESKTOP_ANDROID will return true. + * + * @return Whether the device is a Desktop. + */ + public static boolean isDesktop() { + return BuildConfig.IS_DESKTOP_ANDROID; + } /** * Each activity could be on a different display, and this will just tell you whether the
diff --git a/ui/android/java/src/org/chromium/ui/base/DeviceInput.java b/ui/android/java/src/org/chromium/ui/base/DeviceInput.java index 867272c2..a96c8ca8 100644 --- a/ui/android/java/src/org/chromium/ui/base/DeviceInput.java +++ b/ui/android/java/src/org/chromium/ui/base/DeviceInput.java
@@ -18,12 +18,15 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ResettersForTesting; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * Utilities for accessing device input information. Note that this class is not thread-safe and * currently asserts all interactions occur on the UI thread. If usage is required off the UI thread * in the future, this class can be modified for multi-thread support. */ +@NullMarked public class DeviceInput implements InputDeviceListener { /** Wrapper class which provides lazy initialization of a singleton instance. */ @@ -32,10 +35,10 @@ } /** See {@link #setSupportsAlphabeticKeyboardForTesting(boolean)}. */ - private static Boolean sSupportsAlphabeticKeyboardForTesting; + private static @Nullable Boolean sSupportsAlphabeticKeyboardForTesting; /** See {@link #setSupportsPrevisionPointerForTesting(boolean)}. */ - private static Boolean sSupportsPrecisionPointerForTesting; + private static @Nullable Boolean sSupportsPrecisionPointerForTesting; /** Cached snapshots of all currently connected {@link InputDevice}s. */ private final SparseArray<DeviceSnapshot> mDeviceSnapshotsById = new SparseArray<>();
diff --git a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java index 4cbc05cf..d878949 100644 --- a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java +++ b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
@@ -25,6 +25,9 @@ import org.chromium.base.Log; import org.chromium.base.TraceEvent; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.MotionEventUtils; import java.lang.reflect.UndeclaredThrowableException; @@ -33,6 +36,7 @@ /** Class used to forward view, input events down to native. */ @JNINamespace("ui") +@NullMarked public class EventForwarder { private static final String TAG = "EventForwarder"; private final boolean mIsDragDropEnabled; @@ -65,7 +69,7 @@ private float mLastTrackpadScrollStartRawY; // Delegate to call WebContents functionality. - private StylusWritingDelegate mStylusWritingDelegate; + private @Nullable StylusWritingDelegate mStylusWritingDelegate; /** Interface to provide stylus writing functionality. */ public interface StylusWritingDelegate { @@ -592,6 +596,7 @@ * @param event {@link DragEvent} instance. * @param containerView A view on which the drag event is taking place. */ + @NullUnmarked public boolean onDragEvent(DragEvent event, View containerView) { ClipDescription clipDescription = event.getClipDescription(); // Do not forward chrome/tab events to native eventForwarder. @@ -904,9 +909,9 @@ String[] mimeTypes, String content, String[][] filenames, - String text, - String html, - String url); + @Nullable String text, + @Nullable String html, + @Nullable String url); boolean onGestureEvent( long nativeEventForwarder,
diff --git a/ui/android/java/src/org/chromium/ui/base/EventOffsetHandler.java b/ui/android/java/src/org/chromium/ui/base/EventOffsetHandler.java index c541b01d..26cdc363 100644 --- a/ui/android/java/src/org/chromium/ui/base/EventOffsetHandler.java +++ b/ui/android/java/src/org/chromium/ui/base/EventOffsetHandler.java
@@ -9,10 +9,13 @@ import android.view.View; import android.view.ViewGroup; +import org.chromium.build.annotations.NullMarked; + /** * A class to update motion event offset while dragging. This is needed to compensate the change * caused by top control. */ +@NullMarked public class EventOffsetHandler { /** A delegate for EventOffsetHandler. */ public interface EventOffsetHandlerDelegate {
diff --git a/ui/android/java/src/org/chromium/ui/base/IdleDetector.java b/ui/android/java/src/org/chromium/ui/base/IdleDetector.java index 141ae6a..2a05e77 100644 --- a/ui/android/java/src/org/chromium/ui/base/IdleDetector.java +++ b/ui/android/java/src/org/chromium/ui/base/IdleDetector.java
@@ -16,6 +16,7 @@ import org.jni_zero.JNINamespace; import org.chromium.base.ContextUtils; +import org.chromium.build.annotations.NullMarked; import java.util.concurrent.TimeUnit; @@ -24,6 +25,7 @@ * idle detection. */ @JNINamespace("ui") +@NullMarked public class IdleDetector extends BroadcastReceiver { private static final String TAG = "IdleDetector"; // Memory handled by idle_android:cc: a singleton (```detector```) gets @@ -54,9 +56,9 @@ @Override public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { + if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { start(); - } else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) { + } else if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) { reset(); } }
diff --git a/ui/android/java/src/org/chromium/ui/base/ImmutableWeakReference.java b/ui/android/java/src/org/chromium/ui/base/ImmutableWeakReference.java index acf0248a..a71ebed 100644 --- a/ui/android/java/src/org/chromium/ui/base/ImmutableWeakReference.java +++ b/ui/android/java/src/org/chromium/ui/base/ImmutableWeakReference.java
@@ -4,6 +4,9 @@ package org.chromium.ui.base; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + import java.lang.ref.WeakReference; /** @@ -11,8 +14,9 @@ * This is so that it's safe to pass the same instance to multiple * clients without worrying about modification. */ +@NullMarked public class ImmutableWeakReference<T> extends WeakReference<T> { - public ImmutableWeakReference(T referent) { + public ImmutableWeakReference(@Nullable T referent) { super(referent); }
diff --git a/ui/android/java/src/org/chromium/ui/base/IntentRequestTracker.java b/ui/android/java/src/org/chromium/ui/base/IntentRequestTracker.java index 11bb66e..8f7af3a 100644 --- a/ui/android/java/src/org/chromium/ui/base/IntentRequestTracker.java +++ b/ui/android/java/src/org/chromium/ui/base/IntentRequestTracker.java
@@ -9,6 +9,8 @@ import android.content.IntentSender; import android.os.Bundle; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.base.WindowAndroid.IntentCallback; import java.lang.ref.WeakReference; @@ -17,6 +19,7 @@ * The interface for a helper class that keeps track of the intent requests for an Activity. Its * implementation should be hidden in ui/base. No implementation should be made outside of ui/base. */ +@NullMarked public interface IntentRequestTracker { /** A delegate of this class's intent sending. */ interface Delegate { @@ -24,7 +27,7 @@ * Starts an activity for the provided intent. * @see Activity#startActivityForResult */ - boolean startActivityForResult(Intent intent, int requestCode); + boolean startActivityForResult(@Nullable Intent intent, int requestCode); /** * Uses the provided intent sender to start the intent.
diff --git a/ui/android/java/src/org/chromium/ui/base/IntentRequestTrackerImpl.java b/ui/android/java/src/org/chromium/ui/base/IntentRequestTrackerImpl.java index a75d790..c98d358d 100644 --- a/ui/android/java/src/org/chromium/ui/base/IntentRequestTrackerImpl.java +++ b/ui/android/java/src/org/chromium/ui/base/IntentRequestTrackerImpl.java
@@ -14,12 +14,15 @@ import org.chromium.base.Callback; import org.chromium.base.ContextUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.base.WindowAndroid.IntentCallback; import java.lang.ref.WeakReference; import java.util.HashMap; /** The implementation of IntentRequestTracker. */ +@NullMarked /* package */ final class IntentRequestTrackerImpl implements IntentRequestTracker { // Constants used for intent request code bounding. private static final int REQUEST_CODE_PREFIX = 1000; @@ -57,7 +60,8 @@ } @Override - public int showCancelableIntent(Intent intent, IntentCallback callback, Integer errorId) { + public int showCancelableIntent( + @Nullable Intent intent, IntentCallback callback, Integer errorId) { int requestCode = generateNextRequestCode(); if (!mDelegate.startActivityForResult(intent, requestCode)) {
diff --git a/ui/android/java/src/org/chromium/ui/base/LocalizationUtils.java b/ui/android/java/src/org/chromium/ui/base/LocalizationUtils.java index 6d73487..6af576a 100644 --- a/ui/android/java/src/org/chromium/ui/base/LocalizationUtils.java +++ b/ui/android/java/src/org/chromium/ui/base/LocalizationUtils.java
@@ -14,11 +14,14 @@ import org.chromium.base.ContextUtils; import org.chromium.base.LocaleUtils; import org.chromium.base.ResettersForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.Locale; /** This class provides the locale related methods for the native library. */ @JNINamespace("l10n_util") +@NullMarked public class LocalizationUtils { // This is mirrored from base/i18n/rtl.h. Please keep in sync. @@ -26,7 +29,7 @@ public static final int RIGHT_TO_LEFT = 1; public static final int LEFT_TO_RIGHT = 2; - private static Boolean sIsLayoutRtlForTesting; + private static @Nullable Boolean sIsLayoutRtlForTesting; private LocalizationUtils() { /* cannot be instantiated */
diff --git a/ui/android/java/src/org/chromium/ui/base/MimeTypeUtils.java b/ui/android/java/src/org/chromium/ui/base/MimeTypeUtils.java index 9b8d1f99..c775d38 100644 --- a/ui/android/java/src/org/chromium/ui/base/MimeTypeUtils.java +++ b/ui/android/java/src/org/chromium/ui/base/MimeTypeUtils.java
@@ -8,15 +8,17 @@ import android.webkit.MimeTypeMap; import androidx.annotation.IntDef; -import androidx.annotation.Nullable; import org.chromium.base.BuildInfo; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.url.GURL; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** Utility methods for determining and working with mime types. */ +@NullMarked public class MimeTypeUtils { /** The MIME type for a plain text objects dragged from Chrome. */ public static final String CHROME_MIMETYPE_TEXT = "chrome/text";
diff --git a/ui/android/java/src/org/chromium/ui/base/OverlayTransformApiHelper.java b/ui/android/java/src/org/chromium/ui/base/OverlayTransformApiHelper.java index 2a737152..576aba2 100644 --- a/ui/android/java/src/org/chromium/ui/base/OverlayTransformApiHelper.java +++ b/ui/android/java/src/org/chromium/ui/base/OverlayTransformApiHelper.java
@@ -15,12 +15,16 @@ import androidx.annotation.RequiresApi; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.gfx.OverlayTransform; import java.lang.ref.WeakReference; /** Helper class to avoid fail of ART's class verification for S_V2 APIs in old device. */ @RequiresApi(Build.VERSION_CODES.S_V2) +@NullMarked final class OverlayTransformApiHelper implements AttachedSurfaceControl.OnBufferTransformHintChangedListener, Window.OnFrameMetricsAvailableListener { @@ -31,7 +35,7 @@ private boolean mBufferTransformListenerAdded; private boolean mFrameMetricsListenerAdded; - static OverlayTransformApiHelper create(WindowAndroid windowAndroid) { + static @Nullable OverlayTransformApiHelper create(WindowAndroid windowAndroid) { if (windowAndroid.getWindow() == null) return null; return new OverlayTransformApiHelper(windowAndroid); } @@ -98,6 +102,7 @@ } } + @NullUnmarked private void addOnFrameMetricsAvailableListener() { if (mFrameMetricsListenerAdded) return; Window window = mWindow.get();
diff --git a/ui/android/java/src/org/chromium/ui/base/PhotoPicker.java b/ui/android/java/src/org/chromium/ui/base/PhotoPicker.java index a783aac3..cced40b 100644 --- a/ui/android/java/src/org/chromium/ui/base/PhotoPicker.java +++ b/ui/android/java/src/org/chromium/ui/base/PhotoPicker.java
@@ -4,10 +4,13 @@ package org.chromium.ui.base; +import org.chromium.build.annotations.NullMarked; + /** * An interface for the custom image file picker. * See {@link SelectFileDialog}. */ +@NullMarked public interface PhotoPicker { /** * Called after use of the PhotoPicker results in an external intent.
diff --git a/ui/android/java/src/org/chromium/ui/base/PhotoPickerDelegate.java b/ui/android/java/src/org/chromium/ui/base/PhotoPickerDelegate.java index 4a9f4ee..2b8a07e 100644 --- a/ui/android/java/src/org/chromium/ui/base/PhotoPickerDelegate.java +++ b/ui/android/java/src/org/chromium/ui/base/PhotoPickerDelegate.java
@@ -4,9 +4,12 @@ package org.chromium.ui.base; +import org.chromium.build.annotations.NullMarked; + import java.util.List; /** A delegate interface for the photo picker. */ +@NullMarked public interface PhotoPickerDelegate { /** * Called to display the photo picker.
diff --git a/ui/android/java/src/org/chromium/ui/base/PhotoPickerListener.java b/ui/android/java/src/org/chromium/ui/base/PhotoPickerListener.java index 1e74655..975c3e46 100644 --- a/ui/android/java/src/org/chromium/ui/base/PhotoPickerListener.java +++ b/ui/android/java/src/org/chromium/ui/base/PhotoPickerListener.java
@@ -8,10 +8,13 @@ import androidx.annotation.IntDef; +import org.chromium.build.annotations.NullMarked; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** The callback used to indicate what action the user took in the picker. */ +@NullMarked public interface PhotoPickerListener { /** The action the user took in the picker. */ @IntDef({
diff --git a/ui/android/java/src/org/chromium/ui/base/ResourceBundle.java b/ui/android/java/src/org/chromium/ui/base/ResourceBundle.java index 4ac586d1e..0d865da 100644 --- a/ui/android/java/src/org/chromium/ui/base/ResourceBundle.java +++ b/ui/android/java/src/org/chromium/ui/base/ResourceBundle.java
@@ -10,6 +10,8 @@ import org.chromium.base.ApkAssets; import org.chromium.base.LocaleUtils; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.Arrays; @@ -22,9 +24,10 @@ * {@link ResourceBundle#setNoAvailableLocalePaks()} before calling the getters in this class. */ @JNINamespace("ui") +@NullMarked public final class ResourceBundle { private static final String TAG = "ResourceBundle"; - private static String[] sAvailableLocales; + private static String @Nullable [] sAvailableLocales; private ResourceBundle() {} @@ -69,7 +72,7 @@ * @return Asset path to .pak file, or null if the locale is not supported. */ @CalledByNative - private static String getLocalePakResourcePath( + private static @Nullable String getLocalePakResourcePath( String locale, boolean inBundle, boolean logError) { if (sAvailableLocales == null) { // Locales may be null in unit tests.
diff --git a/ui/android/java/src/org/chromium/ui/base/SPenSupport.java b/ui/android/java/src/org/chromium/ui/base/SPenSupport.java index a3a9133..a80433d 100644 --- a/ui/android/java/src/org/chromium/ui/base/SPenSupport.java +++ b/ui/android/java/src/org/chromium/ui/base/SPenSupport.java
@@ -10,26 +10,29 @@ import android.view.MotionEvent; import org.chromium.base.ContextUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** Support S-Pen event detection and conversion. */ +@NullMarked public final class SPenSupport { // These values are obtained from Samsung. private static final int SPEN_ACTION_DOWN = 211; private static final int SPEN_ACTION_UP = 212; private static final int SPEN_ACTION_MOVE = 213; private static final int SPEN_ACTION_CANCEL = 214; - private static Boolean sIsSPenSupported; + private static @Nullable Boolean sIsSPenSupported; /** * Initialize SPen support. This is done lazily at the first invocation of * {@link #convertSPenEventAction(int)}. */ - private static void initialize() { - if (sIsSPenSupported != null) return; + private static boolean isSPenSupported() { + if (sIsSPenSupported != null) return sIsSPenSupported; if (!"SAMSUNG".equalsIgnoreCase(Build.MANUFACTURER)) { sIsSPenSupported = false; - return; + return false; } Context context = ContextUtils.getApplicationContext(); @@ -37,10 +40,11 @@ for (FeatureInfo info : infos) { if ("com.sec.feature.spen_usp".equalsIgnoreCase(info.name)) { sIsSPenSupported = true; - return; + return true; } } sIsSPenSupported = false; + return false; } /** @@ -51,8 +55,9 @@ * @return Event action after the conversion. */ public static int convertSPenEventAction(int eventActionMasked) { - if (sIsSPenSupported == null) initialize(); - if (!sIsSPenSupported.booleanValue()) return eventActionMasked; + if (!isSPenSupported()) { + return eventActionMasked; + } // S-Pen support: convert to normal stylus event handling switch (eventActionMasked) {
diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java index e21b78a..4b2b7738 100644 --- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java
@@ -24,7 +24,6 @@ import android.webkit.MimeTypeMap; import androidx.annotation.IntDef; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.core.content.ContextCompat; @@ -46,6 +45,9 @@ import org.chromium.base.task.AsyncTask; import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; import org.chromium.ui.UiUtils; @@ -65,6 +67,7 @@ * a set of accepted file types. The path of the selected file is passed to the native dialog. */ @JNINamespace("ui") +@NullMarked public class SelectFileDialog implements WindowAndroid.IntentCallback, PhotoPickerListener { private static final String TAG = "SelectFileDialog"; private static final String IMAGE_TYPE = "image"; @@ -249,17 +252,24 @@ /** If set, overrides the WindowAndroid passed in {@link selectFile()}. */ @SuppressLint("StaticFieldLeak") - private static WindowAndroid sWindowAndroidForTesting; + private static @Nullable WindowAndroid sWindowAndroidForTesting; private long mNativeSelectFileDialog; - private String mIntentAction; + private @Nullable String mIntentAction; + // File types may contain both file extensions and MIME types. + @SuppressWarnings("NullAway.Init") private List<String> mFileTypes; + // Converted from `mFileTypes`, only contains deduped MIME types. + @SuppressWarnings("NullAway.Init") private List<String> mMimeTypes; + private boolean mCapture; private boolean mAllowMultiple; - private Uri mCameraOutputUri; + private @Nullable Uri mCameraOutputUri; + + @SuppressWarnings("NullAway.Init") private WindowAndroid mWindowAndroid; /** Whether an Activity is available on the system to support capturing images (i.e. Camera). */ @@ -282,10 +292,10 @@ private boolean mMediaPickerWasUsed; /** A delegate for the photo picker. */ - private static PhotoPickerDelegate sPhotoPickerDelegate; + private static @Nullable PhotoPickerDelegate sPhotoPickerDelegate; /** The active photo picker, or null if none is active. */ - private static PhotoPicker sPhotoPicker; + private static @Nullable PhotoPicker sPhotoPicker; /** * Allows setting a delegate to override the default Android stock photo picker. @@ -510,8 +520,7 @@ * Returns a Video capture Intent. Can return null if video capture is not supported or the * camera permission has not been granted. */ - @Nullable - private Intent getVideoCaptureIntent() { + private @Nullable Intent getVideoCaptureIntent() { boolean hasCameraPermission = mWindowAndroid.hasPermission(Manifest.permission.CAMERA); if (mSupportsVideoCapture && hasCameraPermission) { return new Intent(MediaStore.ACTION_VIDEO_CAPTURE); @@ -523,8 +532,7 @@ * Returns a SoundRecorder Intent. Can return null if sound capture is not supported or the * sound permission has not been granted. */ - @Nullable - private Intent getSoundRecorderIntent() { + private @Nullable Intent getSoundRecorderIntent() { boolean hasAudioPermission = mWindowAndroid.hasPermission(Manifest.permission.RECORD_AUDIO); if (mSupportsAudioCapture && hasAudioPermission) { return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); @@ -538,7 +546,7 @@ * is allowed to choose files from the camera. * @param camera Intent for selecting files from camera. */ - private void launchSelectFileWithCameraIntent(Intent camera) { + private void launchSelectFileWithCameraIntent(@Nullable Intent camera) { RecordHistogram.recordEnumeratedHistogram( "Android.SelectFileDialogScope", determineSelectFileDialogScope(), @@ -585,7 +593,8 @@ * @param camcorder A camcorder intent to supply as extra Intent data. * @param soundRecorder A soundRecorder intent to supply as extra Intent data. */ - private void showExternalPicker(Intent camera, Intent camcorder, Intent soundRecorder) { + private void showExternalPicker( + @Nullable Intent camera, @Nullable Intent camcorder, @Nullable Intent soundRecorder) { if (UiAndroidFeatureMap.isEnabled(UiAndroidFeatures.DEPRECATED_EXTERNAL_PICKER_FUNCTION)) { showExternalPickerDeprecated(camera, camcorder, soundRecorder); return; @@ -645,7 +654,7 @@ * @param soundRecorder A soundRecorder intent to supply as extra Intent data. */ private void showExternalPickerDeprecated( - Intent camera, Intent camcorder, Intent soundRecorder) { + @Nullable Intent camera, @Nullable Intent camcorder, @Nullable Intent soundRecorder) { Intent getContentIntent = new Intent(mIntentAction); if (mAllowMultiple) { @@ -861,8 +870,9 @@ mCallback = callback; } + @NullUnmarked @Override - public Uri doInBackground() { + public @Nullable Uri doInBackground() { try { Context context = ContextUtils.getApplicationContext(); return FileProviderUtils.getContentUriFromFile(getFileForImageCapture(context)); @@ -873,7 +883,7 @@ } @Override - protected void onPostExecute(Uri result) { + protected void onPostExecute(@Nullable Uri result) { mCameraOutputUri = result; if (mCameraOutputUri == null) { if (captureImage() || mDirectToCamera) { @@ -920,6 +930,7 @@ // TODO(crbug.com/41484704): Merge the Chrome and WebView implementations // of isPathUnderAppDir into one. + @NullUnmarked private static boolean isPathUnderAppDir(String path, Context context) { File file = new File(path); File dataDir = ContextCompat.getDataDir(context); @@ -932,6 +943,7 @@ } } + @NullUnmarked public static boolean isContentUriUnderAppDir(Uri uri, Context context) { assert !ThreadUtils.runningOnUiThread(); try { @@ -955,6 +967,7 @@ * @param resultCode The result code whether the intent returned successfully. * @param results The results of the requested intent. */ + @NullUnmarked @Override public void onIntentCompleted(int resultCode, Intent results) { if (sPhotoPicker != null) { @@ -1241,8 +1254,9 @@ && !FileUtils.getAbsoluteFilePath(mFilePath).isEmpty(); } + @NullUnmarked @Override - protected void onPostExecute(Boolean result) { + protected void onPostExecute(@Nullable Boolean result) { if (result) { onFileSelected(mNativeSelectFileDialog, mFilePath, ""); WindowAndroid.showError(R.string.opening_file_error); @@ -1253,7 +1267,9 @@ } class GetDisplayNameTask extends AsyncTask<String[]> { + @SuppressWarnings("NullAway.Init") String[] mFilePaths; + final Context mContext; final boolean mIsMultiple; final Uri[] mUris; @@ -1264,9 +1280,10 @@ mUris = uris; } + @NullUnmarked @Override @SuppressLint("NewApi") - public String[] doInBackground() { + public String @Nullable [] doInBackground() { mFilePaths = new String[mUris.length]; String[] displayNames = new String[mUris.length]; try { @@ -1306,7 +1323,7 @@ } @Override - protected void onPostExecute(String[] result) { + protected void onPostExecute(String @Nullable [] result) { if (result == null) { onFileNotSelected(); return; @@ -1350,7 +1367,7 @@ } @Override - protected void onPostExecute(Boolean result) {} + protected void onPostExecute(@Nullable Boolean result) {} } protected RecordUploadMetricsTask getUploadMetricTaskForTesting( @@ -1384,7 +1401,9 @@ } protected void onFileSelected( - long nativeSelectFileDialogImpl, String filePath, String displayName) { + long nativeSelectFileDialogImpl, + @Nullable String filePath, + @Nullable String displayName) { recordImageCountHistograms(new String[] {filePath}); if (nativeSelectFileDialogImpl != 0) { SelectFileDialogJni.get() @@ -1463,6 +1482,7 @@ } } + @NullUnmarked private int getMediaType( Uri mediaUri, boolean mediaPickerWasUsed, ContentResolver contentResolver) { if (mediaUri == null) { @@ -1809,8 +1829,8 @@ void onFileSelected( long nativeSelectFileDialogImpl, SelectFileDialog caller, - String filePath, - String displayName); + @Nullable String filePath, + @Nullable String displayName); void onMultipleFilesSelected( long nativeSelectFileDialogImpl,
diff --git a/ui/android/java/src/org/chromium/ui/base/TouchDevice.java b/ui/android/java/src/org/chromium/ui/base/TouchDevice.java index 871ae50..b6eab86 100644 --- a/ui/android/java/src/org/chromium/ui/base/TouchDevice.java +++ b/ui/android/java/src/org/chromium/ui/base/TouchDevice.java
@@ -11,9 +11,11 @@ import org.jni_zero.JNINamespace; import org.chromium.base.ContextUtils; +import org.chromium.build.annotations.NullMarked; /** Simple proxy for querying input device properties from C++. */ @JNINamespace("ui") +@NullMarked public class TouchDevice { /** Static methods only so make constructor private. */
diff --git a/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureList.java b/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureList.java index 660c03cd..d116e0c9 100644 --- a/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureList.java +++ b/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureList.java
@@ -5,8 +5,10 @@ package org.chromium.ui.base; import org.chromium.base.MutableFlagWithSafeDefault; +import org.chromium.build.annotations.NullMarked; /** Helpers and state for features from {@link UiAndroidFeatures}. */ +@NullMarked public class UiAndroidFeatureList { private static MutableFlagWithSafeDefault newMutableFlagWithSafeDefault( String featureName, boolean defaultValue) {
diff --git a/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureMap.java b/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureMap.java index e40192a..0826bbc 100644 --- a/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureMap.java +++ b/ui/android/java/src/org/chromium/ui/base/UiAndroidFeatureMap.java
@@ -8,9 +8,11 @@ import org.jni_zero.NativeMethods; import org.chromium.base.FeatureMap; +import org.chromium.build.annotations.NullMarked; /** Java accessor for ui/android/ui_android_feature_map.cc state */ @JNINamespace("ui") +@NullMarked public class UiAndroidFeatureMap extends FeatureMap { private static final UiAndroidFeatureMap sInstance = new UiAndroidFeatureMap();
diff --git a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java index 6147db190b..4850a5f7 100644 --- a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java +++ b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
@@ -19,7 +19,6 @@ import android.view.inputmethod.InputConnection; import androidx.annotation.CallSuper; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.core.view.MarginLayoutParamsCompat; @@ -29,6 +28,8 @@ import org.chromium.base.Callback; import org.chromium.base.ObserverList; import org.chromium.base.ResettersForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.dragdrop.DragAndDropDelegate; import org.chromium.ui.dragdrop.DragAndDropDelegateImpl; import org.chromium.ui.dragdrop.DragStateTracker; @@ -37,8 +38,9 @@ /** Class to acquire, position, and remove anchor views from the implementing View. */ @JNINamespace("ui") +@NullMarked public class ViewAndroidDelegate { - private static DragAndDropDelegate sDragAndDropDelegateForTesting; + private static @Nullable DragAndDropDelegate sDragAndDropDelegateForTesting; private final DragAndDropDelegateImpl mDragAndDropDelegateImpl; /** @@ -70,7 +72,7 @@ private final ObserverList<VerticalScrollDirectionChangeListener> mVerticalScrollDirectionChangeListeners = new ObserverList<>(); - private Callback<Boolean> mUpdateShouldShowStylusHoverIcon; + private @Nullable Callback<Boolean> mUpdateShouldShowStylusHoverIcon; /** * Sets a callback which should be called with the latest value of whether the element being @@ -185,7 +187,7 @@ * @return An anchor view that can be used to anchor decoration views like Autofill popup. */ @CalledByNative - public View acquireView() { + public @Nullable View acquireView() { ViewGroup containerView = getContainerViewGroup(); if (containerView == null || containerView.getParent() == null) return null; View anchorView = new View(containerView.getContext());
diff --git a/ui/android/java/src/org/chromium/ui/base/ViewUtils.java b/ui/android/java/src/org/chromium/ui/base/ViewUtils.java index 41f092d..13709af 100644 --- a/ui/android/java/src/org/chromium/ui/base/ViewUtils.java +++ b/ui/android/java/src/org/chromium/ui/base/ViewUtils.java
@@ -18,8 +18,10 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import org.chromium.base.TraceEvent; +import org.chromium.build.annotations.NullMarked; /** A utility class that has helper methods for Android view. */ +@NullMarked public final class ViewUtils { private static final int[] sLocationTmp = new int[2];
diff --git a/ui/android/java/src/org/chromium/ui/base/ViewportInsets.java b/ui/android/java/src/org/chromium/ui/base/ViewportInsets.java index 78e91db..fc212ed4 100644 --- a/ui/android/java/src/org/chromium/ui/base/ViewportInsets.java +++ b/ui/android/java/src/org/chromium/ui/base/ViewportInsets.java
@@ -4,6 +4,8 @@ package org.chromium.ui.base; +import org.chromium.build.annotations.NullMarked; + /** * Information about various kinds of insets on the application viewport. * @@ -77,6 +79,7 @@ * │┼───────────────────────┼│ * └─────────────────────────┘ */ +@NullMarked public class ViewportInsets { /** * The total vertical inset on the application viewport coming from all visible UI controls.
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java index f0e9cf8..4c8baedc 100644 --- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -4,6 +4,8 @@ package org.chromium.ui.base; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.SuppressLint; @@ -26,7 +28,6 @@ import android.view.WindowManager; import android.window.TrustedPresentationThresholds; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import org.jni_zero.CalledByNative; @@ -49,6 +50,10 @@ import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; import org.chromium.build.BuildConfig; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; +import org.chromium.build.annotations.RequiresNonNull; import org.chromium.ui.InsetObserver; import org.chromium.ui.KeyboardVisibilityDelegate; import org.chromium.ui.display.DisplayAndroid; @@ -68,6 +73,7 @@ /** The window base class that has the minimum functionality. */ @JNINamespace("ui") +@NullMarked public class WindowAndroid implements AndroidPermissionDelegate, DisplayAndroidObserver, @@ -80,8 +86,8 @@ // exactly match the target rate. private static final float MAX_REFRESH_RATE_DELTA = 2.f; - private final LifetimeAssert mLifetimeAssert; - private IntentRequestTrackerImpl mIntentRequestTracker; + private final @Nullable LifetimeAssert mLifetimeAssert; + private @Nullable IntentRequestTrackerImpl mIntentRequestTracker; private KeyboardVisibilityDelegate mKeyboardVisibilityDelegate = KeyboardVisibilityDelegate.getInstance(); @@ -105,20 +111,20 @@ // We track all animations over content and provide a drawing placeholder for them. private HashSet<Animator> mAnimationsOverContent = new HashSet<>(); - private View mAnimationPlaceholderView; + private @Nullable View mAnimationPlaceholderView; /** A mechanism for observing and updating the application window's bottom inset. */ private ApplicationViewportInsetSupplier mApplicationBottomInsetSupplier = new ApplicationViewportInsetSupplier(); - private AndroidPermissionDelegate mPermissionDelegate; + private @Nullable AndroidPermissionDelegate mPermissionDelegate; // Note that this state lives in Java, rather than in the native BeginFrameSource because // clients may pause VSync before the native WindowAndroid is created. private boolean mVSyncPaused; // List of display modes with the same dimensions as the current mode but varying refresh rate. - private List<Display.Mode> mSupportedRefreshRateModes; + private @Nullable List<Display.Mode> mSupportedRefreshRateModes; // A container for UnownedUserData objects that are not owned by, but can be accessed through // WindowAndroid. @@ -126,7 +132,7 @@ private float mRefreshRate; private boolean mHasFocus = true; - private OverlayTransformApiHelper mOverlayTransformApiHelper; + private @Nullable OverlayTransformApiHelper mOverlayTransformApiHelper; // The information required to draw a replica of the progress bar drawn in // java UI in composited UI. @@ -147,7 +153,7 @@ } } - private ProgressBarConfig.Provider mProgressBarConfigProvider; + private ProgressBarConfig.@Nullable Provider mProgressBarConfigProvider; /** An interface to notify listeners that a context menu is closed. */ public interface OnCloseContextMenuListener { @@ -185,16 +191,16 @@ private final boolean mAllowChangeRefreshRate; /** Gets the view for readback. */ - public View getReadbackView() { + public @Nullable View getReadbackView() { return null; } private final ObserverList<OnCloseContextMenuListener> mContextMenuCloseListeners = new ObserverList<>(); - private ModalDialogManager mModalDialogManagerForTesting; + private @Nullable ModalDialogManager mModalDialogManagerForTesting; - private Consumer<Boolean> mOcclusionObserver; + private @Nullable Consumer<Boolean> mOcclusionObserver; private final boolean mTrackOcclusion; @@ -213,7 +219,7 @@ protected WindowAndroid( Context context, IntentRequestTracker tracker, - InsetObserver insetObserver, + @Nullable InsetObserver insetObserver, boolean trackOcclusion) { this(context, DisplayAndroid.getNonMultiDisplay(context), trackOcclusion); mIntentRequestTracker = (IntentRequestTrackerImpl) tracker; @@ -286,13 +292,13 @@ maybeUnregisterOcclusionObserver(); } - private void maybeRegisterOcclusionObserver(IBinder windowToken) { + private void maybeRegisterOcclusionObserver(@Nullable IBinder windowToken) { if (!mTrackOcclusion || Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) { return; } assert mOcclusionObserver == null; - Context context = getContext().get(); + Context context = assumeNonNull(getContext().get()); WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); var thresholds = new TrustedPresentationThresholds(Float.MIN_VALUE, Float.MIN_VALUE, 1); @@ -320,7 +326,7 @@ } assert mOcclusionObserver != null; - Context context = getContext().get(); + Context context = assumeNonNull(getContext().get()); WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); wm.unregisterTrustedPresentationListener(mOcclusionObserver); @@ -361,8 +367,7 @@ } /** Gets the {@link IntentRequestTracker} associated with the WindowAndroid's activity. */ - @Nullable - public final IntentRequestTracker getIntentRequestTracker() { + public final @Nullable IntentRequestTracker getIntentRequestTracker() { if (mIntentRequestTracker == null) { Log.w( TAG, @@ -402,7 +407,7 @@ * results, or null if no message is required. * @return Whether the intent was shown. */ - public boolean showIntent(Intent intent, IntentCallback callback, Integer errorId) { + public boolean showIntent(@Nullable Intent intent, IntentCallback callback, Integer errorId) { if (mIntentRequestTracker == null) { Log.d(TAG, "Can't show intent as context is not an Activity: " + intent); return false; @@ -849,8 +854,8 @@ // Helper to get the android Window. Always null for application context. Need to null check // result returning value. - @Nullable - public Window getWindow() { + + public @Nullable Window getWindow() { Activity activity = ContextUtils.activityFromContext(mContextRef.get()); if (activity == null || activity.isFinishing()) return null; return activity.getWindow(); @@ -892,7 +897,7 @@ } /** Returns the {@link InsetObserver} for the root view of the activity or null. */ - public InsetObserver getInsetObserver() { + public @Nullable InsetObserver getInsetObserver() { return mInsetObserver; } @@ -957,12 +962,13 @@ // returning to the default optimized state. animation.addListener( new AnimatorListenerAdapter() { + @NullUnmarked @Override public void onAnimationEnd(Animator animation) { animation.removeListener(this); mAnimationsOverContent.remove(animation); if (mAnimationsOverContent.isEmpty()) { - mAnimationPlaceholderView.setWillNotDraw(true); + assumeNonNull(mAnimationPlaceholderView).setWillNotDraw(true); } } }); @@ -979,14 +985,14 @@ } /** Return the decor view, or null. */ - private View getDecorView() { + private @Nullable View getDecorView() { Window window = getWindow(); if (window == null) return null; return window.getDecorView(); } /** Return the current window token, or null. */ - public IBinder getWindowToken() { + public @Nullable IBinder getWindowToken() { Window window = getWindow(); if (window == null) return null; View decorView = window.peekDecorView(); @@ -1035,12 +1041,12 @@ } @Override - public void onCurrentModeChanged(Display.Mode currentMode) { + public void onCurrentModeChanged(Display.@Nullable Mode currentMode) { recomputeSupportedRefreshRates(); } @Override - public void onDisplayModesChanged(List<Display.Mode> supportedModes) { + public void onDisplayModesChanged(@Nullable List<Display.Mode> supportedModes) { recomputeSupportedRefreshRates(); } @@ -1109,7 +1115,7 @@ @SuppressLint("NewApi") // mSupportedRefreshRateModes should only be set if Display.Mode is available. @CalledByNative - private float[] getSupportedRefreshRates() { + private float @Nullable [] getSupportedRefreshRates() { if (mSupportedRefreshRateModes == null || !mAllowChangeRefreshRate) return null; float[] supportedRefreshRates = new float[mSupportedRefreshRateModes.size()]; @@ -1139,8 +1145,10 @@ window.setAttributes(params); } + @NullUnmarked @SuppressLint("NewApi") // mSupportedRefreshRateModes should only be set if Display.Mode is available. + @RequiresNonNull("mSupportedRefreshRateModes") private int getPreferredModeId(float preferredRefreshRate) { if (preferredRefreshRate == 0) return 0; @@ -1232,7 +1240,9 @@ void destroy(long nativeWindowAndroid, WindowAndroid caller); void onSupportedRefreshRatesUpdated( - long nativeWindowAndroid, WindowAndroid caller, float[] supportedRefreshRates); + long nativeWindowAndroid, + WindowAndroid caller, + float @Nullable [] supportedRefreshRates); void onOverlayTransformUpdated(long nativeWindowAndroid, WindowAndroid caller);
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowDelegate.java b/ui/android/java/src/org/chromium/ui/base/WindowDelegate.java index f09d508..b31ee8a 100644 --- a/ui/android/java/src/org/chromium/ui/base/WindowDelegate.java +++ b/ui/android/java/src/org/chromium/ui/base/WindowDelegate.java
@@ -7,7 +7,10 @@ import android.graphics.Rect; import android.view.Window; +import org.chromium.build.annotations.NullMarked; + /** This is a delegate that handles communication about a window's current state and properties. */ +@NullMarked public class WindowDelegate { private final Window mWindow;
diff --git a/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java b/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java index 76856d9..975fd18 100644 --- a/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java +++ b/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java
@@ -4,6 +4,8 @@ package org.chromium.ui.display; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.graphics.Insets; import android.graphics.Rect; @@ -13,6 +15,10 @@ import androidx.annotation.RequiresApi; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; + import java.util.List; import java.util.WeakHashMap; @@ -23,6 +29,7 @@ * anywhere, as long as the corresponding WindowAndroids are destroyed. The observers are * held weakly so to not lead to leaks. */ +@NullMarked public class DisplayAndroid { /** DisplayAndroidObserver interface for changes to this Display. */ public interface DisplayAndroidObserver { @@ -52,14 +59,14 @@ * * @param supportedModes the array of supported modes. */ - default void onDisplayModesChanged(List<Display.Mode> supportedModes) {} + default void onDisplayModesChanged(@Nullable List<Display.Mode> supportedModes) {} /** * Called whenever the attached display's current mode is changed. * * @param currentMode the current display mode. */ - default void onCurrentModeChanged(Display.Mode currentMode) {} + default void onCurrentModeChanged(Display.@Nullable Mode currentMode) {} } private static final DisplayAndroidObserver[] EMPTY_OBSERVER_ARRAY = @@ -69,9 +76,9 @@ // Do NOT add strong references to objects with potentially complex lifetime, like Context. private final int mDisplayId; - private String mName; + private @Nullable String mName; private Rect mBounds; - private Insets mInsets; + private @Nullable Insets mInsets; private float mDipScale; private float mXdpi; private float mYdpi; @@ -79,8 +86,8 @@ private int mBitsPerComponent; private int mRotation; private float mRefreshRate; - private Display.Mode mCurrentDisplayMode; - private List<Display.Mode> mDisplayModes; + private Display.@Nullable Mode mCurrentDisplayMode; + private @Nullable List<Display.Mode> mDisplayModes; private boolean mIsHdr; private float mHdrMaxLuminanceRatio = 1.0f; private boolean mIsInternal; @@ -119,7 +126,7 @@ } /** Returns the name of the display. */ - public String getDisplayName() { + public @Nullable String getDisplayName() { return mName; } @@ -146,13 +153,14 @@ /** Returns the insets of the display. */ @RequiresApi(Build.VERSION_CODES.R) public Insets getInsets() { - return mInsets; + return assumeNonNull(mInsets); } /** Returns the insets as an array. */ @RequiresApi(Build.VERSION_CODES.R) public int[] getInsetsAsArray() { - return new int[] {mInsets.left, mInsets.top, mInsets.right, mInsets.bottom}; + Insets insets = assumeNonNull(mInsets); + return new int[] {insets.left, insets.top, insets.right, insets.bottom}; } /** Returns current orientation. One of Surface.ORIENTATION_* values. */ @@ -217,12 +225,12 @@ } /** Returns Display.Modes supported by this Display. */ - public List<Display.Mode> getSupportedModes() { + public @Nullable List<Display.Mode> getSupportedModes() { return mDisplayModes; } /** Returns current Display.Mode for the display. */ - public Display.Mode getCurrentMode() { + public Display.@Nullable Mode getCurrentMode() { return mCurrentDisplayMode; } @@ -255,7 +263,7 @@ /** * Return window context for display android. Implemented by @{@link PhysicalDisplayAndroid}. */ - public Context getWindowContext() { + public @Nullable Context getWindowContext() { return null; } @@ -286,7 +294,8 @@ return mObservers.keySet().toArray(EMPTY_OBSERVER_ARRAY); } - public void updateIsDisplayServerWideColorGamut(Boolean isDisplayServerWideColorGamut) { + public void updateIsDisplayServerWideColorGamut( + @Nullable Boolean isDisplayServerWideColorGamut) { update( /* name= */ null, /* bounds= */ null, @@ -308,24 +317,25 @@ } /** Update the display to the provided parameters. Null values leave the parameter unchanged. */ + @NullUnmarked protected void update( - String name, - Rect bounds, - Insets insets, - Float dipScale, - Float xdpi, - Float ydpi, - Integer bitsPerPixel, - Integer bitsPerComponent, - Integer rotation, - Boolean isDisplayWideColorGamut, - Boolean isDisplayServerWideColorGamut, - Float refreshRate, - Display.Mode currentMode, - List<Display.Mode> supportedModes, - Boolean isHdr, - Float hdrMaxLuminanceRatio, - Boolean isInternal) { + @Nullable String name, + @Nullable Rect bounds, + @Nullable Insets insets, + @Nullable Float dipScale, + @Nullable Float xdpi, + @Nullable Float ydpi, + @Nullable Integer bitsPerPixel, + @Nullable Integer bitsPerComponent, + @Nullable Integer rotation, + @Nullable Boolean isDisplayWideColorGamut, + @Nullable Boolean isDisplayServerWideColorGamut, + @Nullable Float refreshRate, + Display.@Nullable Mode currentMode, + @Nullable List<Display.Mode> supportedModes, + @Nullable Boolean isHdr, + @Nullable Float hdrMaxLuminanceRatio, + @Nullable Boolean isInternal) { boolean nameChanged = name != null && !name.equals(mName); boolean boundsChanged = bounds != null && !bounds.equals(mBounds); boolean insetsChanged = insets != null && !insets.equals(mInsets);
diff --git a/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java b/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java index e3fad5b..1840454 100644 --- a/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java +++ b/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java
@@ -21,9 +21,12 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** DisplayAndroidManager is a class that informs its observers Display changes. */ @JNINamespace("ui") +@NullMarked public class DisplayAndroidManager { /** * DisplayListenerBackend is used to handle the actual listening of display changes. It handles @@ -72,7 +75,7 @@ } } - private static DisplayAndroidManager sDisplayAndroidManager; + private static @Nullable DisplayAndroidManager sDisplayAndroidManager; private static boolean sDisableHdrSdkRatioCallback; @@ -220,7 +223,7 @@ long nativeDisplayAndroidManager, DisplayAndroidManager caller, int sdkDisplayId, - String label, + @Nullable String label, int[] bounds, // the order is: left, top, right, bottom int[] insets, // the order is: left, top, right, bottom float dipScale,
diff --git a/ui/android/java/src/org/chromium/ui/display/DisplaySwitches.java b/ui/android/java/src/org/chromium/ui/display/DisplaySwitches.java index dcfb64f..3a54add1 100644 --- a/ui/android/java/src/org/chromium/ui/display/DisplaySwitches.java +++ b/ui/android/java/src/org/chromium/ui/display/DisplaySwitches.java
@@ -4,7 +4,10 @@ package org.chromium.ui.display; +import org.chromium.build.annotations.NullMarked; + /** Contains all of the command line switches that are specific to the display. */ +@NullMarked public abstract class DisplaySwitches { // Native switch - display_switches::kForceDeviceScaleFactor public static final String FORCE_DEVICE_SCALE_FACTOR = "force-device-scale-factor";
diff --git a/ui/android/java/src/org/chromium/ui/display/DisplayUtil.java b/ui/android/java/src/org/chromium/ui/display/DisplayUtil.java index 3e4775e..11da4b1f 100644 --- a/ui/android/java/src/org/chromium/ui/display/DisplayUtil.java +++ b/ui/android/java/src/org/chromium/ui/display/DisplayUtil.java
@@ -4,6 +4,8 @@ package org.chromium.ui.display; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.content.res.Configuration; import android.graphics.Insets; @@ -16,12 +18,14 @@ import android.view.WindowInsets; import android.view.WindowManager; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * Helper functions relevant to working with displays, but have no parallel in the native * DisplayAndroid class. */ +@NullMarked public abstract class DisplayUtil { private static @Nullable Float sUiScalingFactorForAutomotiveOverride; @@ -41,7 +45,7 @@ */ @Deprecated public static float getUiScalingFactorForAutomotive() { - return sUiScalingFactorForAutomotiveOverride; + return assumeNonNull(sUiScalingFactorForAutomotiveOverride); } public static int getUiDensityForAutomotive(Context context, int baseDensity) {
diff --git a/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java b/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java index 8b4ecea..90a9c7d 100644 --- a/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java +++ b/ui/android/java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java
@@ -27,12 +27,16 @@ import org.chromium.base.Log; import org.chromium.base.StrictModeContext; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; /** A DisplayAndroid implementation tied to a physical Display. */ +@NullMarked /* package */ class PhysicalDisplayAndroid extends DisplayAndroid { private static final String TAG = "DisplayAndroid"; @@ -42,9 +46,10 @@ // When this object exists, a positive value means that the forced DIP scale is set and // the zero means it is not. The non existing object (i.e. null reference) means that // the existence and value of the forced DIP scale has not yet been determined. + @SuppressWarnings("NullAway.Init") private static Float sForcedDIPScale; - private static Float getHdrSdrRatio(Display display) { + private static @Nullable Float getHdrSdrRatio(Display display) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) return null; return display.getHdrSdrRatio(); } @@ -147,10 +152,10 @@ } } - private final Context mWindowContext; - private final ComponentCallbacks mComponentCallbacks; + private final @Nullable Context mWindowContext; + private final @Nullable ComponentCallbacks mComponentCallbacks; private final Display mDisplay; - private Consumer<Display> mHdrSdrRatioCallback; + private @Nullable Consumer<Display> mHdrSdrRatioCallback; /* package */ PhysicalDisplayAndroid(Display display, boolean disableHdrSdkRatioCallback) { super(display.getDisplayId()); @@ -197,10 +202,11 @@ } @Override - public Context getWindowContext() { + public @Nullable Context getWindowContext() { return mWindowContext; } + @NullUnmarked @RequiresApi(VERSION_CODES.R) private void updateFromConfiguration() { WindowManager windowManager = mWindowContext.getSystemService(WindowManager.class); @@ -230,7 +236,8 @@ mWindowContext.getDisplay()); } - /* package */ void onDisplayRemoved() { + /* package */ @NullUnmarked + void onDisplayRemoved() { if (USE_CONFIGURATION) { mWindowContext.unregisterComponentCallbacks(mComponentCallbacks); } @@ -292,8 +299,14 @@ /* isInternal= */ null); } + @NullUnmarked private void updateCommon( - Rect bounds, Insets insets, float density, float xdpi, float ydpi, Display display) { + Rect bounds, + @Nullable Insets insets, + float density, + float xdpi, + float ydpi, + Display display) { if (hasForcedDIPScale()) density = sForcedDIPScale.floatValue(); boolean isWideColorGamut = false; // Although this API was added in Android O, it was buggy.
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/AnimatedImageDragShadowBuilder.java b/ui/android/java/src/org/chromium/ui/dragdrop/AnimatedImageDragShadowBuilder.java index b6fe175..7f9b80c 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/AnimatedImageDragShadowBuilder.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/AnimatedImageDragShadowBuilder.java
@@ -21,6 +21,7 @@ import androidx.core.content.res.ResourcesCompat; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.R; /** @@ -28,6 +29,7 @@ * to the center of the touch point. See go/animated-image-drag-shadow-corner-cases for known edge * cases. */ +@NullMarked class AnimatedImageDragShadowBuilder extends View.DragShadowBuilder { /** * Animatable progress for the drag shadow. When the progress is 0, the drag shadow is full size
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropBrowserDelegate.java b/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropBrowserDelegate.java index 5370e0a9..2dbf0fb 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropBrowserDelegate.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropBrowserDelegate.java
@@ -9,9 +9,11 @@ import android.view.DragAndDropPermissions; import android.view.DragEvent; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.dragdrop.DragDropMetricUtils.UrlIntentSource; /** Delegate for browser related functions used by Drag and Drop. */ +@NullMarked public interface DragAndDropBrowserDelegate { /** Get whether to support the image drop into Chrome. */ boolean getSupportDropInChrome();
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegate.java b/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegate.java index 33d2f76..c6783c6 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegate.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegate.java
@@ -9,10 +9,14 @@ import android.view.View; import android.view.View.DragShadowBuilder; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** * Delegate to facilitate Drag and Drop operations, for example re-routing the call to {@link * #startDragAndDrop(Bitmap, DropDataAndroid).} */ +@NullMarked public interface DragAndDropDelegate { /** * @see View#startDragAndDrop @@ -21,7 +25,7 @@ View containerView, Bitmap shadowImage, DropDataAndroid dropData, - Context context, + @Nullable Context context, int cursorOffsetX, int cursorOffsetY, int dragObjRectWidth,
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegateImpl.java b/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegateImpl.java index 58b8b41..caf33f7 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegateImpl.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegateImpl.java
@@ -24,8 +24,6 @@ import android.widget.ImageView; import androidx.annotation.IntDef; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.graphics.drawable.RoundedBitmapDrawable; @@ -34,6 +32,9 @@ import org.chromium.base.ContextUtils; import org.chromium.base.MathUtils; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; import org.chromium.ui.accessibility.AccessibilityState; import org.chromium.ui.base.MimeTypeUtils; @@ -50,6 +51,7 @@ * Drag and drop helper class in charge of building the clip data, wrapping calls to {@link * android.view.View#startDragAndDrop}. Also used for mocking out real function calls to Android. */ +@NullMarked public class DragAndDropDelegateImpl implements DragAndDropDelegate, DragStateTracker { /** * Java Enum of AndroidDragTargetType used for histogram recording for @@ -107,12 +109,13 @@ * @param dragObjRectWidth The width of the drag object. * @param dragObjRectHeight The height of the drag object. */ + @NullUnmarked @Override public boolean startDragAndDrop( - @NonNull View containerView, - @NonNull Bitmap shadowImage, - @NonNull DropDataAndroid dropData, - @NonNull Context context, + View containerView, + Bitmap shadowImage, + DropDataAndroid dropData, + @Nullable Context context, int cursorOffsetX, int cursorOffsetY, int dragObjRectWidth, @@ -137,9 +140,7 @@ @Override public boolean startDragAndDrop( - @NonNull View containerView, - @NonNull DragShadowBuilder dragShadowBuilder, - @NonNull DropDataAndroid dropData) { + View containerView, DragShadowBuilder dragShadowBuilder, DropDataAndroid dropData) { if (isA11yStateEnabled()) return false; return startDragAndDropInternal(containerView, dragShadowBuilder, dropData); } @@ -152,9 +153,7 @@ } private boolean startDragAndDropInternal( - @NonNull View containerView, - @NonNull DragShadowBuilder dragShadowBuilder, - @NonNull DropDataAndroid dropData) { + View containerView, DragShadowBuilder dragShadowBuilder, DropDataAndroid dropData) { ClipData clipdata = buildClipData(dropData); if (clipdata == null && !UiAndroidFeatureMap.isEnabled(UiAndroidFeatureList.DRAG_DROP_EMPTY)) { @@ -240,8 +239,8 @@ * @param dropData The data to be dropped. * @return ClipData based on the dropData type. */ - @Nullable - protected ClipData buildClipData(DropDataAndroid dropData) { + @NullUnmarked + protected @Nullable ClipData buildClipData(DropDataAndroid dropData) { @DragTargetType int type = getDragTargetType(dropData); switch (type) { case DragTargetType.TEXT:
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DragDropGlobalState.java b/ui/android/java/src/org/chromium/ui/dragdrop/DragDropGlobalState.java index dead210..659a70c 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DragDropGlobalState.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DragDropGlobalState.java
@@ -8,11 +8,10 @@ import android.view.DragEvent; import android.view.View.DragShadowBuilder; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import org.chromium.base.Log; import org.chromium.base.ResettersForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * Drag-Drop objects to be shared across instances. General usage: @@ -25,6 +24,7 @@ * <li>When drag ends, client that starts the drag need to do {@link #clear(TrackerToken)} to reset * the global state. */ +@NullMarked public class DragDropGlobalState { private static final String TAG = "DnDGlobalState"; private @Nullable static GlobalStateHolder sGlobalStateHolder; @@ -57,7 +57,7 @@ */ public static TrackerToken store( int dragSourceInstanceId, - @NonNull DropDataAndroid dropData, + DropDataAndroid dropData, @Nullable DragShadowBuilder dragShadowBuilder) { if (sGlobalStateHolder != null) { Log.w( @@ -88,7 +88,7 @@ } /** Get the global state using DragEvent with {@link DragEvent#ACTION_DROP}. */ - public static @Nullable DragDropGlobalState getState(@NonNull DragEvent dropEvent) { + public static @Nullable DragDropGlobalState getState(DragEvent dropEvent) { if (sGlobalStateHolder == null || dropEvent.getAction() != DragEvent.ACTION_DROP) { return null; } @@ -99,7 +99,7 @@ * Return the drag shadow builder during this drag and drop process, if provided to the * DragDropGlobalState. */ - public static DragShadowBuilder getDragShadowBuilder() { + public static @Nullable DragShadowBuilder getDragShadowBuilder() { if (sGlobalStateHolder == null) return null; return sGlobalStateHolder.mDragShadowBuilder; } @@ -108,16 +108,16 @@ * Tokens are released when startDragAndDrop fails or by listeners on drag end event. If a * caller fails to release token, sHolder is not cleared and the next build call will fail. */ - public static void clear(@NonNull TrackerToken token) { + public static void clear(TrackerToken token) { assert sGlobalStateHolder == null || sGlobalStateHolder.mToken.equals(token) : "Token mismatch."; sGlobalStateHolder = null; } private final int mDragSourceInstanceId; - private final @NonNull DropDataAndroid mDropData; + private final DropDataAndroid mDropData; - DragDropGlobalState(int dragSourceInstanceId, @NonNull DropDataAndroid dropData) { + DragDropGlobalState(int dragSourceInstanceId, DropDataAndroid dropData) { mDragSourceInstanceId = dragSourceInstanceId; mDropData = dropData; } @@ -133,11 +133,10 @@ } /** Return the {@link DropDataAndroid} held by the global state. */ - public @NonNull DropDataAndroid getData() { + public DropDataAndroid getData() { return mDropData; } - @NonNull @Override public String toString() { return "DragDropGlobalState" + " sourceId:" + mDragSourceInstanceId;
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DragDropMetricUtils.java b/ui/android/java/src/org/chromium/ui/dragdrop/DragDropMetricUtils.java index f009dbb9..453c67a 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DragDropMetricUtils.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DragDropMetricUtils.java
@@ -7,11 +7,13 @@ import androidx.annotation.IntDef; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.build.annotations.NullMarked; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** Define enums for Drag and Drop metrics. This class is not supposed to be instantiated. */ +@NullMarked public class DragDropMetricUtils { public static String HISTOGRAM_DRAG_DROP_TAB_TYPE = "Android.DragDrop.Tab.Type";
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DragEventDispatchHelper.java b/ui/android/java/src/org/chromium/ui/dragdrop/DragEventDispatchHelper.java index 9ca755b..9c1d33ac 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DragEventDispatchHelper.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DragEventDispatchHelper.java
@@ -9,9 +9,11 @@ import android.view.View; import android.view.View.OnDragListener; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** * Wrapper class that accounts for drag event coordinate differences when forwarding a * {@link DragEvent} from View A to View B. This class currently only support destinations that @@ -38,6 +40,7 @@ * } * </pre> */ +@NullMarked public class DragEventDispatchHelper implements OnDragListener { static final int[] ALL_DRAG_ACTIONS = new int[] {
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DragStateTracker.java b/ui/android/java/src/org/chromium/ui/dragdrop/DragStateTracker.java index 6e55d804..4b4ec7a 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DragStateTracker.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DragStateTracker.java
@@ -6,7 +6,10 @@ import android.view.View; +import org.chromium.build.annotations.NullMarked; + /** Helper class the listen and track the latest drag event for the view. */ +@NullMarked public interface DragStateTracker extends View.OnDragListener { /** Return whether there's an active drag process started. */ default boolean isDragStarted() {
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DropDataAndroid.java b/ui/android/java/src/org/chromium/ui/dragdrop/DropDataAndroid.java index a04f89d..e2ae399c 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DropDataAndroid.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DropDataAndroid.java
@@ -11,10 +11,12 @@ import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; +import org.chromium.build.annotations.NullMarked; import org.chromium.url.GURL; /** Bare minimal wrapper class of native content::DropData. */ @JNINamespace("ui") +@NullMarked public class DropDataAndroid { public final String text; public final GURL gurl;
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DropDataContentProvider.java b/ui/android/java/src/org/chromium/ui/dragdrop/DropDataContentProvider.java index 2d07454..8f3be9d 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DropDataContentProvider.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DropDataContentProvider.java
@@ -12,10 +12,11 @@ import android.os.Bundle; import android.os.ParcelFileDescriptor; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + import java.io.FileNotFoundException; /** @@ -26,6 +27,7 @@ * the feature from different platforms as other platform won't be able to access the impl * class directly as it lives in other classloader than the app's one (Chromium classloader). */ +@NullMarked public class DropDataContentProvider extends ContentProvider { private DropDataProviderImpl mDropDataProviderImpl; @@ -41,54 +43,58 @@ } @Override - public String getType(Uri uri) { + public @Nullable String getType(Uri uri) { return mDropDataProviderImpl.getType(uri); } @Override - public String[] getStreamTypes(Uri uri, String mimeTypeFilter) { + public String @Nullable [] getStreamTypes(Uri uri, String mimeTypeFilter) { return mDropDataProviderImpl.getStreamTypes(uri, mimeTypeFilter); } @Override - public AssetFileDescriptor openAssetFile(Uri uri, String mode) + public @Nullable AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException, SecurityException { return mDropDataProviderImpl.openAssetFile(this, uri, mode); } @Override - public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { + public @Nullable ParcelFileDescriptor openFile(Uri uri, String mode) + throws FileNotFoundException { return mDropDataProviderImpl.openFile(this, uri); } @Override public Cursor query( Uri uri, - String[] projection, - String selection, - String[] selectionArgs, - String sortOrder) { + String @Nullable [] projection, + @Nullable String selection, + String @Nullable [] selectionArgs, + @Nullable String sortOrder) { return mDropDataProviderImpl.query(uri, projection); } @Override - public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { + public int update( + Uri uri, + @Nullable ContentValues values, + @Nullable String where, + String @Nullable [] whereArgs) { throw new UnsupportedOperationException(); } @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { + public int delete(Uri uri, @Nullable String selection, String @Nullable [] selectionArgs) { throw new UnsupportedOperationException(); } @Override - public Uri insert(Uri uri, ContentValues values) { + public Uri insert(Uri uri, @Nullable ContentValues values) { throw new UnsupportedOperationException(); } - @Nullable @Override - public Bundle call(@NonNull String method, @Nullable String arg, @Nullable Bundle extras) { + public @Nullable Bundle call(String method, @Nullable String arg, @Nullable Bundle extras) { return mDropDataProviderImpl.call(method, arg, extras); }
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DropDataProviderImpl.java b/ui/android/java/src/org/chromium/ui/dragdrop/DropDataProviderImpl.java index b8df2ba3..c24a88d 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DropDataProviderImpl.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DropDataProviderImpl.java
@@ -18,11 +18,11 @@ import android.provider.OpenableColumns; import android.webkit.MimeTypeMap; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import org.chromium.base.ContextUtils; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.build.annotations.UsedByReflection; import java.io.FileNotFoundException; @@ -38,6 +38,7 @@ * provider to this java doc. */ @UsedByReflection("Webview Support Lib") +@NullMarked public class DropDataProviderImpl { public static final String CACHE_METHOD_NAME = "cache"; public static final String SET_INTERVAL_METHOD_NAME = "setClearCachedDataIntervalMs"; @@ -70,8 +71,8 @@ ParcelFileDescriptor output, Uri uri, String mimeType, - Bundle opts, - byte[] imageBytes) { + @Nullable Bundle opts, + byte @Nullable [] imageBytes) { try (OutputStream out = new FileOutputStream(output.getFileDescriptor())) { if (imageBytes != null) { out.write(imageBytes); @@ -91,21 +92,25 @@ private static final Object LOCK = new Object(); private int mClearCachedDataIntervalMs = DEFAULT_CLEAR_CACHED_DATA_INTERVAL_MS; + + @SuppressWarnings("NullAway.Init") private byte[] mImageBytes; - private String mImageFilename; - private String mMimeType; + + private @Nullable String mImageFilename; + private @Nullable String mMimeType; /** The URI handled by this content provider. */ - private Uri mContentProviderUri; + private @Nullable Uri mContentProviderUri; - private Handler mHandler; + private @Nullable Handler mHandler; private long mDragEndTime; private long mOpenFileLastAccessTime; - private Uri mLastUri; + private @Nullable Uri mLastUri; private long mLastUriClearedTimestamp; private long mLastUriCreatedTimestamp; private boolean mLastUriRecorded; + @SuppressWarnings("NullAway.Init") private DropPipeDataWriter mDropPipeDataWriter; /** This constructor is being used to initialize the pipeWriter. */ @@ -134,7 +139,8 @@ /** * Cache the passed-in image data of Drag and Drop. It is expected for filename to be non-empty. */ - public Uri cache(byte[] imageBytes, String encodingFormat, String filename) { + public Uri cache( + byte[] imageBytes, @Nullable String encodingFormat, @Nullable String filename) { long elapsedRealtime = SystemClock.elapsedRealtime(); long lastUriCreatedTimestamp = mLastUriCreatedTimestamp; String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(encodingFormat); @@ -199,6 +205,7 @@ } /** Clear the image data of Drag and Drop. */ + @NullUnmarked private void clearCacheData() { mImageBytes = null; mImageFilename = null; @@ -240,7 +247,7 @@ /** * @see ContentProvider#getType(Uri) */ - public String getType(Uri uri) { + public @Nullable String getType(Uri uri) { synchronized (LOCK) { if (uri == null || !uri.equals(mContentProviderUri)) { return null; @@ -252,7 +259,7 @@ /** * @see ContentProvider#getStreamTypes(Uri, String) */ - public String[] getStreamTypes(Uri uri, String mimeTypeFilter) { + public String @Nullable [] getStreamTypes(Uri uri, String mimeTypeFilter) { String mimeType; synchronized (LOCK) { if (uri == null || !uri.equals(mContentProviderUri)) { @@ -263,7 +270,7 @@ return matchMimeType(mimeType, mimeTypeFilter) ? new String[] {mimeType} : null; } - private boolean matchMimeType(String mimeType, String mimeTypeFilter) { + private boolean matchMimeType(@Nullable String mimeType, String mimeTypeFilter) { if (mimeType == null || mimeTypeFilter == null) { return false; } @@ -283,7 +290,9 @@ /** * @see ContentProvider#openAssetFile(Uri, String) */ - public AssetFileDescriptor openAssetFile(ContentProvider providerWrapper, Uri uri, String mode) + @NullUnmarked + public @Nullable AssetFileDescriptor openAssetFile( + ContentProvider providerWrapper, Uri uri, String mode) throws FileNotFoundException, SecurityException { if (uri == null) { return null; @@ -322,7 +331,7 @@ /** * @see ContentProvider#openFile(Uri, String) */ - public ParcelFileDescriptor openFile(ContentProvider providerWrapper, Uri uri) + public @Nullable ParcelFileDescriptor openFile(ContentProvider providerWrapper, Uri uri) throws FileNotFoundException { AssetFileDescriptor afd = openAssetFile(providerWrapper, uri, "r"); return afd != null ? afd.getParcelFileDescriptor() : null; @@ -331,7 +340,8 @@ /** * @see ContentProvider#query(Uri, String[], String, String[], String) */ - public Cursor query(Uri uri, String[] projection) { + @NullUnmarked + public Cursor query(Uri uri, String @Nullable [] projection) { byte[] imageBytes; String imageFilename; synchronized (LOCK) { @@ -378,8 +388,8 @@ /** * @see ContentProvider#call(String, String, Bundle) */ - @Nullable - public Bundle call(@NonNull String method, @Nullable String arg, @Nullable Bundle extras) { + @NullUnmarked + public @Nullable Bundle call(String method, @Nullable String arg, @Nullable Bundle extras) { switch (method) { case CACHE_METHOD_NAME: Bundle bundleToReturn = new Bundle(); @@ -410,6 +420,7 @@ } } + @Nullable Handler getHandlerForTesting() { synchronized (LOCK) { return mHandler;
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DropDataProviderUtils.java b/ui/android/java/src/org/chromium/ui/dragdrop/DropDataProviderUtils.java index a588641d..b7f03014 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DropDataProviderUtils.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DropDataProviderUtils.java
@@ -11,14 +11,16 @@ import android.net.Uri; import android.os.Bundle; -import androidx.annotation.Nullable; - import org.chromium.base.ContextUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; /** * This class wraps all the calls to ContentResolver#call. * */ +@NullMarked public class DropDataProviderUtils { /** * Wraps the call to onDragEnd in the provider, we call it to clear the cached image data after @@ -57,8 +59,8 @@ * Wraps the call to cache in the provider and returns the cached Uri or null if it failed to * call the content provider. */ - @Nullable - static Uri cacheImageData(DropDataAndroid dropData) { + @NullUnmarked + static @Nullable Uri cacheImageData(DropDataAndroid dropData) { Bundle bundle = new Bundle(); bundle.putSerializable(DropDataProviderImpl.BYTES_PARAM, dropData.imageContent); bundle.putString(
diff --git a/ui/android/java/src/org/chromium/ui/drawable/AnimationLooper.java b/ui/android/java/src/org/chromium/ui/drawable/AnimationLooper.java index bee2b8c..ce71d12 100644 --- a/ui/android/java/src/org/chromium/ui/drawable/AnimationLooper.java +++ b/ui/android/java/src/org/chromium/ui/drawable/AnimationLooper.java
@@ -9,16 +9,18 @@ import android.graphics.drawable.Drawable; import android.os.Handler; -import androidx.annotation.Nullable; import androidx.vectordrawable.graphics.drawable.Animatable2Compat; import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat; import org.chromium.base.ResettersForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * Encapsulates the logic to loop animated drawables from both Android Framework. The animation * should be started and stopped using {@link #start()} and {@link #stop()}. */ +@NullMarked public class AnimationLooper { private static @Nullable Boolean sAreAnimatorsEnabledForTests;
diff --git a/ui/android/java/src/org/chromium/ui/drawable/StateListDrawableBuilder.java b/ui/android/java/src/org/chromium/ui/drawable/StateListDrawableBuilder.java index bc3475c..fbeb933 100644 --- a/ui/android/java/src/org/chromium/ui/drawable/StateListDrawableBuilder.java +++ b/ui/android/java/src/org/chromium/ui/drawable/StateListDrawableBuilder.java
@@ -13,6 +13,8 @@ import androidx.annotation.DrawableRes; import androidx.appcompat.content.res.AppCompatResources; +import org.chromium.build.annotations.NullMarked; + import java.util.ArrayList; import java.util.List; @@ -35,6 +37,7 @@ * builder.addTransition(unchecked, checked, R.drawable.transition_unchecked_checked); * StateListDrawable drawable = builder.build(); */ +@NullMarked public class StateListDrawableBuilder { /** Identifies single state of the drawable. Used by {@link #addTransition}. */ public static class State {
diff --git a/ui/android/java/src/org/chromium/ui/events/devices/InputDeviceObserver.java b/ui/android/java/src/org/chromium/ui/events/devices/InputDeviceObserver.java index 91f169d2..7cb9b98 100644 --- a/ui/android/java/src/org/chromium/ui/events/devices/InputDeviceObserver.java +++ b/ui/android/java/src/org/chromium/ui/events/devices/InputDeviceObserver.java
@@ -17,12 +17,16 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; /** * A singleton that helps detecting changes in input devices through the interface * {@link InputDeviceObserver}. */ @JNINamespace("ui") +@NullMarked public class InputDeviceObserver implements InputDeviceListener { private static final InputDeviceObserver INSTANCE = new InputDeviceObserver(); private static final String KEYBOARD_CONNECTION_HISTOGRAM_NAME = @@ -50,7 +54,7 @@ INSTANCE.detachObserver(); } - private InputManager mInputManager; + private @Nullable InputManager mInputManager; private int mObserversCounter; // Override InputDeviceListener methods @@ -96,6 +100,7 @@ } } + @NullUnmarked private void detachObserver() { assert mObserversCounter > 0; if (--mObserversCounter == 0) {
diff --git a/ui/android/java/src/org/chromium/ui/gfx/Animation.java b/ui/android/java/src/org/chromium/ui/gfx/Animation.java index cd7fd1d9..2a18c83b 100644 --- a/ui/android/java/src/org/chromium/ui/gfx/Animation.java +++ b/ui/android/java/src/org/chromium/ui/gfx/Animation.java
@@ -10,12 +10,14 @@ import org.jni_zero.JNINamespace; import org.chromium.base.ContextUtils; +import org.chromium.build.annotations.NullMarked; /** * Provides utility methods relating to system animation state on the current platform (i.e. Android * in this case). See ui/gfx/animation/animation_android.cc. */ @JNINamespace("gfx") +@NullMarked public class Animation { @CalledByNative private static boolean prefersReducedMotion() {
diff --git a/ui/android/java/src/org/chromium/ui/gfx/BitmapHelper.java b/ui/android/java/src/org/chromium/ui/gfx/BitmapHelper.java index f2eb0a8..bb36419 100644 --- a/ui/android/java/src/org/chromium/ui/gfx/BitmapHelper.java +++ b/ui/android/java/src/org/chromium/ui/gfx/BitmapHelper.java
@@ -10,14 +10,17 @@ import org.jni_zero.JNINamespace; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** Helper class to decode and sample down bitmap resources. */ @JNINamespace("gfx") +@NullMarked public class BitmapHelper { private static final String TAG = "BitmapHelper"; @CalledByNative - private static Bitmap createBitmap( + private static @Nullable Bitmap createBitmap( int width, int height, int bitmapFormatValue, boolean catchOom) { Bitmap.Config bitmapConfig = getBitmapConfigForFormat(bitmapFormatValue); try {
diff --git a/ui/android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java b/ui/android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java index bcaa328..1eed5a8 100644 --- a/ui/android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java +++ b/ui/android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java
@@ -16,6 +16,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.StrictModeContext; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.R; /** @@ -24,6 +25,7 @@ * */ @JNINamespace("gfx") +@NullMarked public class ViewConfigurationHelper { // Fallback constants when resource lookup fails, see
diff --git a/ui/android/java/src/org/chromium/ui/gl/ChromeSurfaceTexture.java b/ui/android/java/src/org/chromium/ui/gl/ChromeSurfaceTexture.java index 731b74d..581789b 100644 --- a/ui/android/java/src/org/chromium/ui/gl/ChromeSurfaceTexture.java +++ b/ui/android/java/src/org/chromium/ui/gl/ChromeSurfaceTexture.java
@@ -11,8 +11,11 @@ import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import org.chromium.build.annotations.NullMarked; + /** Exposes SurfaceTexture APIs to native. */ @JNINamespace("gl") +@NullMarked class ChromeSurfaceTexture extends SurfaceTexture implements SurfaceTexture.OnFrameAvailableListener { private static final String TAG = "SurfaceTexture";
diff --git a/ui/android/java/src/org/chromium/ui/gl/ScopedJavaSurfaceControl.java b/ui/android/java/src/org/chromium/ui/gl/ScopedJavaSurfaceControl.java index 6e7bbab..54a62f2 100644 --- a/ui/android/java/src/org/chromium/ui/gl/ScopedJavaSurfaceControl.java +++ b/ui/android/java/src/org/chromium/ui/gl/ScopedJavaSurfaceControl.java
@@ -12,8 +12,11 @@ import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; +import org.chromium.build.annotations.NullMarked; + @RequiresApi(Build.VERSION_CODES.Q) @JNINamespace("gl") +@NullMarked class ScopedJavaSurfaceControl { @CalledByNative private static void releaseSurfaceControl(SurfaceControl surfaceControl) {
diff --git a/ui/android/java/src/org/chromium/ui/interpolators/AndroidxInterpolators.java b/ui/android/java/src/org/chromium/ui/interpolators/AndroidxInterpolators.java index 8590301..2b082c19 100644 --- a/ui/android/java/src/org/chromium/ui/interpolators/AndroidxInterpolators.java +++ b/ui/android/java/src/org/chromium/ui/interpolators/AndroidxInterpolators.java
@@ -7,7 +7,10 @@ import androidx.core.animation.Interpolator; import androidx.core.animation.PathInterpolator; +import org.chromium.build.annotations.NullMarked; + /** Reference to one of each standard interpolator to avoid allocations. */ +@NullMarked public class AndroidxInterpolators { public static final Interpolator STANDARD_INTERPOLATOR = new PathInterpolator(0.2f, 0f, 0f, 1f); }
diff --git a/ui/android/java/src/org/chromium/ui/interpolators/Interpolators.java b/ui/android/java/src/org/chromium/ui/interpolators/Interpolators.java index 6e4074e0..b61c6a1 100644 --- a/ui/android/java/src/org/chromium/ui/interpolators/Interpolators.java +++ b/ui/android/java/src/org/chromium/ui/interpolators/Interpolators.java
@@ -16,7 +16,10 @@ import androidx.interpolator.view.animation.FastOutSlowInInterpolator; import androidx.interpolator.view.animation.LinearOutSlowInInterpolator; +import org.chromium.build.annotations.NullMarked; + /** Reference to one of each standard interpolator to avoid allocations. */ +@NullMarked public class Interpolators { public static final Interpolator STANDARD_INTERPOLATOR = PathInterpolatorCompat.create(0.2f, 0f, 0f, 1f);
diff --git a/ui/android/java/src/org/chromium/ui/listmenu/BasicListMenu.java b/ui/android/java/src/org/chromium/ui/listmenu/BasicListMenu.java index 929a47d..d70db50c 100644 --- a/ui/android/java/src/org/chromium/ui/listmenu/BasicListMenu.java +++ b/ui/android/java/src/org/chromium/ui/listmenu/BasicListMenu.java
@@ -15,11 +15,12 @@ import androidx.annotation.ColorRes; import androidx.annotation.IntDef; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.core.view.ViewCompat; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; import org.chromium.ui.UiUtils; import org.chromium.ui.modelutil.LayoutViewBuilder; @@ -37,6 +38,7 @@ * An implementation of a list menu. Uses app_menu_layout as the default layout of menu and * list_menu_item as the default layout of a menu item. */ +@NullMarked public class BasicListMenu implements ListMenu, OnItemClickListener { @Retention(RetentionPolicy.SOURCE) @IntDef({ListMenuItemType.DIVIDER, ListMenuItemType.MENU_ITEM}) @@ -78,7 +80,7 @@ boolean isIconTintable, boolean groupContainsIcon, boolean enabled, - @Nullable View.OnClickListener clickListener, + View.@Nullable OnClickListener clickListener, @Nullable Intent intent) { PropertyModel.Builder modelBuilder = new PropertyModel.Builder(ListMenuItemProperties.ALL_KEYS) @@ -102,11 +104,11 @@ return new ListItem(ListMenuItemType.MENU_ITEM, modelBuilder.build()); } - private final @NonNull ListView mListView; - private final @NonNull ModelListAdapter mAdapter; - private final @NonNull View mContentView; - private final @NonNull List<Runnable> mClickRunnables; - private final @NonNull Delegate mDelegate; + private final ListView mListView; + private final ModelListAdapter mAdapter; + private final View mContentView; + private final List<Runnable> mClickRunnables; + private final Delegate mDelegate; /** * @param context The {@link Context} to inflate the layout. @@ -117,11 +119,11 @@ * @param backgroundTintColor The background tint color of the menu. */ public BasicListMenu( - @NonNull Context context, - @NonNull ModelList data, - @NonNull View contentView, - @NonNull ListView listView, - @NonNull Delegate delegate, + Context context, + ModelList data, + View contentView, + ListView listView, + Delegate delegate, @ColorRes int backgroundTintColor) { mAdapter = new ListMenuItemAdapter(data); mContentView = contentView; @@ -140,13 +142,11 @@ } } - @NonNull @Override public View getContentView() { return mContentView; } - @NonNull public ListView getListView() { return mListView; } @@ -183,6 +183,7 @@ return result; } + @NullUnmarked private void registerListItemTypes() { mAdapter.registerType( ListMenuItemType.MENU_ITEM,
diff --git a/ui/android/java/src/org/chromium/ui/listmenu/ListMenu.java b/ui/android/java/src/org/chromium/ui/listmenu/ListMenu.java index c32e00f..1e93ecbb 100644 --- a/ui/android/java/src/org/chromium/ui/listmenu/ListMenu.java +++ b/ui/android/java/src/org/chromium/ui/listmenu/ListMenu.java
@@ -6,12 +6,14 @@ import android.view.View; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.modelutil.PropertyModel; /** * Representation of a list menu. Contains and manages a content view by {@link #getContentView()}. * Handles click events of list items by {@link Delegate#onItemSelected(PropertyModel)}. */ +@NullMarked public interface ListMenu { /** Delegate handling list item click event of {@link ListMenu}. */ @FunctionalInterface
diff --git a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuButton.java b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuButton.java index 992d19ab..aa635a7 100644 --- a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuButton.java +++ b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuButton.java
@@ -16,6 +16,9 @@ import android.view.ViewParent; import org.chromium.base.ObserverList; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; import org.chromium.ui.widget.AnchoredPopupWindow; import org.chromium.ui.widget.ChromeImageButton; @@ -27,6 +30,7 @@ * parameter in the XML layout of the ListMenuButton. The default content description that * corresponds to context.getString(R.string.accessibility_list_menu_button, "") is used otherwise. */ +@NullMarked public class ListMenuButton extends ChromeImageButton implements AnchoredPopupWindow.LayoutObserver { /** A listener that is notified when the popup menu is shown or dismissed. */ @@ -41,8 +45,11 @@ private final boolean mMenuHorizontalOverlapAnchor; private int mMenuMaxWidth; + + @SuppressWarnings("NullAway.Init") private AnchoredPopupWindow mPopupMenu; - private ListMenuButtonDelegate mDelegate; + + private @Nullable ListMenuButtonDelegate mDelegate; private ObserverList<PopupMenuShownListener> mPopupListeners = new ObserverList<>(); private boolean mTryToFitLargestItem; private boolean mPositionedAtEnd; @@ -141,6 +148,7 @@ } /** Init the popup window with provided attributes, called before {@link #showMenu()} */ + @NullUnmarked private void initPopupWindow() { if (mDelegate == null) throw new IllegalStateException("Delegate was not set.");
diff --git a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuButtonDelegate.java b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuButtonDelegate.java index 797c377..7d2ab505 100644 --- a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuButtonDelegate.java +++ b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuButtonDelegate.java
@@ -6,10 +6,12 @@ import android.view.View; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.widget.RectProvider; import org.chromium.ui.widget.ViewRectProvider; /** A delegate used to populate the menu. */ +@NullMarked public interface ListMenuButtonDelegate { /** * @param listMenuButton The anchor for the {@link ListMenu}.
diff --git a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemAdapter.java b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemAdapter.java index edd288de..2a844cb 100644 --- a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemAdapter.java +++ b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemAdapter.java
@@ -8,10 +8,12 @@ import android.view.ViewGroup; import android.widget.ListView; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.listmenu.BasicListMenu.ListMenuItemType; import org.chromium.ui.modelutil.ModelListAdapter; /** Default adapter for use with {@link ListMenu}. */ +@NullMarked public class ListMenuItemAdapter extends ModelListAdapter { public ListMenuItemAdapter(ModelList data) { super(data);
diff --git a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemProperties.java b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemProperties.java index 07dd225..36a1815 100644 --- a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemProperties.java +++ b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemProperties.java
@@ -8,6 +8,7 @@ import android.graphics.drawable.Drawable; import android.view.View; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel.ReadableBooleanPropertyKey; import org.chromium.ui.modelutil.PropertyModel.ReadableIntPropertyKey; @@ -19,6 +20,7 @@ * The properties controlling the state of the list menu items. Any given list item can have either * one start icon or one end icon but not both. */ +@NullMarked public class ListMenuItemProperties { // TODO(crbug.com/40738791): Consider passing menu item title through TITLE property instead of // TITLE_ID.
diff --git a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemViewBinder.java b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemViewBinder.java index 68703f9..4ceaaba8 100644 --- a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemViewBinder.java +++ b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemViewBinder.java
@@ -11,11 +11,13 @@ import android.widget.TextView; import androidx.annotation.ColorRes; -import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.widget.ImageViewCompat; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; @@ -30,8 +32,11 @@ * As for when a list item contains an icon, it is expected that it either has a start icon * OR an end icon, not both. */ +@NullMarked public class ListMenuItemViewBinder { - public static void binder(PropertyModel model, View view, PropertyKey propertyKey) { + @NullUnmarked + public static void binder( + PropertyModel model, @Nullable View view, @Nullable PropertyKey propertyKey) { TextView textView = view.findViewById(R.id.menu_item_text); ImageView startIcon = view.findViewById(R.id.menu_item_icon); ImageView endIcon = view.findViewById(R.id.menu_item_end_icon);
diff --git a/ui/android/java/src/org/chromium/ui/listmenu/ListSectionDividerProperties.java b/ui/android/java/src/org/chromium/ui/listmenu/ListSectionDividerProperties.java index b37e1e85..43b650c 100644 --- a/ui/android/java/src/org/chromium/ui/listmenu/ListSectionDividerProperties.java +++ b/ui/android/java/src/org/chromium/ui/listmenu/ListSectionDividerProperties.java
@@ -4,10 +4,12 @@ package org.chromium.ui.listmenu; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey; /** Properties for customizing the list section divider. */ +@NullMarked public class ListSectionDividerProperties { public static final WritableIntPropertyKey LEFT_PADDING_DIMEN_ID = new WritableIntPropertyKey(); public static final WritableIntPropertyKey RIGHT_PADDING_DIMEN_ID =
diff --git a/ui/android/java/src/org/chromium/ui/listmenu/ListSectionDividerViewBinder.java b/ui/android/java/src/org/chromium/ui/listmenu/ListSectionDividerViewBinder.java index 1b48de4..76909ce3 100644 --- a/ui/android/java/src/org/chromium/ui/listmenu/ListSectionDividerViewBinder.java +++ b/ui/android/java/src/org/chromium/ui/listmenu/ListSectionDividerViewBinder.java
@@ -9,6 +9,7 @@ import androidx.annotation.DimenRes; import androidx.annotation.Px; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; @@ -16,6 +17,7 @@ * Class responsible for binding the list section divider. This is primarily needed to enable * customization of the list section divider. */ +@NullMarked public class ListSectionDividerViewBinder { public static void bind(PropertyModel model, View view, PropertyKey propertyKey) {
diff --git a/ui/android/java/src/org/chromium/ui/modaldialog/DialogDismissalCause.java b/ui/android/java/src/org/chromium/ui/modaldialog/DialogDismissalCause.java index b309d85..775b637 100644 --- a/ui/android/java/src/org/chromium/ui/modaldialog/DialogDismissalCause.java +++ b/ui/android/java/src/org/chromium/ui/modaldialog/DialogDismissalCause.java
@@ -6,6 +6,8 @@ import androidx.annotation.IntDef; +import org.chromium.build.annotations.NullMarked; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -30,6 +32,7 @@ DialogDismissalCause.CLIENT_TIMEOUT }) @Retention(RetentionPolicy.SOURCE) +@NullMarked public @interface DialogDismissalCause { // Dismissal causes that are fully controlled by clients (i.e. are not used inside the // dialog manager or the dialog presenters) are marked "Controlled by client" on comments.
diff --git a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManager.java b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManager.java index ebc46f239..afc361e 100644 --- a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManager.java +++ b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManager.java
@@ -9,13 +9,14 @@ import androidx.activity.ComponentDialog; import androidx.annotation.IntDef; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import org.chromium.base.Callback; import org.chromium.base.CommandLine; import org.chromium.base.ObserverList; import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.InsetObserver; import org.chromium.ui.UiSwitches; import org.chromium.ui.modelutil.PropertyModel; @@ -30,6 +31,7 @@ import java.util.Set; /** Manager for managing the display of a queue of {@link PropertyModel}s. */ +@NullMarked public class ModalDialogManager { /** * An observer of the ModalDialogManager intended to broadcast notifications about any dialog @@ -80,8 +82,8 @@ /** Present a {@link PropertyModel} in a container. */ public abstract static class Presenter { - private Callback<Integer> mDismissCallback; - private PropertyModel mDialogModel; + private @Nullable Callback<Integer> mDismissCallback; + private @Nullable PropertyModel mDialogModel; /** * @param model The dialog model that's currently showing in this presenter. If null, no @@ -119,7 +121,7 @@ /** * @return The dialog model that this presenter is showing. */ - public final PropertyModel getDialogModel() { + public final @Nullable PropertyModel getDialogModel() { return mDialogModel; } @@ -154,7 +156,7 @@ * * @param model The dialog model that needs to be removed. */ - protected abstract void removeDialogView(PropertyModel model); + protected abstract void removeDialogView(@Nullable PropertyModel model); /** * An {@link InsetObserver} to get insets for the window associated with a modal dialog. @@ -244,7 +246,7 @@ * The presenter of the type of the dialog that is currently showing. Note that if there is no * matching {@link Presenter} for {@link #mCurrentType}, this will be the default presenter. */ - private Presenter mCurrentPresenter; + private @Nullable Presenter mCurrentPresenter; /** * The type of the current dialog. This can be different from the type of the current @@ -258,7 +260,7 @@ /** True if the current dialog is in the process of being dismissed. */ private boolean mDismissingCurrentDialog; - private ModalDialogManagerBridge mModalDialogManagerBridge; + private @Nullable ModalDialogManagerBridge mModalDialogManagerBridge; private boolean mDestroyed; @@ -275,10 +277,10 @@ private final PendingDialogContainer mPendingDialogContainer = new PendingDialogContainer(); /** An {@link InsetObserver} to provide system window insets. */ - private InsetObserver mInsetObserver; + private @Nullable InsetObserver mInsetObserver; /** A supplier to determine whether edge-to-edge is active in the enclosing window. */ - private final ObservableSupplier<Boolean> mEdgeToEdgeStateSupplier; + private final @Nullable ObservableSupplier<Boolean> mEdgeToEdgeStateSupplier; /** * Constructor for initializing default {@link Presenter}. TODO (crbug.com/41492646): Remove @@ -287,8 +289,7 @@ * @param defaultPresenter The default presenter to be used when no presenter specified. * @param defaultType The dialog type of the default presenter. */ - public ModalDialogManager( - @NonNull Presenter defaultPresenter, @ModalDialogType int defaultType) { + public ModalDialogManager(Presenter defaultPresenter, @ModalDialogType int defaultType) { this(defaultPresenter, defaultType, /* edgeToEdgeStateSupplier= */ null); } @@ -303,9 +304,9 @@ * applicable. */ public ModalDialogManager( - @NonNull Presenter defaultPresenter, + Presenter defaultPresenter, @ModalDialogType int defaultType, - ObservableSupplier<Boolean> edgeToEdgeStateSupplier) { + @Nullable ObservableSupplier<Boolean> edgeToEdgeStateSupplier) { mDefaultPresenter = defaultPresenter; mEdgeToEdgeStateSupplier = edgeToEdgeStateSupplier; registerPresenter(defaultPresenter, defaultType); @@ -513,7 +514,8 @@ * @param dismissalCause The {@link DialogDismissalCause} that describes why the dialog is * dismissed. */ - public void dismissDialog(PropertyModel model, @DialogDismissalCause int dismissalCause) { + public void dismissDialog( + @Nullable PropertyModel model, @DialogDismissalCause int dismissalCause) { if (model == null) return; if (dismissalCause == DialogDismissalCause.NAVIGATE_BACK_OR_TOUCH_OUTSIDE) { assert mCurrentType == ModalDialogType.APP; @@ -553,6 +555,7 @@ * @param dismissalCause The {@link DialogDismissalCause} that describes why the dialogs are * dismissed. */ + @NullUnmarked public void dismissAllDialogs(@DialogDismissalCause int dismissalCause) { for (@ModalDialogType int dialogType = ModalDialogType.RANGE_MIN; dialogType <= ModalDialogType.RANGE_MAX; @@ -586,6 +589,7 @@ * dismissed. * @return true if a dialog was showing and was dismissed. */ + @NullUnmarked public boolean dismissActiveDialogOfType( @ModalDialogType int dialogType, @DialogDismissalCause int dismissalCause) { if (isShowing() && dialogType == mCurrentType) { @@ -621,6 +625,7 @@ * @param dialogType The specified type of dialogs to be suspended. * @return A token to use when resuming the suspended type. */ + @NullUnmarked public int suspendType(@ModalDialogType int dialogType) { mSuspendedTypes.add(dialogType); if (isShowing() @@ -638,6 +643,7 @@ * @param dialogType The specified type of dialogs to be resumed. * @param token The token generated from suspending the dialog type. */ + @NullUnmarked public void resumeType(@ModalDialogType int dialogType, int token) { mTokenHolders.get(dialogType).releaseToken(token); } @@ -657,6 +663,7 @@ * * @param dialogType The specified type of dialogs to be resumed. */ + @NullUnmarked private void resumeTypeInternal(@ModalDialogType int dialogType) { if (mTokenHolders.get(dialogType).hasTokens()) return; mSuspendedTypes.remove(dialogType); @@ -664,6 +671,7 @@ } /** Hide the current dialog and put it back to the front of the pending list. */ + @NullUnmarked private void suspendCurrentDialog() { assert isShowing(); PropertyModel dialogView = mCurrentPresenter.getDialogModel(); @@ -702,7 +710,7 @@ } } - public PropertyModel getCurrentDialogForTest() { + public @Nullable PropertyModel getCurrentDialogForTest() { return mCurrentPresenter == null ? null : mCurrentPresenter.getDialogModel(); } @@ -715,6 +723,7 @@ return mPresenters.get(dialogType); } + @NullUnmarked public Presenter getCurrentPresenterForTest() { return mCurrentPresenter; }
diff --git a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManagerBridge.java b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManagerBridge.java index 2fa6cf6..8bfbd1d 100644 --- a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManagerBridge.java +++ b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManagerBridge.java
@@ -4,22 +4,22 @@ package org.chromium.ui.modaldialog; -import androidx.annotation.NonNull; - import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.ModalDialogWrapper; import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; @JNINamespace("ui") +@NullMarked public class ModalDialogManagerBridge { private final ModalDialogManager mModalDialogManager; private long mNativePtr; - public ModalDialogManagerBridge(@NonNull ModalDialogManager manager) { + public ModalDialogManagerBridge(ModalDialogManager manager) { mModalDialogManager = manager; mNativePtr = ModalDialogManagerBridgeJni.get().create(this); }
diff --git a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManagerHolder.java b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManagerHolder.java index 57708147..780a85f 100644 --- a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManagerHolder.java +++ b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogManagerHolder.java
@@ -4,7 +4,10 @@ package org.chromium.ui.modaldialog; +import org.chromium.build.annotations.NullMarked; + /** Classes that hold an instance of {@link ModalDialogManager} should implement this interface. */ +@NullMarked public interface ModalDialogManagerHolder { /** * @return The {@link ModalDialogManager} associated with this class
diff --git a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogProperties.java b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogProperties.java index ce499691..2c1bdd6 100644 --- a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogProperties.java +++ b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogProperties.java
@@ -10,6 +10,7 @@ import androidx.activity.OnBackPressedCallback; import androidx.annotation.IntDef; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel.ReadableBooleanPropertyKey; @@ -24,6 +25,7 @@ import java.lang.annotation.RetentionPolicy; /** The model properties for a modal dialog. */ +@NullMarked public class ModalDialogProperties { /** Interface that controls the actions on the modal dialog. */ public interface Controller {
diff --git a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogUtils.java b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogUtils.java index 77f187c..87eeed54 100644 --- a/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogUtils.java +++ b/ui/android/java/src/org/chromium/ui/modaldialog/ModalDialogUtils.java
@@ -8,12 +8,14 @@ import androidx.annotation.StringRes; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; import org.chromium.ui.modaldialog.ModalDialogProperties.ButtonStyles; import org.chromium.ui.modaldialog.ModalDialogProperties.ButtonType; import org.chromium.ui.modelutil.PropertyModel; /** Set of shared helper functions for using {@link ModalDialogManager}. */ +@NullMarked public final class ModalDialogUtils { /** Do not allow instantiation for utils class. */ private ModalDialogUtils() {}
diff --git a/ui/android/java/src/org/chromium/ui/modaldialog/PendingDialogContainer.java b/ui/android/java/src/org/chromium/ui/modaldialog/PendingDialogContainer.java index dd1b878..2ab87547 100644 --- a/ui/android/java/src/org/chromium/ui/modaldialog/PendingDialogContainer.java +++ b/ui/android/java/src/org/chromium/ui/modaldialog/PendingDialogContainer.java
@@ -4,8 +4,8 @@ package org.chromium.ui.modaldialog; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogPriority; import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; import org.chromium.ui.modelutil.PropertyModel; @@ -22,6 +22,7 @@ * A container class to provide basic operations for pending dialogs with attributes {@link * ModalDialogType} and {@link ModalDialogPriority}. */ +@NullMarked class PendingDialogContainer { /** A class representing the attributes of a pending dialog. */ static class PendingDialogType { @@ -75,7 +76,7 @@ void put( @ModalDialogType int dialogType, @ModalDialogPriority int dialogPriority, - PropertyModel model, + @Nullable PropertyModel model, boolean showAsNext) { Integer key = computeKey(dialogType, dialogPriority); List<PropertyModel> dialogs = mPendingDialogs.get(key);
diff --git a/ui/android/java/src/org/chromium/ui/modaldialog/SimpleModalDialogController.java b/ui/android/java/src/org/chromium/ui/modaldialog/SimpleModalDialogController.java index f7210b4e..0540448 100644 --- a/ui/android/java/src/org/chromium/ui/modaldialog/SimpleModalDialogController.java +++ b/ui/android/java/src/org/chromium/ui/modaldialog/SimpleModalDialogController.java
@@ -4,9 +4,10 @@ package org.chromium.ui.modaldialog; -import androidx.annotation.NonNull; - import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.modelutil.PropertyModel; /** @@ -14,16 +15,17 @@ * * The result of the dialog is passed back via a Callback. */ +@NullMarked public class SimpleModalDialogController implements ModalDialogProperties.Controller { private final ModalDialogManager mModalDialogManager; - private Callback<Integer> mActionCallback; + private @Nullable Callback<Integer> mActionCallback; /** * @param modalDialogManager the dialog manager where the dialog will be shown. * @param action a callback which will be run with the result of the confirmation. */ public SimpleModalDialogController( - ModalDialogManager modalDialogManager, @NonNull Callback<Integer> action) { + ModalDialogManager modalDialogManager, Callback<Integer> action) { mModalDialogManager = modalDialogManager; mActionCallback = action; } @@ -37,6 +39,7 @@ } } + @NullUnmarked @Override public void onDismiss(PropertyModel model, int dismissalCause) { Callback<Integer> action = mActionCallback;
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/ForwardingListObservable.java b/ui/android/java/src/org/chromium/ui/modelutil/ForwardingListObservable.java index 3faad27..8767384 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/ForwardingListObservable.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/ForwardingListObservable.java
@@ -3,7 +3,8 @@ // found in the LICENSE file. package org.chromium.ui.modelutil; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * Helper class for implementing a {@link ListObserver} that just forwards to its own observers. @@ -12,6 +13,7 @@ * partial updates. TODO(bauerb): Remove this class if it turns out we can shortcut * notifications */ +@NullMarked public class ForwardingListObservable<P> extends ListObservableImpl<P> implements ListObservable.ListObserver<P> { @Override
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/LayoutViewBuilder.java b/ui/android/java/src/org/chromium/ui/modelutil/LayoutViewBuilder.java index 52b9825a..dd6e4a0 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/LayoutViewBuilder.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/LayoutViewBuilder.java
@@ -10,12 +10,15 @@ import androidx.annotation.LayoutRes; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.modelutil.MVCListAdapter.ViewBuilder; /** Helper class that inflates view from XML layout. */ +@NullMarked public class LayoutViewBuilder<T extends View> implements ViewBuilder<T> { @LayoutRes private final int mLayoutResId; - private LayoutInflater mInflater; + private @Nullable LayoutInflater mInflater; public LayoutViewBuilder(@LayoutRes int res) { mLayoutResId = res;
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/LazyConstructionPropertyMcp.java b/ui/android/java/src/org/chromium/ui/modelutil/LazyConstructionPropertyMcp.java index 7d20beb..7473abf 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/LazyConstructionPropertyMcp.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/LazyConstructionPropertyMcp.java
@@ -4,8 +4,8 @@ package org.chromium.ui.modelutil; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.ViewProvider; import java.util.HashSet; @@ -19,6 +19,7 @@ * @param <V> The view type * @param <P> The property type for the model */ +@NullMarked public class LazyConstructionPropertyMcp<M extends PropertyObservable<P>, V, P> implements PropertyObservable.PropertyObserver<P> { /**
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/ListModel.java b/ui/android/java/src/org/chromium/ui/modelutil/ListModel.java index 11ba6d0..330e304 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/ListModel.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/ListModel.java
@@ -3,6 +3,8 @@ // found in the LICENSE file. package org.chromium.ui.modelutil; +import org.chromium.build.annotations.NullMarked; + /** * Base class for a {@link ListObservable} containing a {@link SimpleList} of items. * It allows models to compose different ListObservables. @@ -11,4 +13,5 @@ * support partial change notification. * @param <T> The object type that this class manages in a list. */ +@NullMarked public class ListModel<T> extends ListModelBase<T, Void> {}
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/ListModelBase.java b/ui/android/java/src/org/chromium/ui/modelutil/ListModelBase.java index 31cea15..63a0936 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/ListModelBase.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/ListModelBase.java
@@ -4,7 +4,7 @@ package org.chromium.ui.modelutil; -import androidx.annotation.NonNull; +import org.chromium.build.annotations.NullMarked; import java.util.ArrayList; import java.util.Arrays; @@ -20,6 +20,7 @@ * @param <T> The object type that this class manages in a list. * @param <P> The payload type for partial change notifications. */ +@NullMarked public class ListModelBase<T, P> extends ListObservableImpl<P> implements SimpleList<T> { private final List<T> mItems = new ArrayList<>(); @@ -38,7 +39,6 @@ return mItems.size(); } - @NonNull @Override public Iterator<T> iterator() { return mItems.iterator();
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/ListModelChangeProcessor.java b/ui/android/java/src/org/chromium/ui/modelutil/ListModelChangeProcessor.java index 9a35cb8..0211e16 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/ListModelChangeProcessor.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/ListModelChangeProcessor.java
@@ -4,7 +4,8 @@ package org.chromium.ui.modelutil; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * A model change processor for use with a {@link ListObservable} model. The @@ -18,6 +19,7 @@ * @param <V> The view object that is changing. * @param <P> The payload for partial updates. Void can be used if a payload is not needed. */ +@NullMarked public class ListModelChangeProcessor<M extends ListObservable<P>, V, P> implements ListObservable.ListObserver<P> { /** @@ -34,7 +36,7 @@ void onItemsRemoved(M model, V view, int index, int count); - void onItemsChanged(M model, V view, int index, int count, P payload); + void onItemsChanged(M model, V view, int index, int count, @Nullable P payload); } private final V mView;
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/ListObservable.java b/ui/android/java/src/org/chromium/ui/modelutil/ListObservable.java index 4cdb356d..004e525d 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/ListObservable.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/ListObservable.java
@@ -3,7 +3,8 @@ // found in the LICENSE file. package org.chromium.ui.modelutil; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * An interface for models notifying about changes to a list of items. Note that ListObservable @@ -16,6 +17,7 @@ * @param <P> The parameter type for the payload for partial updates. Use {@link Void} for * implementations that don't support partial updates. */ +@NullMarked public interface ListObservable<P> { /** * @param observer An observer to be notified of changes to the model.
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/ListObservableImpl.java b/ui/android/java/src/org/chromium/ui/modelutil/ListObservableImpl.java index 5c79e5b..a4f14c0 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/ListObservableImpl.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/ListObservableImpl.java
@@ -4,9 +4,9 @@ package org.chromium.ui.modelutil; -import androidx.annotation.Nullable; - import org.chromium.base.ObserverList; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * Helper class for implementations of {@link ListObservable}, with some convenience methods for @@ -14,6 +14,7 @@ * @param <P> The parameter type for the payload for partial updates. Use {@link Void} for * implementations that don't support partial updates. */ +@NullMarked public abstract class ListObservableImpl<P> implements ListObservable<P> { private final ObserverList<ListObserver<P>> mObservers = new ObserverList<>();
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/MVCListAdapter.java b/ui/android/java/src/org/chromium/ui/modelutil/MVCListAdapter.java index 1ba7325..03d87738 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/MVCListAdapter.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/MVCListAdapter.java
@@ -7,8 +7,7 @@ import android.view.View; import android.view.ViewGroup; -import androidx.annotation.NonNull; - +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.modelutil.PropertyModelChangeProcessor.ViewBinder; /** @@ -18,6 +17,7 @@ * different types of views that can be shown by the list, i.e.: * {@link #registerType(int, ViewBuilder, ViewBinder)}. */ +@NullMarked public interface MVCListAdapter { /** A basic container for {@link PropertyModel}s with a type. */ class ListItem { @@ -50,7 +50,7 @@ * @param parent Parent view. * @return A new view to show in the list. */ - T buildView(@NonNull ViewGroup parent); + T buildView(ViewGroup parent); } /**
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/ModelListAdapter.java b/ui/android/java/src/org/chromium/ui/modelutil/ModelListAdapter.java index 0b8819a3..c7b9978 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/ModelListAdapter.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/ModelListAdapter.java
@@ -10,9 +10,10 @@ import android.view.ViewGroup; import android.widget.BaseAdapter; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; import org.chromium.ui.modelutil.ListObservable.ListObserver; import org.chromium.ui.modelutil.PropertyModelChangeProcessor.ViewBinder; @@ -37,6 +38,7 @@ * Additionally, ModelListAdapter will hook up a {@link PropertyModelChangeProcessor} when binding * views to ensure that changes to the PropertyModel for that list item are bound to the view. */ +@NullMarked public class ModelListAdapter extends BaseAdapter implements MVCListAdapter { private final ModelList mModelList; private final SparseArray<Pair<ViewBuilder, ViewBinder>> mViewBuilderMap = new SparseArray<>();
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/ModelListPropertyChangeFilter.java b/ui/android/java/src/org/chromium/ui/modelutil/ModelListPropertyChangeFilter.java index fb835e70..362c70ab 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/ModelListPropertyChangeFilter.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/ModelListPropertyChangeFilter.java
@@ -4,8 +4,8 @@ package org.chromium.ui.modelutil; -import androidx.annotation.NonNull; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.modelutil.ListObservable.ListObserver; import org.chromium.ui.modelutil.MVCListAdapter.ListItem; import org.chromium.ui.modelutil.MVCListAdapter.ModelList; @@ -19,6 +19,7 @@ * Observes and notifies when any of the filtered {@link PropertyKey}s are changed inside the * {@link ModelList}. */ +@NullMarked public class ModelListPropertyChangeFilter implements ListObserver<Void>, PropertyObserver<PropertyKey> { private final Runnable mOnPropertyChange; @@ -67,7 +68,8 @@ } @Override - public void onPropertyChanged(PropertyObservable<PropertyKey> source, PropertyKey propertyKey) { + public void onPropertyChanged( + PropertyObservable<PropertyKey> source, @Nullable PropertyKey propertyKey) { if (mPropertyKeySet.contains(propertyKey)) { mOnPropertyChange.run(); } @@ -88,7 +90,7 @@ * set and the new set, and call {@link PropertyModel#removeObserver(PropertyObserver)} on any * we figure out have been removed. */ - private void prunePropertyModels(@NonNull Set<PropertyModel> newPropertyModels) { + private void prunePropertyModels(Set<PropertyModel> newPropertyModels) { for (PropertyModel existingPropertyModel : mTrackedPropertyModels) { if (!newPropertyModels.contains(existingPropertyModel)) { existingPropertyModel.removeObserver(this);
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/PropertyKey.java b/ui/android/java/src/org/chromium/ui/modelutil/PropertyKey.java index 73fa74a..0063818 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/PropertyKey.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/PropertyKey.java
@@ -3,8 +3,11 @@ // found in the LICENSE file. package org.chromium.ui.modelutil; +import org.chromium.build.annotations.NullMarked; + /** * Place holder interface to allow key definitions. Should not be used directly and only exposed to * allow use as generic placeholders. */ +@NullMarked public interface PropertyKey {}
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/PropertyListModel.java b/ui/android/java/src/org/chromium/ui/modelutil/PropertyListModel.java index 9166ad45..5d0b769 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/PropertyListModel.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/PropertyListModel.java
@@ -4,7 +4,8 @@ package org.chromium.ui.modelutil; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.Collection; @@ -14,6 +15,7 @@ * @param <T> The type of item in the list. * @param <P> The property key type for {@code T} to be used as payload for partial updates. */ +@NullMarked public class PropertyListModel<T extends PropertyObservable<P>, P> extends ListModelBase<T, P> { private final PropertyObservable.PropertyObserver<P> mPropertyObserver = this::onPropertyChanged;
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/PropertyModel.java b/ui/android/java/src/org/chromium/ui/modelutil/PropertyModel.java index b7691d4a..fbd0876 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/PropertyModel.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/PropertyModel.java
@@ -9,13 +9,14 @@ import android.graphics.drawable.Drawable; import androidx.annotation.DrawableRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.util.ObjectsCompat; import org.chromium.build.BuildConfig; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; @@ -27,10 +28,11 @@ /** * Generic property model that aims to provide an extensible and efficient model for ease of use. */ +@NullMarked public class PropertyModel extends PropertyObservable<PropertyKey> { /** A PropertyKey implementation that associates a name with the property for easy debugging. */ private static class NamedPropertyKey implements PropertyKey { - private final String mPropertyName; + private final @Nullable String mPropertyName; public NamedPropertyKey(@Nullable String propertyName) { mPropertyName = propertyName; @@ -246,7 +248,7 @@ */ public static class ReadableTransformingObjectPropertyKey<T, V> extends NamedPropertyKey { /** Constructor for a named {@link ReadableTransformingObjectPropertyKey}. */ - public ReadableTransformingObjectPropertyKey(String name) { + public ReadableTransformingObjectPropertyKey(@Nullable String name) { super(name); } @@ -266,7 +268,7 @@ public static final class WritableTransformingObjectPropertyKey<T, V> extends ReadableTransformingObjectPropertyKey<T, V> { /** Constructor for a named {@link WritableTransformingObjectPropertyKey}. */ - public WritableTransformingObjectPropertyKey(String name) { + public WritableTransformingObjectPropertyKey(@Nullable String name) { super(name); } @@ -277,7 +279,8 @@ } private final Map<PropertyKey, ValueContainer> mData; - private final Map<ReadableTransformingObjectPropertyKey<?, ?>, Function<?, ?>> mTransformers; + private final @Nullable Map<ReadableTransformingObjectPropertyKey<?, ?>, Function<?, ?>> + mTransformers; /** * Constructs a model for the given list of keys. @@ -303,7 +306,8 @@ private PropertyModel( Map<PropertyKey, ValueContainer> startingValues, - Map<ReadableTransformingObjectPropertyKey<?, ?>, Function<?, ?>> transformers) { + @Nullable + Map<ReadableTransformingObjectPropertyKey<?, ?>, Function<?, ?>> transformers) { mData = startingValues; mTransformers = transformers; } @@ -408,6 +412,7 @@ } /** Get the current value from the object based key. */ + @NullUnmarked @SuppressWarnings("unchecked") public <T> T get(ReadableObjectPropertyKey<T> key) { validateKey(key); @@ -432,8 +437,9 @@ } /** Get the transformed value from the current value of an object based key. */ + @NullUnmarked @SuppressWarnings("unchecked") - public <T, V> V get(ReadableTransformingObjectPropertyKey<T, V> key) { + public <T, V> @Nullable V get(ReadableTransformingObjectPropertyKey<T, V> key) { validateKey(key); ObjectContainer<T> container = (ObjectContainer<T>) mData.get(key); Function<T, V> transformer = (Function<T, V>) mTransformers.get(key); @@ -505,9 +511,7 @@ * @return The value from the model or the default if the value is not found. */ public static int getFromModelOrDefault( - @NonNull PropertyModel model, - @NonNull PropertyModel.ReadableIntPropertyKey key, - int defaultValue) { + PropertyModel model, PropertyModel.ReadableIntPropertyKey key, int defaultValue) { // We need to check first because PropertyModel#get throws an exception if a key // is not present in the Map. if (model.containsKey(key)) { @@ -525,10 +529,9 @@ * @param defaultValue The default value if the the property is not found. * @return The value from the model or the default if the value is not found. */ - @Nullable - public static <T> T getFromModelOrDefault( - @NonNull PropertyModel model, - @NonNull PropertyModel.ReadableObjectPropertyKey<T> key, + public static <T> @Nullable T getFromModelOrDefault( + PropertyModel model, + PropertyModel.ReadableObjectPropertyKey<T> key, @Nullable T defaultValue) { // We need to check first because PropertyModel#get throws an exception if a key // is not present in the Map. @@ -541,7 +544,8 @@ /** Allows constructing a new {@link PropertyModel} with read-only properties. */ public static class Builder { private final Map<PropertyKey, ValueContainer> mData; - private Map<ReadableTransformingObjectPropertyKey<?, ?>, Function<?, ?>> mTransformers; + private @Nullable Map<ReadableTransformingObjectPropertyKey<?, ?>, Function<?, ?>> + mTransformers; public Builder(PropertyKey... keys) { this(buildData(keys)); @@ -589,7 +593,7 @@ return this; } - public <T> Builder with(ReadableObjectPropertyKey<T> key, T value) { + public <T> Builder with(ReadableObjectPropertyKey<T> key, @Nullable T value) { validateKey(key); ObjectContainer<T> container = new ObjectContainer<>(); container.value = value; @@ -763,7 +767,7 @@ } private static class ObjectContainer<T> extends ValueContainer { - public T value; + public @Nullable T value; @Override public String toString() {
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/PropertyModelAnimatorFactory.java b/ui/android/java/src/org/chromium/ui/modelutil/PropertyModelAnimatorFactory.java index 1f62b419..0a836d8 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/PropertyModelAnimatorFactory.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/PropertyModelAnimatorFactory.java
@@ -7,12 +7,14 @@ import android.animation.ObjectAnimator; import android.util.FloatProperty; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.modelutil.PropertyModel.WritableFloatPropertyKey; /** * Static factory class that creates Animators for MVC properties by providing implementations of * android.util.Property that mutate a given property in a given model. */ +@NullMarked public class PropertyModelAnimatorFactory { /** * Builds an Animator for the given model, key, and target value.
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/PropertyModelChangeProcessor.java b/ui/android/java/src/org/chromium/ui/modelutil/PropertyModelChangeProcessor.java index 5ad37f2..69f810fe 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/PropertyModelChangeProcessor.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/PropertyModelChangeProcessor.java
@@ -4,6 +4,8 @@ package org.chromium.ui.modelutil; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.modelutil.PropertyObservable.PropertyObserver; /** @@ -14,6 +16,7 @@ * @param <V> The view object that is changing. * @param <P> The property of the view that changed. */ +@NullMarked public class PropertyModelChangeProcessor<M extends PropertyObservable<P>, V, P> { /** * A generic view binder that associates a view with a model. @@ -23,7 +26,7 @@ * @param <P> The property of the view that changed. */ public interface ViewBinder<M, V, P> { - void bind(M model, V view, P propertyKey); + void bind(M model, @Nullable V view, @Nullable P propertyKey); } private final V mView; @@ -87,7 +90,7 @@ mModel.removeObserver(mPropertyObserver); } - private void onPropertyChanged(PropertyObservable<P> source, P propertyKey) { + private void onPropertyChanged(PropertyObservable<P> source, @Nullable P propertyKey) { assert source == mModel; // TODO(bauerb): Add support for batching updates.
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/PropertyObservable.java b/ui/android/java/src/org/chromium/ui/modelutil/PropertyObservable.java index 9e79030..49dd0cf4 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/PropertyObservable.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/PropertyObservable.java
@@ -4,9 +4,9 @@ package org.chromium.ui.modelutil; -import androidx.annotation.Nullable; - import org.chromium.base.ObserverList; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.Collection; @@ -15,6 +15,7 @@ * * @param <T> The type of the property key used for uniquely identifying properties. */ +@NullMarked public abstract class PropertyObservable<T> { /** * An observer to be notified of changes to a {@link PropertyObservable}.
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/RecyclerViewAdapter.java b/ui/android/java/src/org/chromium/ui/modelutil/RecyclerViewAdapter.java index 4433ccf..c1ff817f 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/RecyclerViewAdapter.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/RecyclerViewAdapter.java
@@ -6,10 +6,12 @@ import android.view.ViewGroup; -import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView.ViewHolder; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + import java.util.List; /** @@ -21,6 +23,7 @@ * @param <P> The payload type for partial updates, or {@link Void} if the adapter does not support * partial updates. */ +@NullMarked public class RecyclerViewAdapter<VH extends ViewHolder, P> extends RecyclerView.Adapter<VH> implements ListObservable.ListObserver<P> { /**
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/SimpleList.java b/ui/android/java/src/org/chromium/ui/modelutil/SimpleList.java index 5b0133b..b4d64e6 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/SimpleList.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/SimpleList.java
@@ -3,7 +3,7 @@ // found in the LICENSE file. package org.chromium.ui.modelutil; -import androidx.annotation.NonNull; +import org.chromium.build.annotations.NullMarked; import java.util.AbstractList; import java.util.Iterator; @@ -14,6 +14,7 @@ * classes that already extend another class and therefore can't inherit from {@link AbstractList}. * @param <T> The type of list item. */ +@NullMarked public interface SimpleList<T> extends Iterable<T> { /** * @return The size of the list. @@ -34,7 +35,6 @@ * modifications and does not check whether the underlying list is being modified. */ @Override - @NonNull default Iterator<T> iterator() { return new Iterator<T>() { private int mI;
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewAdapter.java b/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewAdapter.java index 7bdf96e0..6a5ab71 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewAdapter.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewAdapter.java
@@ -9,9 +9,10 @@ import android.view.View; import android.view.ViewGroup; -import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.modelutil.ListObservable.ListObserver; import org.chromium.ui.modelutil.PropertyModelChangeProcessor.ViewBinder; @@ -22,6 +23,7 @@ * adapter how to display a particular item. Updates to the {@link ListObservable} list provided in * the constructor will immediately be reflected in the list. */ +@NullMarked public class SimpleRecyclerViewAdapter extends RecyclerView.Adapter<SimpleRecyclerViewAdapter.ViewHolder> implements MVCListAdapter { @@ -30,13 +32,14 @@ */ public static class ViewHolder extends RecyclerView.ViewHolder { /** The model change processor currently associated with this view and model. */ - private PropertyModelChangeProcessor<PropertyModel, View, PropertyKey> mCurrentMcp; + private @Nullable PropertyModelChangeProcessor<PropertyModel, View, PropertyKey> + mCurrentMcp; /** The view binder that knows how to apply a model to the view this holder owns. */ private ViewBinder<PropertyModel, View, PropertyKey> mBinder; /** A handle to the model currently held by this view holder. */ - public PropertyModel model; + public @Nullable PropertyModel model; /** * @param itemView The view to manage. @@ -51,10 +54,10 @@ * Set the model for this view holder to manage. * @param model The model that should be bound to the view. */ - void setModel(PropertyModel model) { + void setModel(@Nullable PropertyModel model) { if (mCurrentMcp != null) mCurrentMcp.destroy(); this.model = model; - if (this.model == null) return; + if (model == null) return; mCurrentMcp = PropertyModelChangeProcessor.create(model, itemView, mBinder); } }
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcp.java b/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcp.java index 3cdbd33..215eacbe 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcp.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcp.java
@@ -3,9 +3,11 @@ // found in the LICENSE file. package org.chromium.ui.modelutil; -import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** * A model change processor (MCP), i.e. an implementation of {@link RecyclerViewAdapter.Delegate}, * which represents a homogeneous {@link SimpleList} of items that are independent of each other. @@ -13,6 +15,7 @@ * @param <T> The type of items in the list. * @param <VH> The view holder type that shows items. */ +@NullMarked public class SimpleRecyclerViewMcp<T, VH> extends SimpleRecyclerViewMcpBase<T, VH, Void> { /** * View binding interface.
diff --git a/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcpBase.java b/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcpBase.java index b8073af..e7ef787c 100644 --- a/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcpBase.java +++ b/ui/android/java/src/org/chromium/ui/modelutil/SimpleRecyclerViewMcpBase.java
@@ -4,9 +4,11 @@ package org.chromium.ui.modelutil; -import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** * A model change processor (MCP), i.e. an implementation of {@link RecyclerViewAdapter.Delegate}, * which represents a homogeneous {@link SimpleList} of items that are independent of each other. It @@ -17,10 +19,11 @@ * @param <P> The payload type for partial updates. If the model change processor doesn't support * partial updates, use the {@link SimpleRecyclerViewMcp} subclass. */ +@NullMarked public class SimpleRecyclerViewMcpBase<T, VH, P> extends ForwardingListObservable<P> implements RecyclerViewAdapter.Delegate<VH, P> { private final SimpleList<T> mModel; - private final ItemViewTypeCallback<T> mItemViewTypeCallback; + private final @Nullable ItemViewTypeCallback<T> mItemViewTypeCallback; private final ViewBinder<T, VH, P> mViewBinder; public SimpleRecyclerViewMcpBase(
diff --git a/ui/android/java/src/org/chromium/ui/permissions/ActivityAndroidPermissionDelegate.java b/ui/android/java/src/org/chromium/ui/permissions/ActivityAndroidPermissionDelegate.java index 3f0b77f..a2a1325 100644 --- a/ui/android/java/src/org/chromium/ui/permissions/ActivityAndroidPermissionDelegate.java +++ b/ui/android/java/src/org/chromium/ui/permissions/ActivityAndroidPermissionDelegate.java
@@ -6,9 +6,12 @@ import android.app.Activity; +import org.chromium.build.annotations.NullMarked; + import java.lang.ref.WeakReference; /** AndroidPermissionDelegate implementation for Activity. */ +@NullMarked public class ActivityAndroidPermissionDelegate extends AndroidPermissionDelegateWithRequester { private WeakReference<Activity> mActivity;
diff --git a/ui/android/java/src/org/chromium/ui/permissions/AndroidPermissionDelegate.java b/ui/android/java/src/org/chromium/ui/permissions/AndroidPermissionDelegate.java index f2ac40d..6541c62 100644 --- a/ui/android/java/src/org/chromium/ui/permissions/AndroidPermissionDelegate.java +++ b/ui/android/java/src/org/chromium/ui/permissions/AndroidPermissionDelegate.java
@@ -4,7 +4,10 @@ package org.chromium.ui.permissions; +import org.chromium.build.annotations.NullMarked; + /** Contains the functionality for interacting with the android permissions system. */ +@NullMarked public interface AndroidPermissionDelegate { /** * Determine whether access to a particular permission is granted.
diff --git a/ui/android/java/src/org/chromium/ui/permissions/AndroidPermissionDelegateWithRequester.java b/ui/android/java/src/org/chromium/ui/permissions/AndroidPermissionDelegateWithRequester.java index 9254eaa..74b52db3 100644 --- a/ui/android/java/src/org/chromium/ui/permissions/AndroidPermissionDelegateWithRequester.java +++ b/ui/android/java/src/org/chromium/ui/permissions/AndroidPermissionDelegateWithRequester.java
@@ -12,6 +12,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ContextUtils; +import org.chromium.build.annotations.NullMarked; import java.util.ArrayList; import java.util.HashMap; @@ -22,6 +23,7 @@ * AndroidPermissionDelegate that implements much of the logic around requesting permissions. * Subclasses need to implement only the basic permissions checking and requesting methods. */ +@NullMarked public abstract class AndroidPermissionDelegateWithRequester implements AndroidPermissionDelegate { private Handler mHandler; private SparseArray<PermissionRequestInfo> mOutstandingPermissionRequests;
diff --git a/ui/android/java/src/org/chromium/ui/permissions/ContextualNotificationPermissionRequester.java b/ui/android/java/src/org/chromium/ui/permissions/ContextualNotificationPermissionRequester.java index 2b41d034..760cc3ec 100644 --- a/ui/android/java/src/org/chromium/ui/permissions/ContextualNotificationPermissionRequester.java +++ b/ui/android/java/src/org/chromium/ui/permissions/ContextualNotificationPermissionRequester.java
@@ -4,7 +4,8 @@ package org.chromium.ui.permissions; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * Contains functionality to request Android notification permission contextually. This will result @@ -12,12 +13,12 @@ * the implementation provided from chrome layer. Internally delegates the permission request to * {@link NotificationPermissionController}. */ +@NullMarked public abstract class ContextualNotificationPermissionRequester { - private static ContextualNotificationPermissionRequester sInstance; + private static @Nullable ContextualNotificationPermissionRequester sInstance; /** @return The singleton instance of this class. */ - @Nullable - public static ContextualNotificationPermissionRequester getInstance() { + public static @Nullable ContextualNotificationPermissionRequester getInstance() { return sInstance; }
diff --git a/ui/android/java/src/org/chromium/ui/permissions/PermissionCallback.java b/ui/android/java/src/org/chromium/ui/permissions/PermissionCallback.java index 4e05e6b..ba908c1 100644 --- a/ui/android/java/src/org/chromium/ui/permissions/PermissionCallback.java +++ b/ui/android/java/src/org/chromium/ui/permissions/PermissionCallback.java
@@ -4,7 +4,10 @@ package org.chromium.ui.permissions; +import org.chromium.build.annotations.NullMarked; + /** Callback for permission requests. */ +@NullMarked public interface PermissionCallback { /** * Called upon completing a permission request.
diff --git a/ui/android/java/src/org/chromium/ui/permissions/PermissionPrefs.java b/ui/android/java/src/org/chromium/ui/permissions/PermissionPrefs.java index 87378537..7e903f1 100644 --- a/ui/android/java/src/org/chromium/ui/permissions/PermissionPrefs.java +++ b/ui/android/java/src/org/chromium/ui/permissions/PermissionPrefs.java
@@ -10,12 +10,14 @@ import org.chromium.base.ContextUtils; import org.chromium.base.TimeUtils; +import org.chromium.build.annotations.NullMarked; import java.util.List; /** * Provides helper methods for shared preference access to store permission request related info. */ +@NullMarked public class PermissionPrefs { /** * Shared preference key prefix for remembering Android permissions denied by the user.
diff --git a/ui/android/java/src/org/chromium/ui/resources/HandleViewResources.java b/ui/android/java/src/org/chromium/ui/resources/HandleViewResources.java index e1c9db5..bd6d9c77 100644 --- a/ui/android/java/src/org/chromium/ui/resources/HandleViewResources.java +++ b/ui/android/java/src/org/chromium/ui/resources/HandleViewResources.java
@@ -18,10 +18,13 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ContextUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; /** Helper class for retrieving resources related to selection handles. */ @JNINamespace("ui") +@NullMarked public class HandleViewResources { // Android handle drawables have a transparent horizontal padding, // which is one-fourth of the image. This variable is to take the @@ -40,19 +43,19 @@ android.R.attr.textSelectHandleRight, }; - public static Drawable getLeftHandleDrawable(Context context) { + public static @Nullable Drawable getLeftHandleDrawable(Context context) { return getHandleDrawable(context, LEFT_HANDLE_ATTRS); } - public static Drawable getCenterHandleDrawable(Context context) { + public static @Nullable Drawable getCenterHandleDrawable(Context context) { return getHandleDrawable(context, CENTER_HANDLE_ATTRS); } - public static Drawable getRightHandleDrawable(Context context) { + public static @Nullable Drawable getRightHandleDrawable(Context context) { return getHandleDrawable(context, RIGHT_HANDLE_ATTRS); } - private static Drawable getHandleDrawable(Context context, final int[] attrs) { + private static @Nullable Drawable getHandleDrawable(Context context, final int[] attrs) { TypedArray a = context.getTheme().obtainStyledAttributes(attrs); Drawable drawable = a.getDrawable(0); if (drawable == null) {
diff --git a/ui/android/java/src/org/chromium/ui/resources/LayoutResource.java b/ui/android/java/src/org/chromium/ui/resources/LayoutResource.java index fe521bd2..8d70957 100644 --- a/ui/android/java/src/org/chromium/ui/resources/LayoutResource.java +++ b/ui/android/java/src/org/chromium/ui/resources/LayoutResource.java
@@ -7,9 +7,11 @@ import android.graphics.Rect; import android.graphics.RectF; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.resources.statics.NinePatchData; /** A resource that provides sizing information for layouts. */ +@NullMarked public class LayoutResource { private final RectF mPadding; private final RectF mBitmapSize;
diff --git a/ui/android/java/src/org/chromium/ui/resources/Resource.java b/ui/android/java/src/org/chromium/ui/resources/Resource.java index 1247b2f25..6937157 100644 --- a/ui/android/java/src/org/chromium/ui/resources/Resource.java +++ b/ui/android/java/src/org/chromium/ui/resources/Resource.java
@@ -7,12 +7,15 @@ import android.graphics.Bitmap; import android.graphics.Rect; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.resources.statics.NinePatchData; /** * A basic resource interface that all assets must use to be exposed to the CC layer as * UIResourceIds. */ +@NullMarked public interface Resource { /** * This can only be called in @@ -44,6 +47,7 @@ * cases, this will be null. * @return The nine patch data for the bitmap or null. */ + @Nullable NinePatchData getNinePatchData(); /**
diff --git a/ui/android/java/src/org/chromium/ui/resources/ResourceFactory.java b/ui/android/java/src/org/chromium/ui/resources/ResourceFactory.java index 4c3da2b..dd17cb6 100644 --- a/ui/android/java/src/org/chromium/ui/resources/ResourceFactory.java +++ b/ui/android/java/src/org/chromium/ui/resources/ResourceFactory.java
@@ -9,12 +9,15 @@ import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.resources.statics.NinePatchData; /** A utility class for creating native resources. */ @JNINamespace("ui") +@NullMarked public class ResourceFactory { - public static long createBitmapResource(NinePatchData ninePatchData) { + public static long createBitmapResource(@Nullable NinePatchData ninePatchData) { return ninePatchData == null ? ResourceFactoryJni.get().createBitmapResource() : createNinePatchBitmapResource(
diff --git a/ui/android/java/src/org/chromium/ui/resources/ResourceLoader.java b/ui/android/java/src/org/chromium/ui/resources/ResourceLoader.java index 323752c..c8881ed 100644 --- a/ui/android/java/src/org/chromium/ui/resources/ResourceLoader.java +++ b/ui/android/java/src/org/chromium/ui/resources/ResourceLoader.java
@@ -4,7 +4,11 @@ package org.chromium.ui.resources; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** A class responsible for loading {@link Resource}s for the {@link ResourceManager}. */ +@NullMarked public abstract class ResourceLoader { /** * A callback that specifies when a {@link Resource} has been loaded and can be exposed to the @@ -19,7 +23,8 @@ * @param resource The {@link Resource} of the resource, or {@code null} if one could * not be loaded. */ - void onResourceLoaded(@AndroidResourceType int resType, int resId, Resource resource); + void onResourceLoaded( + @AndroidResourceType int resType, int resId, @Nullable Resource resource); /** * Called when a resource is unregistered (unneeded). This should only be called for @@ -73,7 +78,7 @@ * @param resId The id of the {@link Resource} that loaded or failed. * @param resource The {@link Resource}, or {@code null} if the load failed. */ - protected void notifyLoadFinished(int resId, Resource resource) { + protected void notifyLoadFinished(int resId, @Nullable Resource resource) { if (mCallback != null) mCallback.onResourceLoaded(getResourceType(), resId, resource); }
diff --git a/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java b/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java index bdd7d5e7..23ef753f 100644 --- a/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java +++ b/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java
@@ -13,6 +13,8 @@ import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.display.DisplayAndroid; import org.chromium.ui.resources.ResourceLoader.ResourceLoaderCallback; @@ -26,6 +28,7 @@ * This class does not hold any resource state, but passes it directly to native as they are loaded. */ @JNINamespace("ui") +@NullMarked public class ResourceManager implements ResourceLoaderCallback { private final SparseArray<ResourceLoader> mResourceLoaders = new SparseArray<ResourceLoader>(); private final SparseArray<SparseArray<LayoutResource>> mLoadedResources = @@ -117,14 +120,15 @@ * @param resId The id of the Android resource. * @return The corresponding {@link LayoutResource}. */ - public LayoutResource getResource(@AndroidResourceType int resType, int resId) { + public @Nullable LayoutResource getResource(@AndroidResourceType int resType, int resId) { SparseArray<LayoutResource> bucket = mLoadedResources.get(resType); return bucket != null ? bucket.get(resId) : null; } @SuppressWarnings("cast") @Override - public void onResourceLoaded(@AndroidResourceType int resType, int resId, Resource resource) { + public void onResourceLoaded( + @AndroidResourceType int resType, int resId, @Nullable Resource resource) { if (resource == null) return; Bitmap bitmap = resource.getBitmap(); if (bitmap == null) {
diff --git a/ui/android/java/src/org/chromium/ui/resources/async/AsyncPreloadResourceLoader.java b/ui/android/java/src/org/chromium/ui/resources/async/AsyncPreloadResourceLoader.java index 3895b8f..5bed797 100644 --- a/ui/android/java/src/org/chromium/ui/resources/async/AsyncPreloadResourceLoader.java +++ b/ui/android/java/src/org/chromium/ui/resources/async/AsyncPreloadResourceLoader.java
@@ -11,12 +11,16 @@ import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskRunner; import org.chromium.base.task.TaskTraits; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.resources.Resource; import org.chromium.ui.resources.ResourceLoader; import java.util.concurrent.ExecutionException; /** Handles loading Android resources from disk asynchronously and synchronously. */ +@NullMarked public class AsyncPreloadResourceLoader extends ResourceLoader { /** Responsible for actually creating a {@link Resource} from a specific resource id. */ public interface ResourceCreator { @@ -28,6 +32,7 @@ * @return A {@link Resource} instance that represents {@code resId} or {@code null} if * none can be loaded. */ + @Nullable Resource create(int resId); } @@ -91,7 +96,7 @@ mOutstandingLoads.put(resId, task); } - private Resource createResource(int resId) { + private @Nullable Resource createResource(int resId) { try { TraceEvent.begin("AsyncPreloadResourceLoader.createResource"); return mCreator.create(resId); @@ -100,7 +105,7 @@ } } - private void registerResource(Resource resource, int resourceId) { + private void registerResource(@Nullable Resource resource, int resourceId) { notifyLoadFinished(resourceId, resource); mOutstandingLoads.remove(resourceId); } @@ -112,13 +117,14 @@ mResourceId = resourceId; } + @NullUnmarked @Override - protected Resource doInBackground() { + protected @Nullable Resource doInBackground() { return createResource(mResourceId); } @Override - protected void onPostExecute(Resource resource) { + protected void onPostExecute(@Nullable Resource resource) { // If we've been removed from the list of outstanding load tasks, don't broadcast the // callback. if (mOutstandingLoads.get(mResourceId) == null) return;
diff --git a/ui/android/java/src/org/chromium/ui/resources/dynamics/BitmapDynamicResource.java b/ui/android/java/src/org/chromium/ui/resources/dynamics/BitmapDynamicResource.java index 5e639bd..e1f08bd 100644 --- a/ui/android/java/src/org/chromium/ui/resources/dynamics/BitmapDynamicResource.java +++ b/ui/android/java/src/org/chromium/ui/resources/dynamics/BitmapDynamicResource.java
@@ -9,13 +9,16 @@ import org.chromium.base.Callback; import org.chromium.base.ObserverList; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.resources.Resource; import org.chromium.ui.resources.ResourceFactory; /** A basic implementation of {@link DynamicResource} to handle updatable bitmaps. */ +@NullMarked public class BitmapDynamicResource implements DynamicResource { private final int mResId; - private Bitmap mBitmap; + private @Nullable Bitmap mBitmap; private final Rect mSize = new Rect(); private final ObserverList<Callback<Resource>> mOnResourceReadyObservers = new ObserverList<>();
diff --git a/ui/android/java/src/org/chromium/ui/resources/dynamics/CaptureObserver.java b/ui/android/java/src/org/chromium/ui/resources/dynamics/CaptureObserver.java index bb6d87f..5ac600c 100644 --- a/ui/android/java/src/org/chromium/ui/resources/dynamics/CaptureObserver.java +++ b/ui/android/java/src/org/chromium/ui/resources/dynamics/CaptureObserver.java
@@ -7,14 +7,18 @@ import android.graphics.Canvas; import android.graphics.Rect; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** Observer that's notified before and after a bitmap capture happens. */ +@NullMarked public interface CaptureObserver { /** * Called before the bitmap capture occurs. * @param canvas The {@link Canvas} that will be drawn to. * @param dirtyRect The dirty {@link Rect} or {@code null} if the entire area is being redrawn. */ - default void onCaptureStart(Canvas canvas, Rect dirtyRect) {} + default void onCaptureStart(Canvas canvas, @Nullable Rect dirtyRect) {} /** Called after bitmap capture occurs. */ default void onCaptureEnd() {}
diff --git a/ui/android/java/src/org/chromium/ui/resources/dynamics/CaptureUtils.java b/ui/android/java/src/org/chromium/ui/resources/dynamics/CaptureUtils.java index 8652fa7..805a445 100644 --- a/ui/android/java/src/org/chromium/ui/resources/dynamics/CaptureUtils.java +++ b/ui/android/java/src/org/chromium/ui/resources/dynamics/CaptureUtils.java
@@ -9,7 +9,10 @@ import android.graphics.Rect; import android.view.View; +import org.chromium.build.annotations.NullMarked; + /** Shared stateless capture utility functions. */ +@NullMarked public class CaptureUtils { /** Creates a bitmap with the given size. */ public static Bitmap createBitmap(int width, int height) {
diff --git a/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResource.java b/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResource.java index 80fe64f7..0038951 100644 --- a/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResource.java +++ b/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResource.java
@@ -5,6 +5,7 @@ package org.chromium.ui.resources.dynamics; import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.resources.Resource; /** @@ -13,6 +14,7 @@ * {@link DynamicResource} is in charge of tracking when it has changed and should actually be * returning a copy of itself. */ +@NullMarked public interface DynamicResource { /** * Will be called every render frame to notify the resource. The expectation is that this call
diff --git a/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceLoader.java b/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceLoader.java index fba4f0e..1ad8997f 100644 --- a/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceLoader.java +++ b/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceLoader.java
@@ -7,6 +7,8 @@ import android.util.SparseArray; import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.resources.Resource; import org.chromium.ui.resources.ResourceLoader; @@ -16,6 +18,7 @@ * render frames are happening, and hands the captured {@link org.chromium.ui.resources.Resource} * back in our {@link ResourceLoaderCallback}. */ +@NullMarked public class DynamicResourceLoader extends ResourceLoader { /** * Adapter for holding a callback and {@link DynamicResource}. The callback must be held so @@ -86,7 +89,7 @@ * @return The {@link DynamicResource} corresponding to the provided {@code resId}, or {@code * null} if no matching resource is found. */ - public DynamicResource getResource(int resId) { + public @Nullable DynamicResource getResource(int resId) { DynamicResourceHolder dynamicResourceHolder = mDynamicResourceHolders.get(resId); if (dynamicResourceHolder == null) return null; return dynamicResourceHolder.getDynamicResource();
diff --git a/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceReadyOnceCallback.java b/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceReadyOnceCallback.java index a11900c..b4a54d0 100644 --- a/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceReadyOnceCallback.java +++ b/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceReadyOnceCallback.java
@@ -5,9 +5,11 @@ package org.chromium.ui.resources.dynamics; import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.resources.Resource; /** A OnceCallback for observing the next {@link ViewResourceAdapter} produced {@link Resource}. */ +@NullMarked public class DynamicResourceReadyOnceCallback implements Callback<Resource> { private final DynamicResource mDynamicResource; private final Callback<Resource> mCallback;
diff --git a/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceSnapshot.java b/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceSnapshot.java index 5f053cb..b412058 100644 --- a/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceSnapshot.java +++ b/ui/android/java/src/org/chromium/ui/resources/dynamics/DynamicResourceSnapshot.java
@@ -7,10 +7,13 @@ import android.graphics.Bitmap; import android.graphics.Rect; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.resources.Resource; import org.chromium.ui.resources.statics.NinePatchData; /** The current state of a dynamic resource. */ +@NullMarked public class DynamicResourceSnapshot implements Resource { private final Bitmap mBitmap; private final boolean mShouldRemoveResourceOnNullBitmap; @@ -44,7 +47,7 @@ } @Override - public NinePatchData getNinePatchData() { + public @Nullable NinePatchData getNinePatchData() { return null; }
diff --git a/ui/android/java/src/org/chromium/ui/resources/dynamics/SoftwareDraw.java b/ui/android/java/src/org/chromium/ui/resources/dynamics/SoftwareDraw.java index 04aa3c4c..e4ee598 100644 --- a/ui/android/java/src/org/chromium/ui/resources/dynamics/SoftwareDraw.java +++ b/ui/android/java/src/org/chromium/ui/resources/dynamics/SoftwareDraw.java
@@ -12,10 +12,13 @@ import org.chromium.base.Callback; import org.chromium.base.TraceEvent; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** Simple bitmap capture approach simply calling {@link View#draw(Canvas)}. */ +@NullMarked public class SoftwareDraw implements ViewResourceAdapter.CaptureMechanism { - private Bitmap mBitmap; + private @Nullable Bitmap mBitmap; @Override public boolean shouldRemoveResourceOnNullBitmap() {
diff --git a/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceAdapter.java b/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceAdapter.java index 6f8b4345..80d59d36 100644 --- a/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceAdapter.java +++ b/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceAdapter.java
@@ -17,6 +17,8 @@ import org.chromium.base.ObserverList; import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.resources.Resource; import org.chromium.ui.resources.ResourceFactory; @@ -26,6 +28,7 @@ * {@link View} are invalidated. For {@link ViewGroup}s the easiest way to do this is to override * {@link ViewGroup#invalidateChildInParent(int[], Rect)}. */ +@NullMarked public class ViewResourceAdapter implements DynamicResource, OnLayoutChangeListener, CaptureObserver { /** Abstraction around the mechanism for actually capturing bitmaps. */ @@ -183,7 +186,7 @@ * @param dirtyRect The region to invalidate, or {@code null} if the entire {@code Bitmap} * should be redrawn. */ - public void invalidate(Rect dirtyRect) { + public void invalidate(@Nullable Rect dirtyRect) { if (dirtyRect == null) { mDirtyRect.set(0, 0, mView.getWidth(), mView.getHeight()); } else {
diff --git a/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceInflater.java b/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceInflater.java index 3f6a303..88674a6 100644 --- a/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceInflater.java +++ b/ui/android/java/src/org/chromium/ui/resources/dynamics/ViewResourceInflater.java
@@ -10,6 +10,10 @@ import android.view.ViewGroup; import android.view.ViewTreeObserver; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; + /** * ViewResourceInflater is a utility class that facilitates using an Android View as a dynamic * resource, which can be later used as a compositor layer. This class assumes that the View @@ -32,6 +36,7 @@ * It's possible to specify custom size constraints by overriding the methods * {@link #getWidthMeasureSpec()} and {@link #getHeightMeasureSpec()}. */ +@NullMarked public class ViewResourceInflater { /** The id of the XML Layout that describes the View. */ @@ -41,18 +46,19 @@ private int mViewId; /** The Context used to inflate the View. */ - private Context mContext; + private @Nullable Context mContext; /** The ViewGroup container used to inflate the View. */ private ViewGroup mContainer; /** The DynamicResourceLoader used to manage resources generated dynamically. */ - private DynamicResourceLoader mResourceLoader; + private @Nullable DynamicResourceLoader mResourceLoader; /** The ViewResourceAdapter used to capture snapshots of the View. */ - private ViewResourceAdapter mResourceAdapter; + private @Nullable ViewResourceAdapter mResourceAdapter; /** The inflated View. */ + @SuppressWarnings("NullAway.Init") private View mView; /** Whether the View needs a layout update. */ @@ -65,7 +71,7 @@ private boolean mIsAttached; /** The ViewInflaterOnDrawListener used to track changes in the View when attached. */ - private ViewInflaterOnDrawListener mOnDrawListener; + private @Nullable ViewInflaterOnDrawListener mOnDrawListener; /** The invalid ID. */ private static final int INVALID_ID = -1; @@ -152,6 +158,7 @@ } /** Destroy the instance. */ + @NullUnmarked public void destroy() { if (mView == null) return; @@ -257,7 +264,7 @@ /** * @return The Context used to inflate the View. */ - protected Context getContext() { + protected @Nullable Context getContext() { return mContext; }
diff --git a/ui/android/java/src/org/chromium/ui/resources/statics/NinePatchData.java b/ui/android/java/src/org/chromium/ui/resources/statics/NinePatchData.java index 1f49e35..c9db346 100644 --- a/ui/android/java/src/org/chromium/ui/resources/statics/NinePatchData.java +++ b/ui/android/java/src/org/chromium/ui/resources/statics/NinePatchData.java
@@ -8,11 +8,15 @@ import android.graphics.NinePatch; import android.graphics.Rect; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; /** A helper class to decode and expose relevant 9-patch data from a Bitmap. */ +@NullMarked public class NinePatchData { private final int mWidth; private final int mHeight; @@ -76,7 +80,7 @@ * encoded in {@code bitmap} or {@code null} if the {@link Bitmap} wasn't a * 9-patch. */ - public static NinePatchData create(Bitmap bitmap) { + public static @Nullable NinePatchData create(Bitmap bitmap) { if (bitmap == null) return null; try {
diff --git a/ui/android/java/src/org/chromium/ui/resources/statics/StaticResource.java b/ui/android/java/src/org/chromium/ui/resources/statics/StaticResource.java index 9d5a834..66f7166a 100644 --- a/ui/android/java/src/org/chromium/ui/resources/statics/StaticResource.java +++ b/ui/android/java/src/org/chromium/ui/resources/statics/StaticResource.java
@@ -12,6 +12,9 @@ import android.graphics.drawable.Drawable; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.resources.Resource; import org.chromium.ui.resources.ResourceFactory; @@ -19,9 +22,10 @@ * A representation of a static resource and all related information for drawing it. In general * this means a {@link Bitmap} and a potential {@link NinePatchData}. */ +@NullMarked public class StaticResource implements Resource { - private Bitmap mBitmap; - private final NinePatchData mNinePatchData; + private @Nullable Bitmap mBitmap; + private final @Nullable NinePatchData mNinePatchData; private final Rect mBitmapSize; /** @@ -36,7 +40,7 @@ } @Override - public NinePatchData getNinePatchData() { + public @Nullable NinePatchData getNinePatchData() { return mNinePatchData; } @@ -77,7 +81,7 @@ * @return The loaded {@link StaticResource} or {@code null} if the resource could not be * loaded. */ - public static StaticResource create( + public static @Nullable StaticResource create( Resources resources, int resId, int fitWidth, int fitHeight) { if (resId <= 0) return null; Bitmap bitmap = decodeBitmap(resources, resId, fitWidth, fitHeight); @@ -87,7 +91,7 @@ return new StaticResource(bitmap); } - private static Bitmap decodeBitmap( + private static @Nullable Bitmap decodeBitmap( Resources resources, int resId, int fitWidth, int fitHeight) { BitmapFactory.Options options = createOptions(resources, resId, fitWidth, fitHeight); options.inPreferredConfig = Bitmap.Config.ARGB_8888; @@ -105,7 +109,8 @@ return convertedBitmap; } - private static Bitmap decodeDrawable( + @NullUnmarked + private static @Nullable Bitmap decodeDrawable( Resources resources, int resId, int fitWidth, int fitHeight) { try { Drawable drawable = ApiCompatibilityUtils.getDrawable(resources, resId);
diff --git a/ui/android/java/src/org/chromium/ui/resources/statics/StaticResourceLoader.java b/ui/android/java/src/org/chromium/ui/resources/statics/StaticResourceLoader.java index 0ff2e663..4341edc4 100644 --- a/ui/android/java/src/org/chromium/ui/resources/statics/StaticResourceLoader.java +++ b/ui/android/java/src/org/chromium/ui/resources/statics/StaticResourceLoader.java
@@ -6,10 +6,13 @@ import android.content.res.Resources; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.resources.Resource; import org.chromium.ui.resources.async.AsyncPreloadResourceLoader; /** Handles loading Android resources from disk asynchronously and synchronously. */ +@NullMarked public class StaticResourceLoader extends AsyncPreloadResourceLoader { /** * Creates a {@link StaticResourceLoader}. @@ -26,7 +29,7 @@ callback, new ResourceCreator() { @Override - public Resource create(int resId) { + public @Nullable Resource create(int resId) { return StaticResource.create(resources, resId, 0, 0); } });
diff --git a/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java b/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java index 735c394f..bfbc7a79 100644 --- a/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java +++ b/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java
@@ -10,12 +10,15 @@ import android.graphics.Paint.Style; import android.graphics.RectF; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.resources.Resource; import org.chromium.ui.resources.SystemUIResourceType; import org.chromium.ui.resources.async.AsyncPreloadResourceLoader; import org.chromium.ui.resources.statics.StaticResource; /** Handles loading system specific resources like overscroll and edge glows. */ +@NullMarked public class SystemResourceLoader extends AsyncPreloadResourceLoader { private static final float SIN_PI_OVER_6 = 0.5f; private static final float COS_PI_OVER_6 = 0.866f; @@ -34,13 +37,13 @@ callback, new ResourceCreator() { @Override - public Resource create(int resId) { + public @Nullable Resource create(int resId) { return createResource(minScreenSideLengthPx, resId); } }); } - private static Resource createResource(int minScreenSideLengthPx, int resId) { + private static @Nullable Resource createResource(int minScreenSideLengthPx, int resId) { switch (resId) { case SystemUIResourceType.OVERSCROLL_GLOW: return createOverscrollGlowBitmap(minScreenSideLengthPx);
diff --git a/ui/android/java/src/org/chromium/ui/text/ChromeClickableSpan.java b/ui/android/java/src/org/chromium/ui/text/ChromeClickableSpan.java index b714a80..dd6417e 100644 --- a/ui/android/java/src/org/chromium/ui/text/ChromeClickableSpan.java +++ b/ui/android/java/src/org/chromium/ui/text/ChromeClickableSpan.java
@@ -13,10 +13,12 @@ import androidx.annotation.ColorRes; import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.R; import org.chromium.ui.util.AttrUtils; /** Shows a blue clickable link with underlines turned on. */ +@NullMarked public class ChromeClickableSpan extends ClickableSpan { private final int mColor; private final Callback<View> mOnClick;
diff --git a/ui/android/java/src/org/chromium/ui/text/DownloadableFontTextAppearanceSpan.java b/ui/android/java/src/org/chromium/ui/text/DownloadableFontTextAppearanceSpan.java index df2f3020..f5c87dda 100644 --- a/ui/android/java/src/org/chromium/ui/text/DownloadableFontTextAppearanceSpan.java +++ b/ui/android/java/src/org/chromium/ui/text/DownloadableFontTextAppearanceSpan.java
@@ -15,11 +15,14 @@ import androidx.annotation.StyleRes; import androidx.core.content.res.ResourcesCompat; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; /** {@link TextAppearanceSpan} that supports downloadable fonts, e.g. google sans. */ +@NullMarked public class DownloadableFontTextAppearanceSpan extends TextAppearanceSpan { - private final Typeface mTypeface; + private final @Nullable Typeface mTypeface; public DownloadableFontTextAppearanceSpan(Context context, int appearance) { super(context, appearance);
diff --git a/ui/android/java/src/org/chromium/ui/text/EmptyTextWatcher.java b/ui/android/java/src/org/chromium/ui/text/EmptyTextWatcher.java index ac42dde0..912e986 100644 --- a/ui/android/java/src/org/chromium/ui/text/EmptyTextWatcher.java +++ b/ui/android/java/src/org/chromium/ui/text/EmptyTextWatcher.java
@@ -7,7 +7,10 @@ import android.text.Editable; import android.text.TextWatcher; +import org.chromium.build.annotations.NullMarked; + /** Simple no-op default interface that allows subclasses to only implement methods as needed. */ +@NullMarked public interface EmptyTextWatcher extends TextWatcher { @Override default void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
diff --git a/ui/android/java/src/org/chromium/ui/text/SpanApplier.java b/ui/android/java/src/org/chromium/ui/text/SpanApplier.java index ee51481..d5b009a 100644 --- a/ui/android/java/src/org/chromium/ui/text/SpanApplier.java +++ b/ui/android/java/src/org/chromium/ui/text/SpanApplier.java
@@ -6,7 +6,8 @@ import android.text.SpannableString; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.Arrays; @@ -22,6 +23,7 @@ * SpannableString output = SpanApplier.applySpans(input, * new Span("<tos>", "</tos>", tosSpan), new Span("<pn>", "</pn>", privacySpan)); */ +@NullMarked public class SpanApplier { private static final int INVALID_INDEX = -1; @@ -29,7 +31,7 @@ public static final class SpanInfo implements Comparable<SpanInfo> { final String mStartTag; final String mEndTag; - final @Nullable Object[] mSpans; + final Object @Nullable [] mSpans; int mStartTagIndex; int mEndTagIndex;
diff --git a/ui/android/java/src/org/chromium/ui/util/AccessibilityUtil.java b/ui/android/java/src/org/chromium/ui/util/AccessibilityUtil.java index 8204f2b1..8817cbd 100644 --- a/ui/android/java/src/org/chromium/ui/util/AccessibilityUtil.java +++ b/ui/android/java/src/org/chromium/ui/util/AccessibilityUtil.java
@@ -4,14 +4,15 @@ package org.chromium.ui.util; -import androidx.annotation.Nullable; - import org.chromium.base.ObserverList; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.accessibility.AccessibilityState; import org.chromium.ui.accessibility.AccessibilityState.State; /** Exposes information about the current accessibility state. */ +@NullMarked public class AccessibilityUtil implements AccessibilityState.Listener { /** An observer to be notified of accessibility status changes. */ @Deprecated @@ -24,7 +25,7 @@ void onAccessibilityModeChanged(boolean enabled); } - private ObserverList<Observer> mObservers; + private @Nullable ObserverList<Observer> mObservers; protected AccessibilityUtil() {} @@ -54,7 +55,7 @@ @Override public void onAccessibilityStateChanged( - State oldAccessibilityState, State newAccessibilityState) { + @Nullable State oldAccessibilityState, State newAccessibilityState) { notifyModeChange(AccessibilityState.isAccessibilityEnabled()); }
diff --git a/ui/android/java/src/org/chromium/ui/util/AttrUtils.java b/ui/android/java/src/org/chromium/ui/util/AttrUtils.java index 602cb7d6..3a938d1 100644 --- a/ui/android/java/src/org/chromium/ui/util/AttrUtils.java +++ b/ui/android/java/src/org/chromium/ui/util/AttrUtils.java
@@ -11,7 +11,10 @@ import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; +import org.chromium.build.annotations.NullMarked; + /** Helper functions for working with attributes. */ +@NullMarked public final class AttrUtils { /** Private constructor to stop instantiation. */ private AttrUtils() {}
diff --git a/ui/android/java/src/org/chromium/ui/util/ColorBlendAnimationFactory.java b/ui/android/java/src/org/chromium/ui/util/ColorBlendAnimationFactory.java index 6ef11987..fd0b931 100644 --- a/ui/android/java/src/org/chromium/ui/util/ColorBlendAnimationFactory.java +++ b/ui/android/java/src/org/chromium/ui/util/ColorBlendAnimationFactory.java
@@ -11,11 +11,13 @@ import androidx.annotation.ColorInt; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.interpolators.Interpolators; import java.util.function.Consumer; /** Factory class for creating animations for blending two colors together. */ +@NullMarked public class ColorBlendAnimationFactory { /**
diff --git a/ui/android/java/src/org/chromium/ui/util/ColorUtils.java b/ui/android/java/src/org/chromium/ui/util/ColorUtils.java index 2942309..3c4248e 100644 --- a/ui/android/java/src/org/chromium/ui/util/ColorUtils.java +++ b/ui/android/java/src/org/chromium/ui/util/ColorUtils.java
@@ -13,8 +13,10 @@ import androidx.annotation.IntRange; import org.chromium.base.MathUtils; +import org.chromium.build.annotations.NullMarked; /** Helper functions for working with colors. */ +@NullMarked public class ColorUtils { // Value used by ui::OptionalSkColorToJavaColor() to represent invalid color. public static final long INVALID_COLOR = ((long) Integer.MAX_VALUE) + 1;
diff --git a/ui/android/java/src/org/chromium/ui/util/StyleUtils.java b/ui/android/java/src/org/chromium/ui/util/StyleUtils.java index 96885440..7d3bb23c 100644 --- a/ui/android/java/src/org/chromium/ui/util/StyleUtils.java +++ b/ui/android/java/src/org/chromium/ui/util/StyleUtils.java
@@ -13,9 +13,11 @@ import androidx.annotation.StyleableRes; import androidx.core.content.res.ResourcesCompat; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.R; /** Helper functions for working with styles. */ +@NullMarked public class StyleUtils { private static final String TAG = "StyleUtils"; private static final int INVALID_RESOURCE_ID = -1;
diff --git a/ui/android/java/src/org/chromium/ui/util/TokenHolder.java b/ui/android/java/src/org/chromium/ui/util/TokenHolder.java index e856e1d..597d785 100644 --- a/ui/android/java/src/org/chromium/ui/util/TokenHolder.java +++ b/ui/android/java/src/org/chromium/ui/util/TokenHolder.java
@@ -4,6 +4,8 @@ package org.chromium.ui.util; +import org.chromium.build.annotations.NullMarked; + import java.util.HashSet; import java.util.Set; @@ -11,6 +13,7 @@ * Helper class for holding tokens, useful when multiple entities need to manipulate the same * boolean state, e.g. visibility of a view. */ +@NullMarked public class TokenHolder { /** An invalid token; this can be used to indicate no token is being held. */ public static final int INVALID_TOKEN = -1;
diff --git a/ui/android/java/src/org/chromium/ui/util/ValueUtils.java b/ui/android/java/src/org/chromium/ui/util/ValueUtils.java index 861bd70..ae2f416 100644 --- a/ui/android/java/src/org/chromium/ui/util/ValueUtils.java +++ b/ui/android/java/src/org/chromium/ui/util/ValueUtils.java
@@ -9,7 +9,10 @@ import androidx.annotation.DimenRes; +import org.chromium.build.annotations.NullMarked; + /** Helper functions for working with {@TypedValue}s. */ +@NullMarked public final class ValueUtils { /** Private constructor to stop instantiation. */
diff --git a/ui/android/java/src/org/chromium/ui/util/WindowInsetsUtils.java b/ui/android/java/src/org/chromium/ui/util/WindowInsetsUtils.java index 44ba1d2..8c32485a 100644 --- a/ui/android/java/src/org/chromium/ui/util/WindowInsetsUtils.java +++ b/ui/android/java/src/org/chromium/ui/util/WindowInsetsUtils.java
@@ -10,17 +10,19 @@ import android.util.Size; import android.view.WindowInsets; -import androidx.annotation.NonNull; import androidx.core.graphics.Insets; import androidx.core.view.WindowInsetsCompat.Type.InsetsType; import org.chromium.base.Callback; import org.chromium.base.Log; import org.chromium.base.ResettersForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.List; /** Helper functions for working with WindowInsets and Rects. */ +@NullMarked public final class WindowInsetsUtils { private static final String TAG = "WindowInsetsUtils"; @@ -30,8 +32,8 @@ private static boolean sGetFrameMethodNotFound; private static boolean sGetBoundingRectsMethodNotFound; - private static Size sFrameForTesting; - private static Rect sWidestUnoccludedRectForTesting; + private static @Nullable Size sFrameForTesting; + private static @Nullable Rect sWidestUnoccludedRectForTesting; /** Private constructor to stop instantiation. */ private WindowInsetsUtils() {} @@ -67,7 +69,7 @@ * @return Rect that the insets represent in the windowRect. Empty rect if insets represent more * than one edge. */ - public static @NonNull Rect toRectInWindow(@NonNull Rect windowRect, @NonNull Insets insets) { + public static Rect toRectInWindow(Rect windowRect, Insets insets) { int sides = 0; Rect res = new Rect(windowRect); @@ -109,8 +111,7 @@ * @param blockedRects Areas within the regionRect that are blocked. * @return The widest Rect seen in the regionRect that's not blocked by any blockedRects. */ - public static @NonNull Rect getWidestUnoccludedRect( - @NonNull Rect regionRect, List<Rect> blockedRects) { + public static Rect getWidestUnoccludedRect(Rect regionRect, List<Rect> blockedRects) { if (sWidestUnoccludedRectForTesting != null) return sWidestUnoccludedRectForTesting; if (regionRect.isEmpty()) return regionRect; @@ -131,7 +132,7 @@ /** See {@link WindowInsets#getFrame()} for details. */ @SuppressWarnings("NewApi") - public static Size getFrameFromInsets(WindowInsets windowInsets) { + public static Size getFrameFromInsets(@Nullable WindowInsets windowInsets) { if (sFrameForTesting != null) return sFrameForTesting; // This invocation is wrapped in a try-catch block to allow backporting of the #getFrame() @@ -150,7 +151,7 @@ /** See {@link WindowInsets#getBoundingRects(int)} for details. */ @SuppressWarnings("NewApi") public static List<Rect> getBoundingRectsFromInsets( - WindowInsets windowInsets, @InsetsType int insetType) { + @Nullable WindowInsets windowInsets, @InsetsType int insetType) { // This invocation is wrapped in a try-catch block to allow backporting of the // #getBoundingRects() API on pre-V devices. On pre-V devices not supporting this API, a // default value will be cached on the first failure and returned subsequently.
diff --git a/ui/android/java/src/org/chromium/ui/widget/AnchoredPopupWindow.java b/ui/android/java/src/org/chromium/ui/widget/AnchoredPopupWindow.java index 8e1bc5e..2bbbb48 100644 --- a/ui/android/java/src/org/chromium/ui/widget/AnchoredPopupWindow.java +++ b/ui/android/java/src/org/chromium/ui/widget/AnchoredPopupWindow.java
@@ -22,12 +22,13 @@ import android.widget.PopupWindow.OnDismissListener; import androidx.annotation.IntDef; -import androidx.annotation.Nullable; import androidx.annotation.StyleRes; import androidx.annotation.VisibleForTesting; import org.chromium.base.ObserverList; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; import org.chromium.ui.base.LocalizationUtils; @@ -38,6 +39,7 @@ * UI component that handles showing a {@link PopupWindow}. Positioning this popup happens through a * {@link RectProvider} provided during construction. */ +@NullMarked public class AnchoredPopupWindow implements OnTouchListener, RectProvider.Observer { private static final int MINIMAL_POPUP_HEIGHT_DIP = 50; // 48dp touch target plus 1dp margin. private static final int MINIMAL_POPUP_WIDTH_DIP = 50; // 48dp touch target plus 1dp margin. @@ -207,8 +209,8 @@ // Pass through for the internal PopupWindow. This class needs to intercept these for API // purposes, but they are still useful to callers. private ObserverList<OnDismissListener> mDismissListeners = new ObserverList<>(); - private OnTouchListener mTouchListener; - private LayoutObserver mLayoutObserver; + private @Nullable OnTouchListener mTouchListener; + private @Nullable LayoutObserver mLayoutObserver; /** The margin to add to the popup so it doesn't bump against the edges of the screen. */ private int mMarginPx;
diff --git a/ui/android/java/src/org/chromium/ui/widget/ButtonCompat.java b/ui/android/java/src/org/chromium/ui/widget/ButtonCompat.java index 6472a02..9b6c356 100644 --- a/ui/android/java/src/org/chromium/ui/widget/ButtonCompat.java +++ b/ui/android/java/src/org/chromium/ui/widget/ButtonCompat.java
@@ -16,6 +16,8 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.AppCompatButton; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; /** @@ -39,6 +41,7 @@ * * See {@link R.styleable#ButtonCompat ButtonCompat Attributes}. */ +@NullMarked public class ButtonCompat extends AppCompatButton { private RippleBackgroundHelper mRippleBackgroundHelper; @@ -57,7 +60,8 @@ this(context, attrs, R.style.FilledButtonThemeOverlay); } - private ButtonCompat(Context context, AttributeSet attrs, @StyleRes int themeOverlay) { + private ButtonCompat( + Context context, @Nullable AttributeSet attrs, @StyleRes int themeOverlay) { super(new ContextThemeWrapper(context, themeOverlay), attrs, android.R.attr.buttonStyle); TypedArray a =
diff --git a/ui/android/java/src/org/chromium/ui/widget/CheckableImageView.java b/ui/android/java/src/org/chromium/ui/widget/CheckableImageView.java index 0c450758..400ac77b 100644 --- a/ui/android/java/src/org/chromium/ui/widget/CheckableImageView.java +++ b/ui/android/java/src/org/chromium/ui/widget/CheckableImageView.java
@@ -9,12 +9,14 @@ import android.util.AttributeSet; import android.widget.Checkable; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * ImageView that has checkable state. Checkable state can be used with StateListDrawable and * AnimatedStateListDrawable to dynamically change the appearance of this widget. */ +@NullMarked public class CheckableImageView extends ChromeImageView implements Checkable { private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};
diff --git a/ui/android/java/src/org/chromium/ui/widget/ChromeBulletSpan.java b/ui/android/java/src/org/chromium/ui/widget/ChromeBulletSpan.java index 95a7d006..ba7c0b3 100644 --- a/ui/android/java/src/org/chromium/ui/widget/ChromeBulletSpan.java +++ b/ui/android/java/src/org/chromium/ui/widget/ChromeBulletSpan.java
@@ -10,12 +10,15 @@ import android.text.Layout; import android.text.style.BulletSpan; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; /** * A wrapper around Android's BulletSpan that provides default styling and adjusts the bullet * positioning to prevent it from being cut off. */ +@NullMarked public class ChromeBulletSpan extends BulletSpan { private int mXOffset; @@ -42,7 +45,7 @@ int start, int end, boolean first, - Layout l) { + @Nullable Layout l) { // Android cuts off the bullet points. Adjust the x-position so that the bullets aren't // cut off. super.drawLeadingMargin(
diff --git a/ui/android/java/src/org/chromium/ui/widget/ChromeImageButton.java b/ui/android/java/src/org/chromium/ui/widget/ChromeImageButton.java index ec7be2ad..21103bd 100644 --- a/ui/android/java/src/org/chromium/ui/widget/ChromeImageButton.java +++ b/ui/android/java/src/org/chromium/ui/widget/ChromeImageButton.java
@@ -10,11 +10,14 @@ import androidx.appcompat.widget.AppCompatImageButton; +import org.chromium.build.annotations.NullMarked; + // TODO(crbug.com/40883889): See if we still need this class. /** * A subclass of AppCompatImageButton to add workarounds for bugs in Android Framework and Support * Library. */ +@NullMarked public class ChromeImageButton extends AppCompatImageButton { public ChromeImageButton(Context context) { super(context);
diff --git a/ui/android/java/src/org/chromium/ui/widget/ChromeImageView.java b/ui/android/java/src/org/chromium/ui/widget/ChromeImageView.java index 6aa4316..b12ee20 100644 --- a/ui/android/java/src/org/chromium/ui/widget/ChromeImageView.java +++ b/ui/android/java/src/org/chromium/ui/widget/ChromeImageView.java
@@ -11,16 +11,18 @@ import android.graphics.drawable.Drawable; import android.util.AttributeSet; -import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatImageView; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; // TODO(crbug.com/40883889): This class has no use now, so we can get rid of it. /** * A subclass of AppCompatImageView to add workarounds for bugs in Android Framework and Support * Library. */ +@NullMarked public class ChromeImageView extends AppCompatImageView { private static final String TAG = "CIV";
diff --git a/ui/android/java/src/org/chromium/ui/widget/LoadingView.java b/ui/android/java/src/org/chromium/ui/widget/LoadingView.java index 5eaff096..6aa41fb5 100644 --- a/ui/android/java/src/org/chromium/ui/widget/LoadingView.java +++ b/ui/android/java/src/org/chromium/ui/widget/LoadingView.java
@@ -13,12 +13,14 @@ import android.widget.ProgressBar; import org.chromium.base.ResettersForTesting; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.interpolators.Interpolators; import java.util.ArrayList; import java.util.List; /** A {@link ProgressBar} that understands the hiding/showing policy defined in Material Design. */ +@NullMarked public class LoadingView extends ProgressBar { private static final int LOADING_ANIMATION_DELAY_MS = 500; private static final int MINIMUM_ANIMATION_SHOW_TIME_MS = 500;
diff --git a/ui/android/java/src/org/chromium/ui/widget/OptimizedFrameLayout.java b/ui/android/java/src/org/chromium/ui/widget/OptimizedFrameLayout.java index 6b402e1..82d3abb7 100644 --- a/ui/android/java/src/org/chromium/ui/widget/OptimizedFrameLayout.java +++ b/ui/android/java/src/org/chromium/ui/widget/OptimizedFrameLayout.java
@@ -11,6 +11,8 @@ import android.view.View; import android.widget.FrameLayout; +import org.chromium.build.annotations.NullMarked; + import java.util.ArrayList; import java.util.List; @@ -18,6 +20,7 @@ * This class overrides {@link FrameLayout#onMeasure} so that it does not call onMeasure on its * children multiple times during the same {@link FrameLayout#onMeasure} call. */ +@NullMarked public class OptimizedFrameLayout extends FrameLayout { private static class MeasurementState { final View mView;
diff --git a/ui/android/java/src/org/chromium/ui/widget/RectProvider.java b/ui/android/java/src/org/chromium/ui/widget/RectProvider.java index aecc016..5b787685 100644 --- a/ui/android/java/src/org/chromium/ui/widget/RectProvider.java +++ b/ui/android/java/src/org/chromium/ui/widget/RectProvider.java
@@ -6,7 +6,11 @@ import android.graphics.Rect; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** Provides a {@link Rect} object that represents a position in screen space. */ +@NullMarked public class RectProvider { /** An observer to be notified of changes to the {@Rect} position. */ public interface Observer { @@ -26,7 +30,7 @@ */ protected final Rect mRect = new Rect(); - private Observer mObserver; + private @Nullable Observer mObserver; /** Creates an instance of a {@link RectProvider}. */ public RectProvider() {}
diff --git a/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java b/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java index b10ff90..76c1a364 100644 --- a/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java +++ b/ui/android/java/src/org/chromium/ui/widget/RippleBackgroundHelper.java
@@ -17,17 +17,19 @@ import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.annotation.DimenRes; -import androidx.annotation.Nullable; import androidx.annotation.Px; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.graphics.ColorUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; /** * A helper class to create and maintain a background drawable with customized background color, * ripple color, and corner radius. */ +@NullMarked public class RippleBackgroundHelper { private static final int[] STATE_SET_PRESSED = {android.R.attr.state_pressed}; private static final int[] STATE_SET_SELECTED = {android.R.attr.state_selected}; @@ -40,9 +42,13 @@ private @Nullable ColorStateList mBackgroundColorList; private @Nullable ColorStateList mStateLayerColorList; + @SuppressWarnings("NullAway.Init") private GradientDrawable mBackgroundGradient; + + @SuppressWarnings("NullAway.Init") private GradientDrawable mStateLayerGradient; - private LayerDrawable mBackgroundLayerDrawable; + + private @Nullable LayerDrawable mBackgroundLayerDrawable; /** * @param view The {@link View} on which background will be applied.
diff --git a/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java b/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java index e6f6acaa..1898cbe 100644 --- a/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java +++ b/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java
@@ -20,6 +20,9 @@ import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.accessibility.AccessibilityState; /** @@ -28,9 +31,10 @@ * do nothing if it's a touch event directly on a ClickableSpan. Otherwise if there's only one * ClickableSpan, we activate it. If there's more than one, we pop up a PopupMenu to disambiguate. */ +@NullMarked public class TextViewWithClickableSpans extends TextViewWithLeading implements View.OnLongClickListener { - private PopupMenu mDisambiguationMenu; + private @Nullable PopupMenu mDisambiguationMenu; public TextViewWithClickableSpans(Context context) { super(context); @@ -63,14 +67,14 @@ } @Override - public final void setOnLongClickListener(View.OnLongClickListener listener) { + public final void setOnLongClickListener(View.@Nullable OnLongClickListener listener) { // Ensure that no one changes the long click listener to anything but this view. assert listener == this || listener == null; super.setOnLongClickListener(listener); } @Override - public boolean performAccessibilityAction(int action, Bundle arguments) { + public boolean performAccessibilityAction(int action, @Nullable Bundle arguments) { // BrailleBack will generate an accessibility click event directly // on this view, make sure we handle that correctly. if (action == AccessibilityNodeInfo.ACTION_CLICK) { @@ -102,6 +106,7 @@ * @param event The motion event to compare the spans against. * @return Whether the motion event intersected any clickable spans. */ + @NullUnmarked protected boolean touchIntersectsAnyClickableSpans(MotionEvent event) { // This logic is borrowed from android.text.method.LinkMovementMethod. // @@ -132,7 +137,7 @@ /** Returns the ClickableSpans in this TextView's text. */ @VisibleForTesting - public ClickableSpan[] getClickableSpans() { + public ClickableSpan @Nullable [] getClickableSpans() { CharSequence text = getText(); if (!(text instanceof SpannableString)) return null;
diff --git a/ui/android/java/src/org/chromium/ui/widget/TextViewWithLeading.java b/ui/android/java/src/org/chromium/ui/widget/TextViewWithLeading.java index a42c3717..79c321c 100644 --- a/ui/android/java/src/org/chromium/ui/widget/TextViewWithLeading.java +++ b/ui/android/java/src/org/chromium/ui/widget/TextViewWithLeading.java
@@ -9,11 +9,12 @@ import android.content.res.TypedArray; import android.util.AttributeSet; -import androidx.annotation.Nullable; import androidx.annotation.StyleRes; import androidx.annotation.StyleableRes; import androidx.appcompat.widget.AppCompatTextView; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; import org.chromium.ui.base.UiAndroidFeatureList; @@ -23,6 +24,7 @@ * calculation to set up leading correctly and allows it to be set in XML. It overwrites * android:lineSpacingExtra and android:lineSpacingMultiplier. */ +@NullMarked public class TextViewWithLeading extends AppCompatTextView { /** * Constructing TextViewWithLeading programmatically without an {@link AttributeSet} will render
diff --git a/ui/android/java/src/org/chromium/ui/widget/TextViewWithTightWrap.java b/ui/android/java/src/org/chromium/ui/widget/TextViewWithTightWrap.java index 9df6522a..e7a87525 100644 --- a/ui/android/java/src/org/chromium/ui/widget/TextViewWithTightWrap.java +++ b/ui/android/java/src/org/chromium/ui/widget/TextViewWithTightWrap.java
@@ -9,11 +9,14 @@ import android.util.AttributeSet; import android.widget.TextView; +import org.chromium.build.annotations.NullMarked; + /** * A TextView with an accurate width calculation support for multilines. * This is used when we want no extra padding on a multiline TextView. The class perform the width * calculation in the overwritten OnMeasure() method. */ +@NullMarked public class TextViewWithTightWrap extends TextView { /** Constructing TextViewWithTightWrap programmatically is similar to a normal TextView. */ public TextViewWithTightWrap(Context context) {
diff --git a/ui/android/java/src/org/chromium/ui/widget/Toast.java b/ui/android/java/src/org/chromium/ui/widget/Toast.java index c51b445..7bbb347 100644 --- a/ui/android/java/src/org/chromium/ui/widget/Toast.java +++ b/ui/android/java/src/org/chromium/ui/widget/Toast.java
@@ -23,6 +23,8 @@ import androidx.annotation.StyleRes; import org.chromium.base.SysUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.R; import org.chromium.ui.display.DisplayAndroid; @@ -39,6 +41,7 @@ * that the toast be shown sooner than those of priority {@code NORMAL} queued for their turn. * See {@link ToastManager} for more details. */ +@NullMarked public class Toast { public static final int LENGTH_SHORT = android.widget.Toast.LENGTH_SHORT; @@ -55,9 +58,9 @@ } private android.widget.Toast mToast; - private ViewGroup mSWLayout; + private @Nullable ViewGroup mSWLayout; private @ToastPriority int mPriority; - private CharSequence mText; + private @Nullable CharSequence mText; public Toast(Context context, View toastView) { if (SysUtils.isLowEndDevice()) { @@ -110,7 +113,7 @@ } } - public View getView() { + public @Nullable View getView() { if (mToast.getView() == null) { return null; } @@ -138,10 +141,11 @@ return mPriority; } - void setText(CharSequence text) { + void setText(@Nullable CharSequence text) { mText = text; } + @Nullable CharSequence getText() { return mText; } @@ -259,10 +263,10 @@ /** Builder pattern class to construct {@link Toast} with various arguments. */ public static class Builder { private final Context mContext; - private CharSequence mText; - private View mAnchoredView; - private Integer mBackgroundColor; - private Integer mTextAppearance; + private @Nullable CharSequence mText; + private @Nullable View mAnchoredView; + private @Nullable Integer mBackgroundColor; + private @Nullable Integer mTextAppearance; private int mDuration = LENGTH_SHORT; private @ToastPriority int mPriority = ToastPriority.NORMAL;
diff --git a/ui/android/java/src/org/chromium/ui/widget/ToastManager.java b/ui/android/java/src/org/chromium/ui/widget/ToastManager.java index 203b397..44b001d 100644 --- a/ui/android/java/src/org/chromium/ui/widget/ToastManager.java +++ b/ui/android/java/src/org/chromium/ui/widget/ToastManager.java
@@ -14,6 +14,10 @@ import org.jni_zero.JNINamespace; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; + import java.util.Iterator; import java.util.PriorityQueue; @@ -28,11 +32,12 @@ * </ul> */ @JNINamespace("ui") +@NullMarked public class ToastManager { private static final int DURATION_SHORT_MS = 2000; private static final int DURATION_LONG_MS = 3500; private static final long DURATION_BETWEEN_TOASTS_MS = 500; - private static ToastManager sInstance; + private static @Nullable ToastManager sInstance; // A queue for toasts waiting to be shown. private final PriorityQueue<Toast> mToastQueue = @@ -50,7 +55,7 @@ private final ToastEvent mToastEvent; // Toast currently showing. {@code null} if none is showing. - private Toast mToast; + private @Nullable Toast mToast; static ToastManager getInstance() { if (sInstance == null) sInstance = new ToastManager(); @@ -99,6 +104,7 @@ } @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + @Nullable Toast getCurrentToast() { return mToast; } @@ -148,6 +154,7 @@ mPostToastRunnable = finishRunnable; } + @NullUnmarked @Override public void onShow(Toast toast) { int durationMs =
diff --git a/ui/android/java/src/org/chromium/ui/widget/UiWidgetFactory.java b/ui/android/java/src/org/chromium/ui/widget/UiWidgetFactory.java index 76dad61..b2af8eb 100644 --- a/ui/android/java/src/org/chromium/ui/widget/UiWidgetFactory.java +++ b/ui/android/java/src/org/chromium/ui/widget/UiWidgetFactory.java
@@ -9,12 +9,16 @@ import android.content.Context; import android.widget.PopupWindow; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** * The factory that creates UI widgets. Instead of direct creation of Android popups * we should ask this factory to create the object for us. */ +@NullMarked public class UiWidgetFactory { - private static UiWidgetFactory sFactory; + private static @Nullable UiWidgetFactory sFactory; protected UiWidgetFactory() {}
diff --git a/ui/android/java/src/org/chromium/ui/widget/ViewLookupCachingFrameLayout.java b/ui/android/java/src/org/chromium/ui/widget/ViewLookupCachingFrameLayout.java index a649b38..f16f7fbc 100644 --- a/ui/android/java/src/org/chromium/ui/widget/ViewLookupCachingFrameLayout.java +++ b/ui/android/java/src/org/chromium/ui/widget/ViewLookupCachingFrameLayout.java
@@ -11,10 +11,11 @@ import android.view.ViewGroup; import androidx.annotation.IdRes; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import org.chromium.build.BuildConfig; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.lang.ref.WeakReference; @@ -35,6 +36,7 @@ * Use the same way that you would use a normal {@link android.widget.FrameLayout}, but instead * of using {@link #findViewById(int)} to access views, use {@link #fastFindViewById(int)}. */ +@NullMarked public class ViewLookupCachingFrameLayout extends OptimizedFrameLayout { /** A map containing views that have had lookup performed on them for quicker access. */ private final SparseArray<WeakReference<View>> mCachedViews = new SparseArray<>(); @@ -73,7 +75,8 @@ * @param view The root of the tree to attach listeners to. * @param listener The listener to attach (null to unset). */ - private void setHierarchyListenerOnTree(View view, OnHierarchyChangeListener listener) { + private void setHierarchyListenerOnTree( + View view, @Nullable OnHierarchyChangeListener listener) { if (!(view instanceof ViewGroup)) return; ViewGroup group = (ViewGroup) view; @@ -90,8 +93,7 @@ * @param id The ID of the view to lookup. * @return The view if it exists. */ - @Nullable - public View fastFindViewById(@IdRes int id) { + public @Nullable View fastFindViewById(@IdRes int id) { WeakReference<View> ref = mCachedViews.get(id); View view = null; if (ref != null) view = ref.get();
diff --git a/ui/android/java/src/org/chromium/ui/widget/ViewRectProvider.java b/ui/android/java/src/org/chromium/ui/widget/ViewRectProvider.java index d1d7ea1..3ae4a0e 100644 --- a/ui/android/java/src/org/chromium/ui/widget/ViewRectProvider.java +++ b/ui/android/java/src/org/chromium/ui/widget/ViewRectProvider.java
@@ -10,11 +10,15 @@ import androidx.core.view.ViewCompat; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** * Provides a {@link Rect} for the location of a {@link View} in its window, see {@link * View#getLocationOnScreen(int[])}. When view bound changes, {@link RectProvider.Observer} will be * notified. */ +@NullMarked public class ViewRectProvider extends RectProvider implements ViewTreeObserver.OnGlobalLayoutListener, View.OnAttachStateChangeListener, @@ -28,7 +32,7 @@ private int mCachedViewHeight; /** If not {@code null}, the {@link ViewTreeObserver} that we are registered to. */ - private ViewTreeObserver mViewTreeObserver; + private @Nullable ViewTreeObserver mViewTreeObserver; private boolean mIncludePadding;
diff --git a/ui/android/javatests/src/org/chromium/ui/test/util/UiRestriction.java b/ui/android/javatests/src/org/chromium/ui/test/util/UiRestriction.java index 1d8f96c..d1f9a41 100644 --- a/ui/android/javatests/src/org/chromium/ui/test/util/UiRestriction.java +++ b/ui/android/javatests/src/org/chromium/ui/test/util/UiRestriction.java
@@ -18,8 +18,16 @@ * </code> */ public final class UiRestriction { + private static Boolean sIsDesktop; private static Boolean sIsTablet; + private static boolean isDesktop() { + if (sIsDesktop == null) { + sIsDesktop = DeviceFormFactor.isDesktop(); + } + return sIsDesktop; + } + private static boolean isTablet() { if (sIsTablet == null) { sIsTablet = @@ -33,6 +41,7 @@ } public static void registerChecks(RestrictionSkipCheck check) { + check.addHandler(DeviceFormFactor.DESKTOP, () -> isDesktop()); check.addHandler(DeviceFormFactor.PHONE, () -> isTablet()); check.addHandler(DeviceFormFactor.TABLET, () -> !isTablet()); }
diff --git a/ui/base/models/combobox_model.cc b/ui/base/models/combobox_model.cc index 2bd9e83e..d1dd4f4 100644 --- a/ui/base/models/combobox_model.cc +++ b/ui/base/models/combobox_model.cc
@@ -32,6 +32,10 @@ return false; } +bool ComboboxModel::IsItemTitleAt(size_t index) const { + return false; +} + std::optional<size_t> ComboboxModel::GetDefaultIndex() const { return size_t{0}; }
diff --git a/ui/base/models/combobox_model.h b/ui/base/models/combobox_model.h index 299571c..cc52b94 100644 --- a/ui/base/models/combobox_model.h +++ b/ui/base/models/combobox_model.h
@@ -45,6 +45,10 @@ // item. virtual bool IsItemSeparatorAt(size_t index) const; + // TODO(pbos): Consider replacing this (and IsItemSeparatorAt) with something + // that either returns or maps well to MenuModel::ItemType. + virtual bool IsItemTitleAt(size_t index) const; + // The index of the item that is selected by default (before user // interaction). virtual std::optional<size_t> GetDefaultIndex() const;
diff --git a/ui/ozone/platform/wayland/host/wayland_shm_buffer.cc b/ui/ozone/platform/wayland/host/wayland_shm_buffer.cc index 6ed0893..d1d36e7 100644 --- a/ui/ozone/platform/wayland/host/wayland_shm_buffer.cc +++ b/ui/ozone/platform/wayland/host/wayland_shm_buffer.cc
@@ -57,7 +57,7 @@ stride_ = stride; } -uint8_t* WaylandShmBuffer::GetMemory() const { +uint8_t* WaylandShmBuffer::GetMemory() { if (!IsValid() || !shared_memory_mapping_.IsValid()) return nullptr; return shared_memory_mapping_.GetMemoryAs<uint8_t>();
diff --git a/ui/ozone/platform/wayland/host/wayland_shm_buffer.h b/ui/ozone/platform/wayland/host/wayland_shm_buffer.h index 6a38389..93284cfc 100644 --- a/ui/ozone/platform/wayland/host/wayland_shm_buffer.h +++ b/ui/ozone/platform/wayland/host/wayland_shm_buffer.h
@@ -39,7 +39,7 @@ // Returns the underlying raw memory buffer, if it's currently mapped into // local address space, otherwise return nullptr - uint8_t* GetMemory() const; + uint8_t* GetMemory(); // Returns the underlying wl_buffer pointer wl_buffer* get() const { return buffer_.get(); }
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 0d4a2d80..55fe914 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -214,6 +214,7 @@ "controls/textfield/textfield.h", "controls/textfield/textfield_controller.h", "controls/textfield/textfield_model.h", + "controls/theme_tracking_animated_image_view.h", "controls/theme_tracking_image_view.h", "controls/throbber.h", "controls/tree/tree_view.h", @@ -446,6 +447,7 @@ "controls/textfield/textfield.cc", "controls/textfield/textfield_controller.cc", "controls/textfield/textfield_model.cc", + "controls/theme_tracking_animated_image_view.cc", "controls/theme_tracking_image_view.cc", "controls/throbber.cc", "controls/tree/tree_view.cc",
diff --git a/ui/views/controls/combobox/combobox.h b/ui/views/controls/combobox/combobox.h index a836092d..8463d2c 100644 --- a/ui/views/controls/combobox/combobox.h +++ b/ui/views/controls/combobox/combobox.h
@@ -72,10 +72,8 @@ callback_ = std::move(callback); } - // Set menu model. - void SetMenuModel(std::unique_ptr<ui::MenuModel> menu_model) { - menu_model_ = std::move(menu_model); - } + // Gets the matching menu-model adapter for testing. + ui::MenuModel* menu_model_for_testing() const { return menu_model_.get(); } // Gets/Sets the selected index. std::optional<size_t> GetSelectedIndex() const { return selected_index_; }
diff --git a/ui/views/controls/combobox/combobox_menu_model.cc b/ui/views/controls/combobox/combobox_menu_model.cc index 32e2cdad..5e0bcacb 100644 --- a/ui/views/controls/combobox/combobox_menu_model.cc +++ b/ui/views/controls/combobox/combobox_menu_model.cc
@@ -24,8 +24,12 @@ } ui::MenuModel::ItemType ComboboxMenuModel::GetTypeAt(size_t index) const { - if (model_->IsItemSeparatorAt(index)) + if (model_->IsItemSeparatorAt(index)) { return TYPE_SEPARATOR; + } + if (model_->IsItemTitleAt(index)) { + return TYPE_TITLE; + } return UseCheckmarks() ? TYPE_CHECK : TYPE_COMMAND; }
diff --git a/ui/views/controls/theme_tracking_animated_image_view.cc b/ui/views/controls/theme_tracking_animated_image_view.cc new file mode 100644 index 0000000..3c7f9b3 --- /dev/null +++ b/ui/views/controls/theme_tracking_animated_image_view.cc
@@ -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. + +#include "ui/views/controls/theme_tracking_animated_image_view.h" + +#include <stdint.h> + +#include <memory> +#include <optional> +#include <utility> +#include <vector> + +#include "base/functional/callback.h" +#include "cc/paint/skottie_wrapper.h" +#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/color_utils.h" + +namespace views { + +ThemeTrackingAnimatedImageView::ThemeTrackingAnimatedImageView( + int light_animation_lottie_id, + int dark_animation_lottie_id, + base::RepeatingCallback<SkColor()> get_background_color_callback) + : light_animation_lottie_id_(light_animation_lottie_id), + dark_animation_lottie_id_(dark_animation_lottie_id), + get_background_color_callback_(std::move(get_background_color_callback)) { +} + +ThemeTrackingAnimatedImageView::~ThemeTrackingAnimatedImageView() = default; + +void ThemeTrackingAnimatedImageView::OnThemeChanged() { + AnimatedImageView::OnThemeChanged(); + const bool is_dark = + color_utils::IsDark(get_background_color_callback_.Run()); + UpdateAnimatedImage(is_dark ? dark_animation_lottie_id_ + : light_animation_lottie_id_); +} + +void ThemeTrackingAnimatedImageView::UpdateAnimatedImage(int lottie_id) { + std::optional<std::vector<uint8_t>> lottie_bytes = + ui::ResourceBundle::GetSharedInstance().GetLottieData(lottie_id); + scoped_refptr<cc::SkottieWrapper> skottie = + cc::SkottieWrapper::UnsafeCreateSerializable(std::move(*lottie_bytes)); + SetAnimatedImage(std::make_unique<lottie::Animation>(skottie)); + SizeToPreferredSize(); + Play(); +} + +BEGIN_METADATA(ThemeTrackingAnimatedImageView) +END_METADATA + +} // namespace views
diff --git a/ui/views/controls/theme_tracking_animated_image_view.h b/ui/views/controls/theme_tracking_animated_image_view.h new file mode 100644 index 0000000..0cf257f --- /dev/null +++ b/ui/views/controls/theme_tracking_animated_image_view.h
@@ -0,0 +1,49 @@ +// 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_VIEWS_CONTROLS_THEME_TRACKING_ANIMATED_IMAGE_VIEW_H_ +#define UI_VIEWS_CONTROLS_THEME_TRACKING_ANIMATED_IMAGE_VIEW_H_ + +#include "base/functional/callback_forward.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/views/controls/animated_image_view.h" + +namespace views { + +// An AnimatedImageView that displays either `light_animation_lottie_id` or +// `dark_animation_lottie_id` based on the current background color returned by +// `get_background_color_callback`. Tracks theme changes so the image is always +// the correct version. +class VIEWS_EXPORT ThemeTrackingAnimatedImageView : public AnimatedImageView { + METADATA_HEADER(ThemeTrackingAnimatedImageView, AnimatedImageView) + + public: + ThemeTrackingAnimatedImageView( + int light_animation_lottie_id, + int dark_animation_lottie_id, + base::RepeatingCallback<SkColor()> get_background_color_callback); + + ThemeTrackingAnimatedImageView(const ThemeTrackingAnimatedImageView&) = + delete; + ThemeTrackingAnimatedImageView& operator=( + const ThemeTrackingAnimatedImageView&) = delete; + ~ThemeTrackingAnimatedImageView() override; + + // AnimatedImageView: + void OnThemeChanged() override; + + private: + void UpdateAnimatedImage(int lottie_id); + + // The underlying light and dark mode animated images' Lottie IDs. + int light_animation_lottie_id_; + int dark_animation_lottie_id_; + + base::RepeatingCallback<SkColor()> get_background_color_callback_; +}; + +} // namespace views + +#endif // UI_VIEWS_CONTROLS_THEME_TRACKING_ANIMATED_IMAGE_VIEW_H_
diff --git a/v8 b/v8 index 27d5ca8..99d615b 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit 27d5ca8ed62889fc9974afc2fd89c078582d5dd4 +Subproject commit 99d615b4cef42ad9a32639547e8ac4bd7db462e5