diff --git a/DEPS b/DEPS index f113f26..be67900 100644 --- a/DEPS +++ b/DEPS
@@ -300,23 +300,23 @@ # 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': 'ebf59a967121173a07b14a2c2b415983f7267b85', + 'src_internal_revision': '3f05162719c305d3e7dcf93800c67fa5b4a295ee', # 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': '5f0f9b76b975a5c70022a35372bd1618628d3e78', + 'skia_revision': '245d2b8fb04212b4b7f122f02438a1f0ac62141e', # 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': '9737790587bc0ce61a1ffc9fadde3abf70dbb5a9', + 'v8_revision': 'bd4ded6cee0c3cbd1106937be7a43116671692b2', # 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': '1b92a973484c95f26bba5e2e4e2511ed03ab6c66', + 'angle_revision': '0e28c030a2625e3022a9adeec9746519af4217a2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '4982425ff1bdcb2ce52a360edde58a379119bfde', + 'swiftshader_revision': '2b323370501c03d249c91b57fe8585e63960f9e9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -376,7 +376,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '556571f9e93b7e4fe6f61c09b0281442722facef', + 'catapult_revision': 'd451fed9573b5eb485dc364514d1ec95f20eadb0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # 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 devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '3b6a4060c03f56f901cb39084b52b5ef1dea16fa', + 'devtools_frontend_revision': 'e8b639c4812cbc6276f37fb393da8537422844f8', # 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. @@ -528,7 +528,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': 'aa5c758d870f1a1f2f0b51c960dc96f73a50eb54', + 'llvm_libc_revision': '6df4308a5d808514f7af2e941ba2f0b28133762d', # 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. @@ -1158,7 +1158,7 @@ }, 'src/chrome/release_scripts': { - 'url': Var('chrome_git') + '/chrome/tools/release/scripts' + '@' + 'ebacc4377d49ec15f4d19e061d5d9ed344cffc1e', + 'url': Var('chrome_git') + '/chrome/tools/release/scripts' + '@' + 'b0e8d98f5141c3b50870406a7cf1e090806b2f8e', 'condition': 'checkout_chrome_release_scripts', }, @@ -1490,7 +1490,7 @@ 'packages': [ { 'package': 'chromium/chrome/test/data/variations/cipd', - 'version': 'LgXKHxzIXTM8zViEt_MjmEwZCS2eFHecYh5BSTnhGw8C', + 'version': '5o1aqhP1KwO_yLbWQrePDjIOPYWmsLtIihEL4tFjJqIC', }, ], 'dep_type': 'cipd', @@ -1501,7 +1501,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '5c66745b33cda1230040a42b22046206497c6580', + '618a8ebb6ca63dee8c6b5066c777e88ec88596d2', 'condition': 'checkout_android and checkout_src_internal', }, @@ -1753,7 +1753,7 @@ 'packages': [ { 'package': 'chromium/third_party/android_build_tools/lint', - 'version': 'cpi5krkjlhoCfjDOZ3fIdPXDOqnCGMBVzm_yHg1WnWUC', + 'version': 'vBqKHQdjLFM5l79fpi3L9l7kD9b1FfeyfWbIFjXShSgC', }, ], 'condition': 'checkout_android and non_git_source', @@ -2541,7 +2541,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('chromium_git') + '/external/github.com/google/perfetto.git' + '@' + '745c6d3fead9008f05ee73172e46d059863b5ab3', + Var('chromium_git') + '/external/github.com/google/perfetto.git' + '@' + '181c298de2ebe848dad23788d76ae1f517aae6ec', 'src/base/tracing/test/data': { 'bucket': 'perfetto', @@ -2855,16 +2855,16 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@22fd0de3755bed1806292e15b640b93e1812bb2b', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@8ede18e2d91dfd40c5e71c25f42761519142dd1a', 'src/third_party/glslang/src': '{chromium_git}/external/github.com/KhronosGroup/glslang@4a038eafdf9e9f3e0ac2e200127df969f3a51ddb', 'src/third_party/spirv-cross/src': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Cross@b8fcf307f1f347089e3c46eb4451d27f32ebc8d3', 'src/third_party/spirv-headers/src': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Headers@8e82b7cfeca98baae9a01a53511483da7194f854', 'src/third_party/spirv-tools/src': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Tools@1a811fd69871da36d9cca84586d8a7799be893ec', 'src/third_party/vulkan-headers/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Headers@5ceb9ed481e58e705d0d9b5326537daedd06b97d', 'src/third_party/vulkan-loader/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Loader@b8eb2b901835497b91db7bd7005f4d6ddba2bf1e', - 'src/third_party/vulkan-tools/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Tools@9c0fff2798d769b4c0681001c24d3d55467dde8f', + 'src/third_party/vulkan-tools/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Tools@59dc56aa3023434317a5197d77be51855b5fd2fb', 'src/third_party/vulkan-utility-libraries/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Utility-Libraries@abc2498bde8d65841f463431a6220701fad44c64', - 'src/third_party/vulkan-validation-layers/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-ValidationLayers@91fd4f29aed4015857822e8edad5004e7e3f90da', + 'src/third_party/vulkan-validation-layers/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-ValidationLayers@2d41063e90346d2fceca5f40b90e43a7a3368f7b', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '56300b29fbfcc693ee6609ddad3fdd5b7a449a21', @@ -2909,7 +2909,7 @@ Var('chromium_git') + '/webpagereplay.git' + '@' + Var('webpagereplay_revision'), 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '5ed7ffd7ff73d95bf87d85de4eb469bb78af6c2b', + Var('webrtc_git') + '/src.git' + '@' + '74b51006acd2bd9f533c3c309a73cdf2479057c4', # 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. @@ -4635,7 +4635,7 @@ 'src/components/optimization_guide/internal': { 'url': Var('chrome_git') + '/chrome/components/optimization_guide.git' + '@' + - 'a96fd8cc0fc8feab1676ce8076f5ec60079e6d7a', + '6200c82b11623748653bcac9e5293f347bf072fb', 'condition': 'checkout_src_internal', }, @@ -4701,7 +4701,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - 'ff8ce0b2995198b6076b1a6fc0ac27d0d4bc5d6f', + '04489da71ef10228a79347ccfd484cfed4f613d3', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/OWNERS b/OWNERS index eb6d61e..5047e10b 100644 --- a/OWNERS +++ b/OWNERS
@@ -99,6 +99,7 @@ per-file third_party/clang-format/script=* per-file third_party/cld_3/src=* per-file third_party/colorama/src=* +per-file third_party/compiler-rt/src=* per-file third_party/content_analysis_sdk/src=* per-file third_party/cpu_features/src=* per-file third_party/cpuinfo/src=*
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index 38feca9..7a3c31a 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -929,6 +929,7 @@ "//components/gwp_asan/client/android:gwp_asan_java", "//components/metrics:metrics_java", "//components/network_session_configurator/android:network_session_configurator_java", + "//components/payments/content/android:feature_list_java", "//components/permissions/android:core_java", "//components/safe_browsing/android:safe_browsing_java", "//components/sensitive_content:sensitive_content_features_java", @@ -1140,7 +1141,6 @@ "java/res/layout/aw_context_menu_fullscreen_container.xml", "java/res/layout/aw_context_menu_header.xml", "java/res/layout/aw_context_menu_row.xml", - "java/res/raw/histograms_allowlist.txt", "java/res/values/styles.xml", ] deps = [ ":strings_grd" ]
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index ef792a9..d88efbc 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -782,40 +782,6 @@ return result; } -std::vector<std::unique_ptr<blink::URLLoaderThrottle>> -AwContentBrowserClient::CreateURLLoaderThrottlesForKeepAlive( - const network::ResourceRequest& request, - content::BrowserContext* browser_context, - const base::RepeatingCallback<content::WebContents*()>& wc_getter, - content::FrameTreeNodeId frame_tree_node_id) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - // Set lookup mechanism based on feature flag - HashRealTimeSelection hash_real_time_selection = - (base::FeatureList::IsEnabled(safe_browsing::kHashPrefixRealTimeLookups)) - ? HashRealTimeSelection::kDatabaseManager - : HashRealTimeSelection::kNone; - - std::vector<std::unique_ptr<blink::URLLoaderThrottle>> result; - - result.push_back(safe_browsing::BrowserURLLoaderThrottle::Create( - base::BindRepeating( - [](AwContentBrowserClient* client) { - return client->GetSafeBrowsingUrlCheckerDelegate(); - }, - base::Unretained(this)), - wc_getter, frame_tree_node_id, /*navigation_id=*/std::nullopt, - // TODO(crbug.com/40663467): rt_lookup_service is - // used to perform real time URL check, which is gated by UKM opted-in. - // Since AW currently doesn't support UKM, this feature is not enabled. - /* rt_lookup_service */ nullptr, - /* hash_realtime_service */ nullptr, - /* hash_realtime_selection */ - hash_real_time_selection, - /* async_check_tracker */ nullptr, /*referring_app_info=*/std::nullopt)); - - return result; -} - scoped_refptr<safe_browsing::UrlCheckerDelegate> AwContentBrowserClient::GetSafeBrowsingUrlCheckerDelegate() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index 7164087..cc057760 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -178,12 +178,6 @@ content::NavigationUIData* navigation_ui_data, content::FrameTreeNodeId frame_tree_node_id, std::optional<int64_t> navigation_id) override; - std::vector<std::unique_ptr<blink::URLLoaderThrottle>> - CreateURLLoaderThrottlesForKeepAlive( - const network::ResourceRequest& request, - content::BrowserContext* browser_context, - const base::RepeatingCallback<content::WebContents*()>& wc_getter, - content::FrameTreeNodeId frame_tree_node_id) override; bool ShouldOverrideUrlLoading(content::FrameTreeNodeId frame_tree_node_id, bool browser_initiated, const GURL& gurl,
diff --git a/android_webview/java/res/raw/PRESUBMIT.py b/android_webview/java/res/raw/PRESUBMIT.py index f23353c..67bf46ee 100644 --- a/android_webview/java/res/raw/PRESUBMIT.py +++ b/android_webview/java/res/raw/PRESUBMIT.py
@@ -14,7 +14,7 @@ def _CheckHistogramsAllowlist(input_api, output_api): - """Checks that histograms_allowlist.txt contains valid histograms.""" + """Checks that HistogramsAllowlist.java contains valid histograms.""" src_path = os.path.join(input_api.PresubmitLocalPath(), '..', '..', '..', '..') histograms_path = os.path.join(src_path, 'tools', 'metrics', 'histograms')
diff --git a/android_webview/java/res/raw/histograms_allowlist.txt b/android_webview/java/res/raw/histograms_allowlist.txt deleted file mode 100644 index be8099d..0000000 --- a/android_webview/java/res/raw/histograms_allowlist.txt +++ /dev/null
@@ -1,20 +0,0 @@ -Android.WebView.HistoricalApplicationExitInfo.Counts2.FOREGROUND -Android.WebView.SafeMode.ActionName -Android.WebView.SafeMode.ReceivedFix -Android.WebView.SafeMode.SafeModeEnabled -Android.WebView.SitesVisitedWeekly -Android.WebView.Startup.CreationTime.Stage1.FactoryInit -Android.WebView.Startup.CreationTime.StartChromiumLocked -Android.WebView.Startup.CreationTime.TotalFactoryInitTime -Android.WebView.Visibility.Global -Android.WebView.VisibleScreenCoverage.PerWebView.data -Android.WebView.VisibleScreenCoverage.PerWebView.file -Android.WebView.VisibleScreenCoverage.PerWebView.http -Android.WebView.VisibleScreenCoverage.PerWebView.https -Autofill.WebView.Enabled -Memory.Total.PrivateMemoryFootprint -PageLoad.InteractiveTiming.InputDelay3 -PageLoad.InteractiveTiming.UserInteractionLatency.HighPercentile2.MaxEventDuration -PageLoad.PaintTiming.NavigationToFirstContentfulPaint -PageLoad.PaintTiming.NavigationToLargestContentfulPaint2 -Power.ForegroundBatteryDrain.30SecondsAvg2 \ No newline at end of file
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 74bfaed..4feb465 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
@@ -18,6 +18,7 @@ import org.chromium.components.metrics.MetricsFeatures; import org.chromium.components.metrics.MetricsSwitches; import org.chromium.components.network_session_configurator.NetworkSessionSwitches; +import org.chromium.components.payments.PaymentFeatureList; import org.chromium.components.permissions.PermissionsAndroidFeatureList; import org.chromium.components.safe_browsing.SafeBrowsingFeatures; import org.chromium.components.sensitive_content.SensitiveContentFeatures; @@ -1031,6 +1032,14 @@ "Enable the JavaScript PaymentRequest API for launching payment apps through" + " Android intents."), Flag.baseFeature( + PaymentFeatureList.UPDATE_PAYMENT_DETAILS_INTENT_FILTER_IN_PAYMENT_APP, + "PaymentRequest looks up the dynamic price updates service in the payment app," + + " via an intent filter."), + Flag.baseFeature( + PaymentFeatureList.ANDROID_PAYMENT_INTENTS_OMIT_DEPRECATED_PARAMETERS, + "Omit the deprecated parameters from the intents that are sent to " + + "Android payment apps in the PaymentRequest API."), + Flag.baseFeature( GpuFeatures.WEB_GPU_USE_VULKAN_MEMORY_MODEL, "Use the Vulkan Memory Model from WebGPU when available"), Flag.baseFeature("RunBeforeUnloadClosureOnStackInvestigation"),
diff --git a/android_webview/java/src/org/chromium/android_webview/metrics/HistogramsAllowlist.java b/android_webview/java/src/org/chromium/android_webview/metrics/HistogramsAllowlist.java index fc2be26c..ce0f330 100644 --- a/android_webview/java/src/org/chromium/android_webview/metrics/HistogramsAllowlist.java +++ b/android_webview/java/src/org/chromium/android_webview/metrics/HistogramsAllowlist.java
@@ -4,25 +4,16 @@ package org.chromium.android_webview.metrics; -import android.content.Context; - -import org.chromium.android_webview.R; -import org.chromium.base.ContextUtils; -import org.chromium.base.JavaUtils; import org.chromium.components.metrics.HistogramEventProtos.HistogramEventProto; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.util.HashSet; import java.util.Set; /** * Keeps a list of which histograms to upload if histograms filtering is applied. * - * <p>histograms_allowlist.txt contains histograms that will be sampled at 100%. This is not done - * for all histograms in order to preserve network usage and storage. See + * <p>The list below contains histograms that will be sampled at 100%. This is not done for all + * histograms in order to preserve network usage and storage. See * go/clank-webview-uma#histograms-allowlist-guidance for reasons to add your histogram to it and * how to do it safely. */ @@ -34,17 +25,34 @@ } public static HistogramsAllowlist load() { - Context appContext = ContextUtils.getApplicationContext(); - InputStream inputStream = - appContext.getResources().openRawResource(R.raw.histograms_allowlist); + String[] histogramsAllowlist = + new String[] { + // histograms_allowlist_check START_PARSING + "Android.WebView.HistoricalApplicationExitInfo.Counts2.FOREGROUND", + "Android.WebView.SafeMode.ActionName", + "Android.WebView.SafeMode.ReceivedFix", + "Android.WebView.SafeMode.SafeModeEnabled", + "Android.WebView.SitesVisitedWeekly", + "Android.WebView.Startup.CreationTime.Stage1.FactoryInit", + "Android.WebView.Startup.CreationTime.StartChromiumLocked", + "Android.WebView.Startup.CreationTime.TotalFactoryInitTime", + "Android.WebView.Visibility.Global", + "Android.WebView.VisibleScreenCoverage.PerWebView.data", + "Android.WebView.VisibleScreenCoverage.PerWebView.file", + "Android.WebView.VisibleScreenCoverage.PerWebView.http", + "Android.WebView.VisibleScreenCoverage.PerWebView.https", + "Autofill.WebView.Enabled", + "Memory.Total.PrivateMemoryFootprint", + "PageLoad.InteractiveTiming.InputDelay3", + "PageLoad.InteractiveTiming.UserInteractionLatency.HighPercentile2.MaxEventDuration", + "PageLoad.PaintTiming.NavigationToFirstContentfulPaint", + "PageLoad.PaintTiming.NavigationToLargestContentfulPaint2", + "Power.ForegroundBatteryDrain.30SecondsAvg2", + // histograms_allowlist_check END_PARSING + }; Set<Long> hashes = new HashSet(); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { - String line; - while ((line = reader.readLine()) != null) { - hashes.add(AwMetricsUtils.hashHistogramName(line)); - } - } catch (IOException e) { - JavaUtils.throwUnchecked(e); + for (String histogram : histogramsAllowlist) { + hashes.add(AwMetricsUtils.hashHistogramName(histogram)); } return new HistogramsAllowlist(hashes);
diff --git a/android_webview/tools/cts_config/webview_cts_gcs_path.json b/android_webview/tools/cts_config/webview_cts_gcs_path.json index c787f28..bf78f28 100644 --- a/android_webview/tools/cts_config/webview_cts_gcs_path.json +++ b/android_webview/tools/cts_config/webview_cts_gcs_path.json
@@ -244,10 +244,9 @@ "force_full_mode": true } ], - "excludes": [ + "includes": [ { - "match": "android.view.inputmethod.cts.KeyboardVisibilityControlTest#testShowHideKeyboardOnWebView", - "_bug_id": "crbug.com/408990245" + "match": "android.view.inputmethod.cts.KeyboardVisibilityControlTest#testShowHideKeyboardOnWebView" } ] }, @@ -274,14 +273,6 @@ "_bug_id": "crbug.com/1369088" }, { - "match": "android.autofillservice.cts.inline.InlineWebViewActivityTest#testAutofillNoDatasets", - "_bug_id": "crbug.com/409004450" - }, - { - "match": "android.autofillservice.cts.inline.InlineWebViewActivityTest#testAutofillOneDataset", - "_bug_id": "crbug.com/409004450" - }, - { "match": "android.autofillservice.cts.inline.InlineAugmentedWebViewActivityTest#testAugmentedAutoFill_startTypingHideInline", "_bug_id": "crbug.com/1369088" } @@ -392,14 +383,6 @@ "_bug_id": "crbug.com/1369088" }, { - "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testAutofillNoDatasets", - "_bug_id": "crbug.com/408979469" - }, - { - "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testAutofillOneDataset", - "_bug_id": "crbug.com/408979469" - }, - { "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testSaveOnly", "_bug_id": "crbug.com/1369088" }, @@ -430,6 +413,9 @@ ], "includes": [ { + "match": "android.view.inputmethod.cts.KeyboardVisibilityControlTest#testShowHideKeyboardOnWebView" + }, + { "match": "android.view.inputmethod.cts.InputMethodServiceTest#testBatchEdit_commitAndSetComposingRegion_webView" }, { @@ -438,12 +424,6 @@ { "match": "android.view.inputmethod.cts.InputMethodServiceTest#testBatchEdit_commitSpaceThenSetComposingRegion_webView" } - ], - "excludes": [ - { - "match": "android.view.inputmethod.cts.KeyboardVisibilityControlTest#testShowHideKeyboardOnWebView", - "_bug_id": "crbug.com/408990245" - } ] }, { @@ -553,14 +533,6 @@ "_bug_id": "crbug.com/1369088" }, { - "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testAutofillNoDatasets", - "_bug_id": "crbug.com/408979469" - }, - { - "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testAutofillOneDataset", - "_bug_id": "crbug.com/408979469" - }, - { "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testSaveOnly", "_bug_id": "crbug.com/1369088" }, @@ -697,14 +669,6 @@ "_bug_id": "crbug.com/1369088" }, { - "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testAutofillNoDatasets", - "_bug_id": "crbug.com/408979469" - }, - { - "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testAutofillOneDataset", - "_bug_id": "crbug.com/408979469" - }, - { "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testSaveOnly", "_bug_id": "crbug.com/1369088" }, @@ -841,14 +805,6 @@ "_bug_id": "crbug.com/1369088" }, { - "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testAutofillNoDatasets", - "_bug_id": "crbug.com/408979469" - }, - { - "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testAutofillOneDataset", - "_bug_id": "crbug.com/408979469" - }, - { "match": "android.autofillservice.cts.dropdown.WebViewActivityTest#testSaveOnly", "_bug_id": "crbug.com/1369088" },
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java index d2a7cdf..01fcc52 100644 --- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java +++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
@@ -99,6 +99,7 @@ } @Override + @SuppressWarnings("GestureBackNavigation") public void onBackPressed() { if (mWebView != null && mWebView.canGoBack()) { mWebView.goBack();
diff --git a/ash/ambient/ambient_controller.cc b/ash/ambient/ambient_controller.cc index 2852961..a47c9744 100644 --- a/ash/ambient/ambient_controller.cc +++ b/ash/ambient/ambient_controller.cc
@@ -177,15 +177,6 @@ return IsUserAmbientModeEnabled() || IsAmbientModeManagedScreensaverEnabled(); } -class AmbientWidgetDelegate : public views::WidgetDelegate { - public: - AmbientWidgetDelegate() { - SetCanFullscreen(true); - SetCanMaximize(true); - SetOwnedByWidget(true); - } -}; - void RecordManagedScreensaverEnabledPref() { if (PrefService* pref_service = GetActivePrefService(); pref_service && @@ -198,6 +189,15 @@ } // namespace +class AmbientWidgetDelegate : public views::WidgetDelegate { + public: + AmbientWidgetDelegate() { + SetCanFullscreen(true); + SetCanMaximize(true); + SetOwnedByWidget(true); + } +}; + // static void AmbientController::RegisterProfilePrefs(PrefRegistrySimple* registry) { registry->RegisterStringPref(ash::ambient::prefs::kAmbientBackdropClientId,
diff --git a/ash/auth/active_session_auth_controller_impl.cc b/ash/auth/active_session_auth_controller_impl.cc index 632323b..fb69da0 100644 --- a/ash/auth/active_session_auth_controller_impl.cc +++ b/ash/auth/active_session_auth_controller_impl.cc
@@ -70,32 +70,6 @@ return {}; } -std::unique_ptr<views::Widget> CreateAuthDialogWidget( - std::unique_ptr<views::View> contents_view) { - views::Widget::InitParams params( - views::Widget::InitParams::CLIENT_OWNS_WIDGET, - views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); - params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; - params.delegate = new views::WidgetDelegate(); - params.show_state = ui::mojom::WindowShowState::kNormal; - CHECK_EQ(Shell::Get()->session_controller()->GetSessionState(), - session_manager::SessionState::ACTIVE); - params.parent = Shell::GetPrimaryRootWindow()->GetChildById( - kShellWindowId_SystemModalContainer); - params.autosize = true; - params.name = "AuthDialogWidget"; - - params.delegate->SetInitiallyFocusedView(contents_view.get()); - params.delegate->SetModalType(ui::mojom::ModalType::kSystem); - params.delegate->SetOwnedByWidget(true); - - std::unique_ptr<views::Widget> widget = std::make_unique<views::Widget>(); - widget->Init(std::move(params)); - widget->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE); - widget->SetContentsView(std::move(contents_view)); - return widget; -} - const char* ReasonToString(AuthRequest::Reason reason) { switch (reason) { case AuthRequest::Reason::kPasswordManager: @@ -448,7 +422,28 @@ account_id_, title_, description_, available_factors_); contents_view_ = contents_view.get(); - widget_ = CreateAuthDialogWidget(std::move(contents_view)); + views::Widget::InitParams params( + views::Widget::InitParams::CLIENT_OWNS_WIDGET, + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; + params.delegate = new views::WidgetDelegate(); + params.show_state = ui::mojom::WindowShowState::kNormal; + CHECK_EQ(Shell::Get()->session_controller()->GetSessionState(), + session_manager::SessionState::ACTIVE); + params.parent = Shell::GetPrimaryRootWindow()->GetChildById( + kShellWindowId_SystemModalContainer); + params.autosize = true; + params.name = "AuthDialogWidget"; + + params.delegate->SetInitiallyFocusedView(contents_view.get()); + params.delegate->SetModalType(ui::mojom::ModalType::kSystem); + params.delegate->SetOwnedByWidget(true); + + widget_ = std::make_unique<views::Widget>(); + widget_->Init(std::move(params)); + widget_->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE); + widget_->SetContentsView(std::move(contents_view)); + contents_view_observer_.Observe(contents_view_); contents_view_->AddObserver(this); SetState(ActiveSessionAuthState::kInitialized);
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index b1ffe1c..0c50557 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -748,7 +748,7 @@ // Settings > Privacy controls. BASE_FEATURE(kEnableToggleCameraShortcut, "EnableToggleCameraShortcut", - base::FEATURE_ENABLED_BY_DEFAULT); + base::FEATURE_DISABLED_BY_DEFAULT); // TODO:(b/345017297): If enabled, touchscreen mapping experience is visible in // settings. @@ -1186,7 +1186,7 @@ // Enables the App launch keyboard shortcut. BASE_FEATURE(kAppLaunchShortcut, "AppLaunchShortcut", - base::FEATURE_ENABLED_BY_DEFAULT); + base::FEATURE_DISABLED_BY_DEFAULT); // Enables the Game Dashboard's Record Game feature. This flag is to be enabled // by the feature management module.
diff --git a/ash/frame/wide_frame_view.cc b/ash/frame/wide_frame_view.cc index fdb6850..d51e04b 100644 --- a/ash/frame/wide_frame_view.cc +++ b/ash/frame/wide_frame_view.cc
@@ -97,9 +97,6 @@ : target_(target), frame_context_menu_controller_( std::make_unique<FrameContextMenuController>(target_, this)) { - // WideFrameView is owned by its client, not by Views. - SetOwnedByWidget(false); - aura::Window* target_window = target->GetNativeWindow(); target_window->AddObserver(this); // Use the HeaderView itself as a frame view because WideFrameView is
diff --git a/ash/in_session_auth/auth_dialog_contents_view_pixeltest.cc b/ash/in_session_auth/auth_dialog_contents_view_pixeltest.cc index 8db0704..5d84289 100644 --- a/ash/in_session_auth/auth_dialog_contents_view_pixeltest.cc +++ b/ash/in_session_auth/auth_dialog_contents_view_pixeltest.cc
@@ -35,8 +35,6 @@ namespace ash { -namespace { - class AuthDialogContentsViewPixelTest : public AshTestBase { public: AuthDialogContentsViewPixelTest() = default; @@ -308,6 +306,4 @@ "fingerprint_light", /*revision_number=*/4, widget.get())); } -} // namespace - } // namespace ash
diff --git a/ash/in_session_auth/auth_dialog_contents_view_unittest.cc b/ash/in_session_auth/auth_dialog_contents_view_unittest.cc index f8c5a81b..29dcb02 100644 --- a/ash/in_session_auth/auth_dialog_contents_view_unittest.cc +++ b/ash/in_session_auth/auth_dialog_contents_view_unittest.cc
@@ -24,8 +24,6 @@ namespace ash { -namespace { - class AuthDialogContentsViewTest : public AshTestBase { public: AuthDialogContentsViewTest() = default; @@ -148,6 +146,4 @@ EXPECT_EQ(data.role, ax::mojom::Role::kStaticText); } -} // namespace - } // namespace ash
diff --git a/ash/in_session_auth/in_session_auth_dialog.cc b/ash/in_session_auth/in_session_auth_dialog.cc index 87858732..b9c8a01 100644 --- a/ash/in_session_auth/in_session_auth_dialog.cc +++ b/ash/in_session_auth/in_session_auth_dialog.cc
@@ -26,29 +26,6 @@ // address bar, for anti-spoofing. constexpr int kTopInsetDp = 36; -std::unique_ptr<views::Widget> CreateAuthDialogWidget( - std::unique_ptr<views::View> contents_view, - aura::Window* parent) { - views::Widget::InitParams params( - views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET, - views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); - params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; - params.delegate = new views::WidgetDelegate(); - params.show_state = ui::mojom::WindowShowState::kNormal; - params.parent = parent; - params.name = "AuthDialogWidget"; - - params.delegate->SetInitiallyFocusedView(contents_view.get()); - params.delegate->SetModalType(ui::mojom::ModalType::kNone); - params.delegate->SetOwnedByWidget(true); - - std::unique_ptr<views::Widget> widget = std::make_unique<views::Widget>(); - widget->Init(std::move(params)); - widget->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE); - widget->SetContentsView(std::move(contents_view)); - return widget; -} - } // namespace InSessionAuthDialog::InSessionAuthDialog( @@ -58,10 +35,26 @@ const AuthDialogContentsView::AuthMethodsMetadata& auth_metadata, const UserAvatar& avatar) : auth_methods_(auth_methods) { - widget_ = CreateAuthDialogWidget( - std::make_unique<AuthDialogContentsView>(auth_methods, origin_name, - auth_metadata, avatar), - parent_window); + views::Widget::InitParams params( + views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET, + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; + params.delegate = new views::WidgetDelegate(); + params.show_state = ui::mojom::WindowShowState::kNormal; + params.parent = parent_window; + params.name = "AuthDialogWidget"; + + auto contents_view = std::make_unique<AuthDialogContentsView>( + auth_methods, origin_name, auth_metadata, avatar); + params.delegate->SetInitiallyFocusedView(contents_view.get()); + params.delegate->SetModalType(ui::mojom::ModalType::kNone); + params.delegate->SetOwnedByWidget(true); + + widget_ = std::make_unique<views::Widget>(); + widget_->Init(std::move(params)); + widget_->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE); + widget_->SetContentsView(std::move(contents_view)); + gfx::Rect bounds = parent_window->GetBoundsInScreen(); gfx::Size preferred_size = widget_->GetContentsView()->GetPreferredSize(); int horizontal_inset_dp = (bounds.width() - preferred_size.width()) / 2;
diff --git a/ash/in_session_auth/in_session_auth_dialog_controller_impl.cc b/ash/in_session_auth/in_session_auth_dialog_controller_impl.cc index 929ab89..893478f3 100644 --- a/ash/in_session_auth/in_session_auth_dialog_controller_impl.cc +++ b/ash/in_session_auth/in_session_auth_dialog_controller_impl.cc
@@ -56,28 +56,6 @@ } } -std::unique_ptr<views::Widget> CreateAuthDialogWidget( - std::unique_ptr<views::View> contents_view) { - views::Widget::InitParams params( - views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET, - views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); - params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; - params.delegate = new views::WidgetDelegate(); - params.show_state = ui::mojom::WindowShowState::kNormal; - params.parent = nullptr; - params.name = "AuthDialogWidget"; - - params.delegate->SetInitiallyFocusedView(contents_view.get()); - params.delegate->SetModalType(ui::mojom::ModalType::kSystem); - params.delegate->SetOwnedByWidget(true); - - std::unique_ptr<views::Widget> widget = std::make_unique<views::Widget>(); - widget->Init(std::move(params)); - widget->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE); - widget->SetContentsView(std::move(contents_view)); - return widget; -} - // TODO(b/271248452): Subscribe to primary display changes, so that the // authentication dialog correctly changes its location to center on new // primary displays. We will need to also listen to `work_area` changes and @@ -183,8 +161,26 @@ contents_view_ = contents_view.get(); out_consumer = contents_view->GetAuthPanel(); - dialog_ = CreateAuthDialogWidget(std::move(contents_view)); + + views::Widget::InitParams params( + views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET, + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; + params.delegate = new views::WidgetDelegate(); + params.show_state = ui::mojom::WindowShowState::kNormal; + params.parent = nullptr; + params.name = "AuthDialogWidget"; + + params.delegate->SetInitiallyFocusedView(contents_view.get()); + params.delegate->SetModalType(ui::mojom::ModalType::kSystem); + params.delegate->SetOwnedByWidget(true); + + dialog_ = std::make_unique<views::Widget>(); + dialog_->Init(std::move(params)); + dialog_->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE); + dialog_->SetContentsView(std::move(contents_view)); dialog_->Show(); + state_ = State::kShown; AuthParts::Get() ->GetLegacyAuthSurfaceRegistry()
diff --git a/ash/login/ui/local_authentication_request_controller_impl.cc b/ash/login/ui/local_authentication_request_controller_impl.cc index f80f8330..8312e0f 100644 --- a/ash/login/ui/local_authentication_request_controller_impl.cc +++ b/ash/login/ui/local_authentication_request_controller_impl.cc
@@ -123,40 +123,6 @@ return {}; } -std::unique_ptr<views::Widget> CreateAuthDialogWidget( - std::unique_ptr<views::View> contents_view) { - views::Widget::InitParams params( - views::Widget::InitParams::CLIENT_OWNS_WIDGET, - views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); - params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; - params.delegate = new views::WidgetDelegate(); - params.show_state = ui::mojom::WindowShowState::kNormal; - - ShellWindowId parent_window_id = - Shell::Get()->session_controller()->GetSessionState() == - session_manager::SessionState::ACTIVE - ? kShellWindowId_SystemModalContainer - : kShellWindowId_LockSystemModalContainer; - params.parent = Shell::GetPrimaryRootWindow()->GetChildById(parent_window_id); - - params.autosize = true; - params.name = "AuthDialogWidget"; - - params.delegate->SetInitiallyFocusedView(contents_view.get()); - // ModalType::kSystem is used to get a semi-transparent background behind the - // local authentication request view, when it is used directly on a widget. - // The overlay consumes all the inputs from the user, so that they can only - // interact with the local authentication request view while it is visible. - params.delegate->SetModalType(ui::mojom::ModalType::kSystem); - params.delegate->SetOwnedByWidget(true); - - auto widget = std::make_unique<views::Widget>(); - widget->Init(std::move(params)); - widget->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE); - widget->SetContentsView(std::move(contents_view)); - return widget; -} - const char* LocalAuthenticationWithPinStateToString( LocalAuthenticationWithPinControllerImpl::LocalAuthenticationWithPinState state) { @@ -245,7 +211,36 @@ account_id_, title_, description_, available_factors_); contents_view_ = contents_view.get(); - widget_ = CreateAuthDialogWidget(std::move(contents_view)); + views::Widget::InitParams params( + views::Widget::InitParams::CLIENT_OWNS_WIDGET, + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent; + params.delegate = new views::WidgetDelegate(); + params.show_state = ui::mojom::WindowShowState::kNormal; + + ShellWindowId parent_window_id = + Shell::Get()->session_controller()->GetSessionState() == + session_manager::SessionState::ACTIVE + ? kShellWindowId_SystemModalContainer + : kShellWindowId_LockSystemModalContainer; + params.parent = Shell::GetPrimaryRootWindow()->GetChildById(parent_window_id); + + params.autosize = true; + params.name = "AuthDialogWidget"; + + params.delegate->SetInitiallyFocusedView(contents_view.get()); + // ModalType::kSystem is used to get a semi-transparent background behind the + // local authentication request view, when it is used directly on a widget. + // The overlay consumes all the inputs from the user, so that they can only + // interact with the local authentication request view while it is visible. + params.delegate->SetModalType(ui::mojom::ModalType::kSystem); + params.delegate->SetOwnedByWidget(true); + + widget_ = std::make_unique<views::Widget>(); + widget_->Init(std::move(params)); + widget_->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE); + widget_->SetContentsView(std::move(contents_view)); + contents_view_observer_.Observe(contents_view_); contents_view_->AddObserver(this); SetState(LocalAuthenticationWithPinState::kInitialized);
diff --git a/ash/shell_unittest.cc b/ash/shell_unittest.cc index 296e68f3..4f00271 100644 --- a/ash/shell_unittest.cc +++ b/ash/shell_unittest.cc
@@ -141,15 +141,6 @@ EXPECT_FALSE(Shell::GetContainer(root_window, kShellWindowId_PhantomWindow)); } -std::unique_ptr<views::WidgetDelegateView> CreateModalWidgetDelegate() { - auto delegate = std::make_unique<views::WidgetDelegateView>(); - delegate->SetCanResize(true); - delegate->SetModalType(ui::mojom::ModalType::kSystem); - delegate->SetOwnedByWidget(true); - delegate->SetTitle(u"Modal Window"); - return delegate; -} - class SimpleMenuDelegate : public ui::SimpleMenuModel::Delegate { public: SimpleMenuDelegate() = default; @@ -170,6 +161,16 @@ class ShellTest : public AshTestBase { public: + static std::unique_ptr<views::WidgetDelegateView> + CreateModalWidgetDelegate() { + auto delegate = std::make_unique<views::WidgetDelegateView>(); + delegate->SetCanResize(true); + delegate->SetModalType(ui::mojom::ModalType::kSystem); + delegate->SetOwnedByWidget(true); + delegate->SetTitle(u"Modal Window"); + return delegate; + } + void TestCreateWindow(views::Widget::InitParams::Type type, bool always_on_top, aura::Window* expected_container) {
diff --git a/ash/webui/boca_ui/boca_app_page_handler.cc b/ash/webui/boca_ui/boca_app_page_handler.cc index 70b990f..21e0c9b 100644 --- a/ash/webui/boca_ui/boca_app_page_handler.cc +++ b/ash/webui/boca_ui/boca_app_page_handler.cc
@@ -270,6 +270,16 @@ void BocaAppHandler::CreateSession(mojom::ConfigPtr config, CreateSessionCallback callback) { + if (config->caption_config) { + NotifyLocalCaptionConfigUpdate(config->caption_config->Clone()); + } + + if (BocaAppClient::Get() + ->GetSessionManager() + ->disabled_on_non_managed_network()) { + std::move(callback).Run(false); + return; + } std::unique_ptr<CreateSessionRequest> request = std::make_unique<CreateSessionRequest>( session_client_impl_->sender(), base_url_, user_identity_, @@ -316,10 +326,6 @@ } session_client_impl_->CreateSession(std::move(request)); - - if (auto caption_config = std::move(config->caption_config)) { - NotifyLocalCaptionConfigUpdate(std::move(caption_config)); - } } void BocaAppHandler::GetSession(GetSessionCallback callback) { @@ -543,6 +549,12 @@ void BocaAppHandler::SubmitAccessCode(const std::string& access_code, SubmitAccessCodeCallback callback) { + if (BocaAppClient::Get() + ->GetSessionManager() + ->disabled_on_non_managed_network()) { + std::move(callback).Run(mojom::SubmitAccessCodeError::kInvalid); + return; + } std::unique_ptr<JoinSessionRequest> request = std::make_unique<JoinSessionRequest>( session_client_impl_->sender(), base_url_, user_identity_,
diff --git a/ash/webui/boca_ui/boca_app_page_handler_unittest.cc b/ash/webui/boca_ui/boca_app_page_handler_unittest.cc index db40ffb..3578680 100644 --- a/ash/webui/boca_ui/boca_app_page_handler_unittest.cc +++ b/ash/webui/boca_ui/boca_app_page_handler_unittest.cc
@@ -246,6 +246,7 @@ MOCK_METHOD(void, LoadCurrentSession, (bool), (override)); MOCK_METHOD(void, ToggleAppStatus, (bool), (override)); MOCK_METHOD(void, NotifyAppReload, (), (override)); + MOCK_METHOD(bool, disabled_on_non_managed_network, (), (override)); ~MockSessionManager() override = default; }; @@ -389,7 +390,6 @@ // Register self as listener. ON_CALL(*boca_app_client(), GetSessionManager()) .WillByDefault(Return(session_manager())); - // Create the WebContents for the BrowserContext. web_contents_ = content::WebContents::Create( content::WebContents::CreateParams(browser_context)); @@ -612,6 +612,8 @@ EXPECT_CALL(*session_manager(), UpdateCurrentSession(_, /*dispatch_event=*/true)) .Times(1); + EXPECT_CALL(*session_manager(), disabled_on_non_managed_network()) + .WillOnce(Return(false)); boca_app_handler()->CreateSession(config->Clone(), future_1.GetCallback()); ASSERT_TRUE(future_1.Wait()); @@ -662,12 +664,49 @@ // Verify local events not dispatched EXPECT_CALL(*session_manager(), NotifyLocalCaptionEvents(_)).Times(0); + EXPECT_CALL(*session_manager(), disabled_on_non_managed_network()) + .WillOnce(Return(false)); boca_app_handler()->CreateSession(config.Clone(), future_1.GetCallback()); ASSERT_TRUE(future_1.Wait()); EXPECT_TRUE(future_1.Get()); } +TEST_F(BocaAppPageHandlerTest, CreateSessionFailedOnNonManagedNetwork) { + // Page handler callback. + base::test::TestFuture<base::expected<std::unique_ptr<::boca::Session>, + google_apis::ApiErrorCode>> + future; + // API callback. + base::test::TestFuture<bool> future_1; + + const auto config = mojom::Config::New( + base::Minutes(2), std::nullopt, nullptr, + std::vector<mojom::IdentityPtr>{}, std::vector<mojom::IdentityPtr>{}, + mojom::OnTaskConfigPtr(nullptr), GetCommonCaptionConfig(), ""); + + ::boca::UserIdentity teacher; + teacher.set_gaia_id(kGaiaId.ToString()); + CreateSessionRequest request( + nullptr, kTestUrlBase, teacher, config->session_duration, + ::boca::Session::SessionState::Session_SessionState_ACTIVE, + future.GetCallback()); + EXPECT_CALL(*session_manager(), disabled_on_non_managed_network()) + .WillOnce(Return(true)); + EXPECT_CALL(*session_client_impl(), CreateSession(_)).Times(0); + + EXPECT_CALL(*session_manager(), + UpdateCurrentSession(_, /*dispatch_event=*/true)) + .Times(0); + + // Verify local events dispatched + EXPECT_CALL(*session_manager(), NotifyLocalCaptionEvents(_)).Times(1); + + boca_app_handler()->CreateSession(config.Clone(), future_1.GetCallback()); + ASSERT_TRUE(future_1.Wait()); + EXPECT_FALSE(future_1.Get()); +} + TEST_F(BocaAppPageHandlerTest, GetSessionWithFullInputTest) { // Page handler callback. base::test::TestFuture<base::expected<std::unique_ptr<::boca::Session>, @@ -1895,6 +1934,8 @@ Invoke([&](auto request) { request->callback().Run(std::make_unique<::boca::Session>()); }))); + EXPECT_CALL(*session_manager(), disabled_on_non_managed_network()) + .WillOnce(Return(false)); boca_app_handler()->SubmitAccessCode("code", future_1.GetCallback()); ASSERT_TRUE(future_1.Wait()); @@ -1924,12 +1965,37 @@ request->callback().Run( base::unexpected(google_apis::ApiErrorCode::HTTP_FORBIDDEN)); }))); + EXPECT_CALL(*session_manager(), disabled_on_non_managed_network()) + .WillOnce(Return(false)); boca_app_handler()->SubmitAccessCode("code", future_1.GetCallback()); ASSERT_TRUE(future_1.Wait()); EXPECT_EQ(mojom::SubmitAccessCodeError::kInvalid, future_1.Get().value()); } +TEST_F(BocaAppPageHandlerTest, JoinSessionFailedDueToNonManagedNetwork) { + EXPECT_CALL(*session_manager(), + UpdateCurrentSession(_, /*dispatch_event=*/true)) + .Times(0); + + // Page handler callback. + base::test::TestFuture<base::expected<std::unique_ptr<::boca::Session>, + google_apis::ApiErrorCode>> + future; + // API callback. + base::test::TestFuture<std::optional<mojom::SubmitAccessCodeError>> future_1; + + JoinSessionRequest request(nullptr, kTestUrlBase, ::boca::UserIdentity(), + "device", "code", future.GetCallback()); + + EXPECT_CALL(*session_client_impl(), JoinSession(_)).Times(0); + EXPECT_CALL(*session_manager(), disabled_on_non_managed_network()) + .WillOnce(Return(true)); + boca_app_handler()->SubmitAccessCode("code", future_1.GetCallback()); + ASSERT_TRUE(future_1.Wait()); + EXPECT_EQ(mojom::SubmitAccessCodeError::kInvalid, future_1.Get().value()); +} + TEST_F(BocaAppPageHandlerTest, ViewScreenSucceeded) { const std::string student_id = "123"; EXPECT_CALL(*spotlight_service(), ViewScreen(student_id, kTestUrlBase, _))
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 fe4b330..70ff740c 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
@@ -57,7 +57,7 @@ class="suggestion" on-click="onClickSuggestion_" tabindex$="[[getSuggestionTabIndex_(index)]]"> - [[suggestion]] + [[i18n(suggestion)]] </cr-button> </template> </iron-selector>
diff --git a/ash/webui/common/resources/sea_pen/sea_pen_suggestions_element.ts b/ash/webui/common/resources/sea_pen/sea_pen_suggestions_element.ts index 2a9cf68..3710c3a1 100644 --- a/ash/webui/common/resources/sea_pen/sea_pen_suggestions_element.ts +++ b/ash/webui/common/resources/sea_pen/sea_pen_suggestions_element.ts
@@ -14,6 +14,7 @@ import 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js'; import type {CrButtonElement} from 'chrome://resources/ash/common/cr_elements/cr_button/cr_button.js'; +import {I18nMixin} from 'chrome://resources/ash/common/cr_elements/i18n_mixin.js'; import {assert} from 'chrome://resources/js/assert.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js'; @@ -52,7 +53,9 @@ }; } -export class SeaPenSuggestionsElement extends PolymerElement { +const SeaPenSuggestionsElementBase = I18nMixin(PolymerElement); + +export class SeaPenSuggestionsElement extends SeaPenSuggestionsElementBase { static get is() { return 'sea-pen-suggestions'; }
diff --git a/ash/webui/common/resources/sea_pen/sea_pen_untranslated_constants.ts b/ash/webui/common/resources/sea_pen/sea_pen_untranslated_constants.ts index c876d2d..484050b0 100644 --- a/ash/webui/common/resources/sea_pen/sea_pen_untranslated_constants.ts +++ b/ash/webui/common/resources/sea_pen/sea_pen_untranslated_constants.ts
@@ -5,34 +5,34 @@ import type {SeaPenSamplePrompt} from './constants.js'; export const SEA_PEN_SUGGESTIONS: string[] = [ - '4k', - 'realistic photo', - 'surreal', - 'beautiful', - 'minimal', - 'sunset', - 'pastel colors', - 'glowing', - 'star-filled sky', - 'dramatic shadows', - 'covered in snow', - 'bioluminescent', - 'long exposure', - 'foggy', - 'galaxy', - 'neon lights', - 'reflections', - 'lightning', - 'bokeh effect', - 'with color grading', - 'volumetric light', - 'negative space', - 'digital art', - 't-rex', - 'unicorn', - 'cats', - 'vector art style', - '3D render', + 'seaPenFreeformSuggestion4K', + 'seaPenFreeformSuggestionRealisticPhoto', + 'seaPenFreeformSuggestionSurreal', + 'seaPenFreeformSuggestionBeautiful', + 'seaPenFreeformSuggestionMinimal', + 'seaPenFreeformSuggestionSunset', + 'seaPenFreeformSuggestionPastelColors', + 'seaPenFreeformSuggestionGlowing', + 'seaPenFreeformSuggestionStarFilledSky', + 'seaPenFreeformSuggestionDramaticShadows', + 'seaPenFreeformSuggestionCoveredInSnow', + 'seaPenFreeformSuggestionBioluminescent', + 'seaPenFreeformSuggestionLongExposure', + 'seaPenFreeformSuggestionFoggy', + 'seaPenFreeformSuggestionGalaxy', + 'seaPenFreeformSuggestionNeonLights', + 'seaPenFreeformSuggestionReflections', + 'seaPenFreeformSuggestionLightning', + 'seaPenFreeformSuggestionBokehEffect', + 'seaPenFreeformSuggestionWithColorGrading', + 'seaPenFreeformSuggestionVolumetricLight', + 'seaPenFreeformSuggestionNegativeSpace', + 'seaPenFreeformSuggestionDigitalArt', + 'seaPenFreeformSuggestionTRex', + 'seaPenFreeformSuggestionUnicorn', + 'seaPenFreeformSuggestionCats', + 'seaPenFreeformSuggestionVectorArtStyle', + 'seaPenFreeformSuggestion3DRender', ]; // These values are used for metrics; do not change or reuse values.
diff --git a/ash/webui/common/sea_pen_resources.cc b/ash/webui/common/sea_pen_resources.cc index 242653f..b4b66df71 100644 --- a/ash/webui/common/sea_pen_resources.cc +++ b/ash/webui/common/sea_pen_resources.cc
@@ -98,6 +98,58 @@ IDS_SEA_PEN_ARIA_ANNOUNCE_SAMPLE_PROMPTS_SHUFFLED}, {"ariaAnnouncePromptSuggestionsShuffled", IDS_SEA_PEN_ARIA_ANNOUNCE_SUGGESTIONS_SHUFFLED}, + {"seaPenFreeformSuggestion4K", IDS_SEA_PEN_FREEFORM_SUGGESTION_4K}, + {"seaPenFreeformSuggestionRealisticPhoto", + IDS_SEA_PEN_FREEFORM_SUGGESTION_REALISTIC_PHOTO}, + {"seaPenFreeformSuggestionSurreal", + IDS_SEA_PEN_FREEFORM_SUGGESTION_SURREAL}, + {"seaPenFreeformSuggestionBeautiful", + IDS_SEA_PEN_FREEFORM_SUGGESTION_BEAUTIFUL}, + {"seaPenFreeformSuggestionMinimal", + IDS_SEA_PEN_FREEFORM_SUGGESTION_MINIMAL}, + {"seaPenFreeformSuggestionSunset", + IDS_SEA_PEN_FREEFORM_SUGGESTION_SUNSET}, + {"seaPenFreeformSuggestionPastelColors", + IDS_SEA_PEN_FREEFORM_SUGGESTION_PASTEL_COLORS}, + {"seaPenFreeformSuggestionGlowing", + IDS_SEA_PEN_FREEFORM_SUGGESTION_GLOWING}, + {"seaPenFreeformSuggestionStarFilledSky", + IDS_SEA_PEN_FREEFORM_SUGGESTION_STAR_FILLED_SKY}, + {"seaPenFreeformSuggestionDramaticShadows", + IDS_SEA_PEN_FREEFORM_SUGGESTION_DRAMATIC_SHADOWS}, + {"seaPenFreeformSuggestionCoveredInSnow", + IDS_SEA_PEN_FREEFORM_SUGGESTION_COVERED_IN_SNOW}, + {"seaPenFreeformSuggestionBioluminescent", + IDS_SEA_PEN_FREEFORM_SUGGESTION_BIOLUMINESCENT}, + {"seaPenFreeformSuggestionLongExposure", + IDS_SEA_PEN_FREEFORM_SUGGESTION_LONG_EXPOSURE}, + {"seaPenFreeformSuggestionFoggy", IDS_SEA_PEN_FREEFORM_SUGGESTION_FOGGY}, + {"seaPenFreeformSuggestionGalaxy", + IDS_SEA_PEN_FREEFORM_SUGGESTION_GALAXY}, + {"seaPenFreeformSuggestionNeonLights", + IDS_SEA_PEN_FREEFORM_SUGGESTION_NEON_LIGHTS}, + {"seaPenFreeformSuggestionReflections", + IDS_SEA_PEN_FREEFORM_SUGGESTION_REFLECTIONS}, + {"seaPenFreeformSuggestionLightning", + IDS_SEA_PEN_FREEFORM_SUGGESTION_LIGHTNING}, + {"seaPenFreeformSuggestionBokehEffect", + IDS_SEA_PEN_FREEFORM_SUGGESTION_BOKEH_EFFECT}, + {"seaPenFreeformSuggestionWithColorGrading", + IDS_SEA_PEN_FREEFORM_SUGGESTION_WITH_COLOR_GRADING}, + {"seaPenFreeformSuggestionVolumetricLight", + IDS_SEA_PEN_FREEFORM_SUGGESTION_VOLUMETRIC_LIGHT}, + {"seaPenFreeformSuggestionNegativeSpace", + IDS_SEA_PEN_FREEFORM_SUGGESTION_NEGATIVE_SPACE}, + {"seaPenFreeformSuggestionDigitalArt", + IDS_SEA_PEN_FREEFORM_SUGGESTION_DIGITAL_ART}, + {"seaPenFreeformSuggestionTRex", IDS_SEA_PEN_FREEFORM_SUGGESTION_T_REX}, + {"seaPenFreeformSuggestionUnicorn", + IDS_SEA_PEN_FREEFORM_SUGGESTION_UNICORN}, + {"seaPenFreeformSuggestionCats", IDS_SEA_PEN_FREEFORM_SUGGESTION_CATS}, + {"seaPenFreeformSuggestionVectorArtStyle", + IDS_SEA_PEN_FREEFORM_SUGGESTION_VECTOR_ART_STYLE}, + {"seaPenFreeformSuggestion3DRender", + IDS_SEA_PEN_FREEFORM_SUGGESTION_3D_RENDER}, }; source->AddLocalizedStrings(kLocalizedStrings); }
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc index 5d3cf06..7e85bc53 100644 --- a/ash/wm/desks/desks_unittests.cc +++ b/ash/wm/desks/desks_unittests.cc
@@ -176,6 +176,30 @@ namespace ash { +// A widget delegate that refuses to close. +class StuckWidgetDelegate : public views::WidgetDelegate { + public: + StuckWidgetDelegate() { + SetCanMaximize(true); + SetCanMinimize(true); + SetCanResize(true); + SetOwnedByWidget(true); + } + StuckWidgetDelegate(const StuckWidgetDelegate& other) = delete; + StuckWidgetDelegate& operator=(const StuckWidgetDelegate& other) = delete; + ~StuckWidgetDelegate() override = default; + + // Overridden from WidgetDelegate: + std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView( + views::Widget* widget) override { + return Shell::Get()->CreateDefaultNonClientFrameView(widget); + } + + bool OnCloseRequested(views::Widget::ClosedReason close_reason) override { + return false; + } +}; + namespace { using ::testing::ElementsAre; @@ -427,30 +451,6 @@ bool is_fullscreen_ = false; }; -// A widget delegate that refuses to close. -class StuckWidgetDelegate : public views::WidgetDelegate { - public: - StuckWidgetDelegate() { - SetCanMaximize(true); - SetCanMinimize(true); - SetCanResize(true); - SetOwnedByWidget(true); - } - StuckWidgetDelegate(const StuckWidgetDelegate& other) = delete; - StuckWidgetDelegate& operator=(const StuckWidgetDelegate& other) = delete; - ~StuckWidgetDelegate() override = default; - - // Overridden from WidgetDelegate: - std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView( - views::Widget* widget) override { - return Shell::Get()->CreateDefaultNonClientFrameView(widget); - } - - bool OnCloseRequested(views::Widget::ClosedReason close_reason) override { - return false; - } -}; - struct DesksTestParams { bool use_touch_gestures = false; bool use_16_desks = false;
diff --git a/ash/wm/lock_layout_manager_unittest.cc b/ash/wm/lock_layout_manager_unittest.cc index f34aa4a..27f5f197 100644 --- a/ash/wm/lock_layout_manager_unittest.cc +++ b/ash/wm/lock_layout_manager_unittest.cc
@@ -27,8 +27,6 @@ namespace ash { -namespace { - // A login implementation of WidgetDelegate. class LoginTestWidgetDelegate : public views::WidgetDelegate { public: @@ -51,8 +49,6 @@ raw_ptr<views::Widget> widget_; }; -} // namespace - class LockLayoutManagerTest : public AshTestBase { public: void SetUp() override {
diff --git a/base/android/java/src/org/chromium/base/BinderCallsListener.java b/base/android/java/src/org/chromium/base/BinderCallsListener.java index d44b1cb..a49d472 100644 --- a/base/android/java/src/org/chromium/base/BinderCallsListener.java +++ b/base/android/java/src/org/chromium/base/BinderCallsListener.java
@@ -188,10 +188,8 @@ mInvocationHandler); mImplementation = implementation; } catch (Exception e) { - // Undocumented API, do not fail if it changes. Pretend that it has been installed - // to not attempt it later. + // Undocumented API, do not fail if it changes. Log.w(TAG, "Failed to create the listener proxy. Has the framework changed?"); - mInstalled = true; } } @@ -212,6 +210,21 @@ return installListener(mImplementation); } + /** + * Get the total time spent in Binder calls since the listener was installed, if it was + * installed. + * + * <p>NOTE: The current implementation of BinderCallsListener is *very* exhaustive. This method + * will include time spent in Binder calls that originated from outside of Chrome too. + * + * @return time spent in Binder calls in milliseconds since the listener was installed or null. + */ + @Nullable + public Long getTimeSpentInBinderCalls() { + if (!mInstalled || mInvocationHandler == null) return null; + return mInvocationHandler.getTimeSpentInBinderCalls(); + } + private boolean installListener(@Nullable Object listener) { if (mInstalled) return false; @@ -255,8 +268,13 @@ private @Nullable BiConsumer<String, String> mObserver; private int mCurrentTransactionId; private int mNumUploads; + private long mTotalTimeSpentInBinderCallsMillis; private long mCurrentTransactionStartTimeMillis; + public long getTimeSpentInBinderCalls() { + return mTotalTimeSpentInBinderCallsMillis; + } + @Override public @Nullable Object invoke(Object proxy, Method method, Object[] args) { if (!ThreadUtils.runningOnUiThread()) return null; @@ -282,6 +300,10 @@ return null; case "onTransactEnded": TraceEvent.end("BinderCallsListener.invoke", mCurrentInterfaceDescriptor); + + long transactionDurationMillis = + SystemClock.uptimeMillis() - mCurrentTransactionStartTimeMillis; + mTotalTimeSpentInBinderCallsMillis += transactionDurationMillis; if (mObserver != null) { mObserver.accept("onTransactEnded", mCurrentInterfaceDescriptor); } @@ -291,9 +313,6 @@ return null; } - long transactionDurationMillis = - SystemClock.uptimeMillis() - mCurrentTransactionStartTimeMillis; - // Only report a subset of slow calls for non-local builds. boolean shouldReportSlowCall = transactionDurationMillis >= LONG_BINDER_CALL_LIMIT_MILLIS @@ -303,7 +322,8 @@ // If there was a new Binder call introduced, consider moving it to a // background thread if possible. If not, add it to the allow list. String message = - "BinderCallsListener detected a slow call on the UI thread by: " + "This is not a crash. BinderCallsListener detected a slow call on" + + " the UI thread by: " + mCurrentInterfaceDescriptor + " with duration=" + transactionDurationMillis
diff --git a/base/android/java/src/org/chromium/base/Callback.java b/base/android/java/src/org/chromium/base/Callback.java index 4d56928d..7a64361 100644 --- a/base/android/java/src/org/chromium/base/Callback.java +++ b/base/android/java/src/org/chromium/base/Callback.java
@@ -7,6 +7,7 @@ import org.jni_zero.CalledByNative; import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; import org.chromium.build.annotations.Nullable; import java.util.Optional; @@ -43,6 +44,7 @@ * @param callback The {@link Callback} to run. * @param object The payload to provide to the callback (may be null). */ + @NullUnmarked // https://github.com/uber/NullAway/issues/1075 static <T extends @Nullable Object> void runNullSafe(@Nullable Callback<T> callback, T object) { if (callback != null) callback.onResult(object); }
diff --git a/base/check.cc b/base/check.cc index 49e97f1..fa5f814 100644 --- a/base/check.cc +++ b/base/check.cc
@@ -2,11 +2,6 @@ // 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/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "base/check.h" #include <optional>
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h index 19e3f2f..fa9c289 100644 --- a/base/trace_event/builtin_categories.h +++ b/base/trace_event/builtin_categories.h
@@ -153,6 +153,13 @@ perfetto::Category("page-serialization"), perfetto::Category("paint_preview"), perfetto::Category("pepper"), + perfetto::Category("performance_scenarios").SetDescription( + "Includes events when processes enter and leave states defined in " + "//components/performance_manager/scenario_api/" + "performance_scenarios.h. For each scenario type, events for " + "ScenarioScope::kCurrentProcess are emitted to an async track under " + "each process track, and events for ScenarioScope::kGlobal are emitted " + "to global async tracks."), perfetto::Category("persistent_cache"), perfetto::Category("PlatformMalloc"), perfetto::Category("power"),
diff --git a/base/version_info/android/java/VersionConstants.java.version b/base/version_info/android/java/VersionConstants.java.version index ad319bd..f0d7980 100644 --- a/base/version_info/android/java/VersionConstants.java.version +++ b/base/version_info/android/java/VersionConstants.java.version
@@ -4,8 +4,11 @@ package org.chromium.base.version_info; +import org.chromium.build.annotations.NullMarked; + // Constants shared by Android Chrome and WebView. Chrome specific constants are // in ChromeVersionConstants. +@NullMarked public class VersionConstants { public static final String PRODUCT_VERSION = "@MAJOR@.@MINOR@.@BUILD@.@PATCH@"; @SuppressWarnings({"ComplexBooleanConstant", "IdentityBinaryExpression"})
diff --git a/build/android/pylib/utils/device_dependencies.py b/build/android/pylib/utils/device_dependencies.py index 8bb14cf..7e24e10 100644 --- a/build/android/pylib/utils/device_dependencies.py +++ b/build/android/pylib/utils/device_dependencies.py
@@ -26,6 +26,7 @@ re.compile(r'.*lib.java/.*'), # Never need java intermediates. # Test filter files: + re.compile(r'.*/clank/build/bot/filters/.*'), re.compile(r'.*/testing/buildbot/filters/.*'), # Chrome external extensions config file. @@ -36,9 +37,12 @@ re.compile(r'.*icudtl\.bin'), # Scripts that are needed by swarming, but not on devices: + re.compile(r'.*goldctl'), + re.compile(r'.*llvm-readelf'), + re.compile(r'.*llvm-readobj'), re.compile(r'.*llvm-symbolizer'), - re.compile(r'.*devil_util_(?:bin|dist)'), - re.compile(r'.*md5sum_(?:bin|dist)'), + re.compile(r'.*devil_util_(?:bin|dist|host)'), + re.compile(r'.*md5sum_(?:bin|dist|host)'), re.compile(r'.*/development/scripts/stack'), re.compile(r'.*/build/android/pylib/symbols'), re.compile(r'.*/build/android/stacktrace'), @@ -50,6 +54,7 @@ # Our tests don't need these. re.compile(r'.*/devtools-frontend/.*front_end/.*'), + re.compile(r'.*/devtools-frontend/.*inspector_overlay/.*'), # Build artifacts: re.compile(r'.*\.stamp'),
diff --git a/build/rust/allocator/BUILD.gn b/build/rust/allocator/BUILD.gn index 06aa47f..f09314a 100644 --- a/build/rust/allocator/BUILD.gn +++ b/build/rust/allocator/BUILD.gn
@@ -12,6 +12,9 @@ rust_allocator_uses_partition_alloc = use_partition_alloc_as_malloc } +use_cpp_allocator_impls = + rust_allocator_uses_partition_alloc || (is_win && is_asan) + buildflag_header("buildflags") { header = "buildflags.h" flags = [ @@ -30,16 +33,24 @@ crate_root = "lib.rs" cxx_bindings = [ "lib.rs" ] - deps = [ - ":allocator_impls", - ":allocator_shim_definitions", - ] + deps = [ ":allocator_impls" ] no_chromium_prelude = true no_allocator_crate = true allow_unsafe = true + + if (use_cpp_allocator_impls) { + rustflags = [ + "--cfg", + "use_cpp_allocator_impls", + ] + } + + configs -= [ "//build/config/compiler:disallow_unstable_features" ] } + # TODO(crbug.com/408221149): don't build this when `use_cpp_allocator_impls` + # is false. static_library("allocator_impls") { public_deps = [] if (rust_allocator_uses_partition_alloc) { @@ -47,44 +58,19 @@ } sources = [ - "allocator_impls.cc", - "allocator_impls.h", - ] - - deps = [ - ":allocator_cpp_shared", - ":buildflags", - - # TODO(crbug.com/408221149): remove the C++ -> Rust dependency for the - # default allocator. - "//build/rust/std", - ] - - visibility = [ ":*" ] - } - - source_set("allocator_shim_definitions") { - sources = [ "allocator_shim_definitions.cc" ] - - deps = [ ":allocator_cpp_shared" ] - - visibility = [ ":*" ] - } - - source_set("allocator_cpp_shared") { - sources = [ # `alias.*`, `compiler_specific.h`, and `immediate_crash.*` have been # copied from `//base`. # TODO(crbug.com/40279749): Avoid duplication / reuse code. "alias.cc", "alias.h", + "allocator_impls.cc", + "allocator_impls.h", "compiler_specific.h", "immediate_crash.h", ] - visibility = [ - ":allocator_impls", - ":allocator_shim_definitions", - ] + deps = [ ":buildflags" ] + + visibility = [ ":*" ] } }
diff --git a/build/rust/allocator/allocator_impls.cc b/build/rust/allocator/allocator_impls.cc index 1fde98f2..bf3c2a30 100644 --- a/build/rust/allocator/allocator_impls.cc +++ b/build/rust/allocator/allocator_impls.cc
@@ -101,16 +101,6 @@ #define USE_WIN_ALIGNED_MALLOC 0 #endif -// The default allocator functions provided by the Rust standard library. -extern "C" void* __rdl_alloc(size_t size, size_t align); -extern "C" void __rdl_dealloc(void* p, size_t size, size_t align); -extern "C" void* __rdl_realloc(void* p, - size_t old_size, - size_t align, - size_t new_size); - -extern "C" void* __rdl_alloc_zeroed(size_t size, size_t align); - namespace rust_allocator_internal { unsigned char* alloc(size_t size, size_t align) { @@ -129,7 +119,8 @@ #elif USE_WIN_ALIGNED_MALLOC return static_cast<unsigned char*>(_aligned_malloc(size, align)); #else - return static_cast<unsigned char*>(__rdl_alloc(size, align)); + // TODO(crbug.com/408221149): don't build this file in this case. + IMMEDIATE_CRASH(); #endif } @@ -143,7 +134,8 @@ #elif USE_WIN_ALIGNED_MALLOC return _aligned_free(p); #else - __rdl_dealloc(p, size, align); + // TODO(crbug.com/408221149): don't build this file in this case. + IMMEDIATE_CRASH(); #endif } @@ -162,8 +154,8 @@ #elif USE_WIN_ALIGNED_MALLOC return static_cast<unsigned char*>(_aligned_realloc(p, new_size, align)); #else - return static_cast<unsigned char*>( - __rdl_realloc(p, old_size, align, new_size)); + // TODO(crbug.com/408221149): don't build this file in this case. + IMMEDIATE_CRASH(); #endif } @@ -179,8 +171,14 @@ } return p; #else - return static_cast<unsigned char*>(__rdl_alloc_zeroed(size, align)); + // TODO(crbug.com/408221149): don't build this file in this case. + IMMEDIATE_CRASH(); #endif } +void crash_immediately() { + NO_CODE_FOLDING(); + IMMEDIATE_CRASH(); +} + } // namespace rust_allocator_internal
diff --git a/build/rust/allocator/allocator_impls.h b/build/rust/allocator/allocator_impls.h index afb3354..e90ab7c 100644 --- a/build/rust/allocator/allocator_impls.h +++ b/build/rust/allocator/allocator_impls.h
@@ -20,6 +20,8 @@ size_t new_size); unsigned char* alloc_zeroed(size_t size, size_t align); +void crash_immediately(); + } // namespace rust_allocator_internal #endif // BUILD_RUST_ALLOCATOR_ALLOCATOR_IMPLS_H_
diff --git a/build/rust/allocator/allocator_shim_definitions.cc b/build/rust/allocator/allocator_shim_definitions.cc deleted file mode 100644 index a4d1bd77..0000000 --- a/build/rust/allocator/allocator_shim_definitions.cc +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2025 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <cstddef> - -#include "build/rust/allocator/alias.h" -#include "build/rust/allocator/immediate_crash.h" - -extern "C" { - -// As part of rustc's contract for using `#[global_allocator]` without -// rustc-generated shims we must define this symbol, since we are opting in to -// unstable functionality. See https://github.com/rust-lang/rust/issues/123015 -// -// Mark it weak since rustc will generate it when it drives linking. -[[maybe_unused]] -__attribute__((weak)) unsigned char __rust_no_alloc_shim_is_unstable; - -__attribute__((weak)) void __rust_alloc_error_handler(size_t size, - size_t align) { - NO_CODE_FOLDING(); - IMMEDIATE_CRASH(); -} - -__attribute__(( - weak)) extern const unsigned char __rust_alloc_error_handler_should_panic = - 0; - -} // extern "C"
diff --git a/build/rust/allocator/lib.rs b/build/rust/allocator/lib.rs index 7f4a0fc..b8b67d9 100644 --- a/build/rust/allocator/lib.rs +++ b/build/rust/allocator/lib.rs
@@ -8,10 +8,20 @@ //! the allocator defined here. Currently this is a thin wrapper around //! allocator_impls.cc's functions; see the documentation there. +// Required to apply weak linkage to symbols. +#![feature(linkage)] +// Required to apply `#[rustc_std_internal_symbol]` to our alloc error handler +// so the name is correctly mangled as rustc expects. +#![cfg_attr(mangle_alloc_error_handler, allow(internal_features))] +#![cfg_attr(mangle_alloc_error_handler, feature(rustc_attrs))] + +#[cfg(use_cpp_allocator_impls)] use std::alloc::{GlobalAlloc, Layout}; +#[cfg(use_cpp_allocator_impls)] struct Allocator; +#[cfg(use_cpp_allocator_impls)] unsafe impl GlobalAlloc for Allocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { unsafe { ffi::alloc(layout.size(), layout.align()) } @@ -32,9 +42,36 @@ } } +#[cfg(use_cpp_allocator_impls)] #[global_allocator] static GLOBAL: Allocator = Allocator; +#[cfg(not(use_cpp_allocator_impls))] +#[global_allocator] +static GLOBAL: std::alloc::System = std::alloc::System; + +// As part of rustc's contract for using `#[global_allocator]` without +// rustc-generated shims we must define this symbol, since we are opting in to +// unstable functionality. See https://github.com/rust-lang/rust/issues/123015 +#[no_mangle] +#[linkage = "weak"] +static __rust_no_alloc_shim_is_unstable: u8 = 0; + +#[no_mangle] +#[linkage = "weak"] +static __rust_alloc_error_handler_should_panic: u8 = 0; + +// Mangle the symbol name as rustc expects. +#[cfg_attr(mangle_alloc_error_handler, rustc_std_internal_symbol)] +#[cfg_attr(not(mangle_alloc_error_handler), no_mangle)] +#[linkage = "weak"] +fn __rust_alloc_error_handler(_size: usize, _align: usize) { + unsafe { ffi::crash_immediately() } +} + +// TODO(crbug.com/408221149): conditionally include the FFI glue based on +// `use_cpp_allocator_impls` +#[allow(dead_code)] #[cxx::bridge(namespace = "rust_allocator_internal")] mod ffi { extern "C++" { @@ -44,5 +81,6 @@ unsafe fn dealloc(p: *mut u8, size: usize, align: usize); unsafe fn realloc(p: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8; unsafe fn alloc_zeroed(size: usize, align: usize) -> *mut u8; + unsafe fn crash_immediately(); } }
diff --git a/cc/input/browser_controls_offset_manager.cc b/cc/input/browser_controls_offset_manager.cc index faf0a59b..d5f66499f 100644 --- a/cc/input/browser_controls_offset_manager.cc +++ b/cc/input/browser_controls_offset_manager.cc
@@ -279,7 +279,6 @@ ? BottomControlsShownRatio() * old_bottom_height / BottomControlsHeight() : BottomControlsShownRatio(); - if (!animate_changes) { // If the min-heights changed when the controls were at the min-height, the // shown ratios need to be snapped to the new min-shown-ratio to keep the @@ -287,10 +286,15 @@ // keep them fully shown even after the heights changed. For any other // cases, we should update the shown ratio so the visible height remains the // same. - if (TopControlsShownRatio() == OldTopControlsMinShownRatio()) + bool min_height_changed = + TopControlsMinHeight() != + old_browser_controls_params_.top_controls_min_height; + if (min_height_changed && + TopControlsShownRatio() == OldTopControlsMinShownRatio()) { new_top_ratio = TopControlsMinShownRatio(); - else if (TopControlsShownRatio() == 1.f) + } else if (TopControlsShownRatio() == 1.f) { new_top_ratio = 1.f; + } if (BottomControlsShownRatio() == OldBottomControlsMinShownRatio()) new_bottom_ratio = BottomControlsMinShownRatio();
diff --git a/cc/input/browser_controls_offset_manager_unittest.cc b/cc/input/browser_controls_offset_manager_unittest.cc index f6194b7..2ecce4f 100644 --- a/cc/input/browser_controls_offset_manager_unittest.cc +++ b/cc/input/browser_controls_offset_manager_unittest.cc
@@ -961,6 +961,24 @@ EXPECT_FLOAT_EQ(20.f, manager->ContentTopOffset()); } +TEST(BrowserControlsOffsetManagerTest, + ControlsStayAtFullHeightWhenPreviousMinHeightEqualledFullHeight) { + MockBrowserControlsOffsetManagerClient client(20.f, 0.5f, 0.5f); + BrowserControlsOffsetManager* manager = client.manager(); + + // Set the min-height to 20. + client.SetBrowserControlsParams({20, 20, 0, 0, false, false}); + + // Change the height to 120. + client.SetBrowserControlsParams({120, 20, 0, 0, false, false}); + EXPECT_FALSE(manager->HasAnimation()); + EXPECT_FLOAT_EQ(120.f, manager->TopControlsHeight()); + EXPECT_FLOAT_EQ(20.f, manager->TopControlsMinHeight()); + // Top controls should stay at the same visible height. + EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); + EXPECT_FLOAT_EQ(120.f, manager->ContentTopOffset()); +} + TEST(BrowserControlsOffsetManagerTest, ControlsAdjustToNewHeight) { MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f); BrowserControlsOffsetManager* manager = client.manager();
diff --git a/cc/layers/tile_display_layer_impl.cc b/cc/layers/tile_display_layer_impl.cc index 5e83881..73038ad 100644 --- a/cc/layers/tile_display_layer_impl.cc +++ b/cc/layers/tile_display_layer_impl.cc
@@ -124,12 +124,19 @@ tiles_.erase(it); } } else { + // If there is a valid TileResource, import it in order to track its usage. + if (auto* resource = std::get_if<TileResource>(&contents)) { + layer_->ImportResource(resource->resource); + } old_tile = std::exchange(tiles_[key], std::make_unique<Tile>(contents)); } if (old_tile) { if (auto* resource = std::get_if<TileResource>(&old_tile->contents())) { - layer_->discarded_resources_.push_back(resource->resource); + // As of now, this will mark only one resource discarded at a time. + // TODO(vikassoni): Optimize to discard resources in batch. This will + // eventually trigger less IPCs back to the Renderer. + layer_->DiscardResource(resource->resource.id); } } } @@ -346,4 +353,12 @@ damage_rect_.Union(damage_rect); } +void TileDisplayLayerImpl::DiscardResource(viz::ResourceId resource) { + client_->DiscardResource(std::move(resource)); +} + +void TileDisplayLayerImpl::ImportResource(viz::TransferableResource resource) { + client_->ImportResource(std::move(resource)); +} + } // namespace cc
diff --git a/cc/layers/tile_display_layer_impl.h b/cc/layers/tile_display_layer_impl.h index daf1d3a..833ae2f6 100644 --- a/cc/layers/tile_display_layer_impl.h +++ b/cc/layers/tile_display_layer_impl.h
@@ -36,6 +36,10 @@ virtual ~Client() = default; virtual void DidAppendQuadsWithResources( const std::vector<viz::TransferableResource>& resource) = 0; + + // To notify client to Import or Discard a TransferableResource. + virtual void ImportResource(viz::TransferableResource resource) = 0; + virtual void DiscardResource(viz::ResourceId resource) = 0; }; struct NoContents {}; @@ -162,10 +166,12 @@ void RecordDamage(const gfx::Rect& damage_rect); + void ImportResource(viz::TransferableResource resource); + void DiscardResource(viz::ResourceId resource); + private: raw_ref<Client> client_; std::vector<std::unique_ptr<Tiling>> tilings_; - std::vector<viz::TransferableResource> discarded_resources_; std::optional<SkColor4f> solid_color_; bool is_backdrop_filter_mask_ = false;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 80605bc4..840bc4e 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -3265,11 +3265,9 @@ viz::CompositorFrame compositor_frame; compositor_frame.metadata = std::move(metadata); - if (!settings_.is_display_tree) { resource_provider_->PrepareSendToParent( resources, &compositor_frame.resource_list, layer_tree_frame_sink_->context_provider()); - } compositor_frame.render_pass_list = std::move(frame->render_passes); // We should always have a valid LocalSurfaceId in LayerTreeImpl unless we
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 15234361..d6ce677e 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -747,6 +747,7 @@ "java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageView.java", "java/src/org/chromium/chrome/browser/ntp/NativePageRootFrameLayout.java", "java/src/org/chromium/chrome/browser/ntp/NewTabPage.java", + "java/src/org/chromium/chrome/browser/ntp/NewTabPageCreationTracker.java", "java/src/org/chromium/chrome/browser/ntp/NewTabPageLaunchOrigin.java", "java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java", "java/src/org/chromium/chrome/browser/ntp/NewTabPageManager.java",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java index f73b13c..0b49a63 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java
@@ -31,6 +31,7 @@ import org.chromium.chrome.browser.profiles.ProfileProvider; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.tab_ui.TabContentManager; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.tab_ui.TabSwitcher; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabGroupModelFilter; @@ -136,7 +137,7 @@ @NonNull BackPressManager backPressManager, @NonNull ObservableSupplier<EdgeToEdgeController> edgeToEdgeSupplier, @Nullable DesktopWindowStateManager desktopWindowStateManager, - @NonNull ObservableSupplier<Boolean> tabModelNotificationDotSupplier, + @NonNull ObservableSupplier<TabModelDotInfo> tabModelNotificationDotSupplier, @NonNull ObservableSupplier<CompositorViewHolder> compositorViewHolderSupplier, @NonNull ObservableSupplier<ShareDelegate> shareDelegateSupplier, @NonNull ObservableSupplier<TabBookmarker> tabBookmarkerSupplier,
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java index 18d1718..532ba4de 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java
@@ -37,6 +37,7 @@ import org.chromium.chrome.browser.profiles.ProfileProvider; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.tab_ui.TabContentManager; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.tab_ui.TabSwitcher; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabGroupModelFilter; @@ -108,7 +109,7 @@ @NonNull BackPressManager backPressManager, @NonNull ObservableSupplier<EdgeToEdgeController> edgeToEdgeSupplier, @Nullable DesktopWindowStateManager desktopWindowStateManager, - @NonNull ObservableSupplier<Boolean> tabModelNotificationDotSupplier, + @NonNull ObservableSupplier<TabModelDotInfo> tabModelNotificationDotSupplier, @NonNull ObservableSupplier<CompositorViewHolder> compositorViewHolderSupplier, @NonNull ObservableSupplier<ShareDelegate> shareDelegateSupplier, @NonNull ObservableSupplier<TabBookmarker> tabBookmarkerSupplier,
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabModelNotificationDotManager.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabModelNotificationDotManager.java index eef6f4d..b5aeeafa 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabModelNotificationDotManager.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabModelNotificationDotManager.java
@@ -4,10 +4,13 @@ package org.chromium.chrome.browser.tasks.tab_management; +import android.content.Context; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.chromium.base.CallbackController; +import org.chromium.base.Token; import org.chromium.base.lifetime.Destroyable; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; @@ -17,8 +20,10 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.tabmodel.TabGroupModelFilter; import org.chromium.chrome.browser.tabmodel.TabGroupModelFilterObserver; +import org.chromium.chrome.browser.tabmodel.TabGroupTitleUtils; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -47,7 +52,9 @@ public void displayPersistentMessage(PersistentMessage message) { if (message.type != PersistentNotificationType.DIRTY_TAB) return; - if (Boolean.TRUE.equals(mNotificationDotObservableSupplier.get())) return; + if (Boolean.TRUE.equals(mNotificationDotObservableSupplier.get().showDot)) { + return; + } computeUpdate(); } @@ -56,7 +63,9 @@ public void hidePersistentMessage(PersistentMessage message) { if (message.type != PersistentNotificationType.DIRTY_TAB) return; - if (Boolean.FALSE.equals(mNotificationDotObservableSupplier.get())) return; + if (Boolean.FALSE.equals(mNotificationDotObservableSupplier.get().showDot)) { + return; + } computeUpdate(); } @@ -107,15 +116,23 @@ } }; - private final ObservableSupplierImpl<Boolean> mNotificationDotObservableSupplier = - new ObservableSupplierImpl<>(false); + private final ObservableSupplierImpl<TabModelDotInfo> mNotificationDotObservableSupplier = + new ObservableSupplierImpl<>(TabModelDotInfo.HIDE); private final CallbackController mCallbackController = new CallbackController(); + private final Context mContext; private @Nullable MessagingBackendService mMessagingBackendService; private @Nullable TabGroupModelFilter mTabGroupModelFilter; private boolean mTabModelSelectorInitialized; private boolean mMessagingBackendServiceInitialized; /** + * @param context Used to load resources. + */ + public TabModelNotificationDotManager(Context context) { + mContext = context; + } + + /** * Initializes native dependencies of the notification dot manager for the regular tab model. * * @param tabModelSelector The tab model selector to use. Only the regular tab model is @@ -151,7 +168,7 @@ * Returns an {@link ObservableSupplier} that contains true when the notification dot should be * shown. */ - public @NonNull ObservableSupplier<Boolean> getNotificationDotObservableSupplier() { + public @NonNull ObservableSupplier<TabModelDotInfo> getNotificationDotObservableSupplier() { return mNotificationDotObservableSupplier; } @@ -168,8 +185,8 @@ } private void maybeUpdateForTab(Tab tab, boolean mayAddDot) { - @Nullable Boolean showingDot = mNotificationDotObservableSupplier.get(); - boolean stateWillBeUnchanged = showingDot != null && showingDot == mayAddDot; + TabModelDotInfo info = mNotificationDotObservableSupplier.get(); + boolean stateWillBeUnchanged = info.showDot == mayAddDot; if (tab.getTabGroupId() == null || stateWillBeUnchanged) { return; } @@ -178,12 +195,10 @@ private void computeUpdate() { if (!mMessagingBackendServiceInitialized || !mTabModelSelectorInitialized) return; - - boolean shouldShowNotificationDot = anyTabsInModelHaveDirtyBit(); - mNotificationDotObservableSupplier.set(shouldShowNotificationDot); + mNotificationDotObservableSupplier.set(computeTabModelDotInfo()); } - private boolean anyTabsInModelHaveDirtyBit() { + private TabModelDotInfo computeTabModelDotInfo() { assert mTabGroupModelFilter != null && mMessagingBackendService != null; TabModel tabModel = mTabGroupModelFilter.getTabModel(); @@ -196,8 +211,14 @@ if (tabId == Tab.INVALID_TAB_ID) continue; @Nullable Tab tab = tabModel.getTabById(tabId); - if (tab != null && !tab.isClosing()) return true; + if (tab != null && !tab.isClosing()) { + Token groupId = mTabGroupModelFilter.getTabGroupIdFromRootId(tab.getRootId()); + String title = + TabGroupTitleUtils.getDisplayableTitle( + mContext, mTabGroupModelFilter, groupId); + return new TabModelDotInfo(true, title); + } } - return false; + return TabModelDotInfo.HIDE; } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabModelNotificationDotManagerUnitTest.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabModelNotificationDotManagerUnitTest.java index 74ca0ef..230d7fb 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabModelNotificationDotManagerUnitTest.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabModelNotificationDotManagerUnitTest.java
@@ -4,12 +4,18 @@ package org.chromium.chrome.browser.tasks.tab_management; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.content.Context; +import android.text.TextUtils; + +import androidx.test.core.app.ApplicationProvider; + import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -29,6 +35,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.tabmodel.TabGroupModelFilter; import org.chromium.chrome.browser.tabmodel.TabGroupModelFilterObserver; import org.chromium.chrome.browser.tabmodel.TabGroupModelFilterProvider; @@ -53,8 +60,11 @@ @RunWith(BaseRobolectricTestRunner.class) public class TabModelNotificationDotManagerUnitTest { private static final int EXISTING_TAB_ID = 5; + private static final int ROOT_ID = 6; private static final int NON_EXISTANT_TAB_ID = 7; + private static final int TAB_COUNT = 3; private static final Token TAB_GROUP_ID = new Token(378L, 4378L); + private static final String TITLE = "Vacation"; @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule(); @@ -73,9 +83,10 @@ @Captor private ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor; @Captor private ArgumentCaptor<TabGroupModelFilterObserver> mTabGroupModelFilterObserverCaptor; + private final PersistentMessage mDirtyTabMessage = new PersistentMessage(); + private final PersistentMessage mNonDirtyTabMessage = new PersistentMessage(); + private TabModelNotificationDotManager mTabModelNotificationDotManager; - private PersistentMessage mDirtyTabMessage = new PersistentMessage(); - private PersistentMessage mNonDirtyTabMessage = new PersistentMessage(); @Before public void setUp() { @@ -93,10 +104,16 @@ when(mTabGroupModelFilterProvider.getTabGroupModelFilter(false)) .thenReturn(mTabGroupModelFilter); when(mTabGroupModelFilter.getTabModel()).thenReturn(mTabModel); + when(mTabGroupModelFilter.getTabGroupIdFromRootId(ROOT_ID)).thenReturn(TAB_GROUP_ID); + when(mTabGroupModelFilter.getRootIdFromTabGroupId(TAB_GROUP_ID)).thenReturn(ROOT_ID); + when(mTabGroupModelFilter.getTabCountForGroup(TAB_GROUP_ID)).thenReturn(TAB_COUNT); + when(mTabGroupModelFilter.getTabGroupTitle(ROOT_ID)).thenReturn(TITLE); when(mTabModel.getProfile()).thenReturn(mProfile); when(mTabModel.getTabById(EXISTING_TAB_ID)).thenReturn(mTab); + when(mTab.getRootId()).thenReturn(ROOT_ID); - mTabModelNotificationDotManager = new TabModelNotificationDotManager(); + Context context = ApplicationProvider.getApplicationContext(); + mTabModelNotificationDotManager = new TabModelNotificationDotManager(context); mTabModelNotificationDotManager.initWithNative(mTabModelSelector); verify(mMessagingBackendService) @@ -113,8 +130,9 @@ @Test public void testDestroyNoNativeInit() { + Context context = ApplicationProvider.getApplicationContext(); TabModelNotificationDotManager notificationDotManager = - new TabModelNotificationDotManager(); + new TabModelNotificationDotManager(context); // Verify this doesn't crash if called before native is initialized. notificationDotManager.destroy(); @@ -128,10 +146,10 @@ verify(mTabModel).addObserver(mTabModelObserverCaptor.capture()); verify(mTabGroupModelFilter) .addTabGroupObserver(mTabGroupModelFilterObserverCaptor.capture()); - assertFalse(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyHidden(); mPersistentMessageObserverCaptor.getValue().onMessagingBackendServiceInitialized(); - assertTrue(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyShown(); } @Test @@ -139,13 +157,13 @@ createDirtyTabMessageForIds(List.of(EXISTING_TAB_ID)); mPersistentMessageObserverCaptor.getValue().onMessagingBackendServiceInitialized(); - assertFalse(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyHidden(); mTabModelSelectorObserverCaptor.getValue().onTabStateInitialized(); verify(mTabModel).addObserver(mTabModelObserverCaptor.capture()); verify(mTabGroupModelFilter) .addTabGroupObserver(mTabGroupModelFilterObserverCaptor.capture()); - assertTrue(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyShown(); } @Test @@ -154,21 +172,21 @@ createDirtyTabMessageForIds(List.of(EXISTING_TAB_ID)); // Set to visible. mPersistentMessageObserverCaptor.getValue().displayPersistentMessage(mDirtyTabMessage); - assertTrue(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyShown(); createDirtyTabMessageForIds(List.of(NON_EXISTANT_TAB_ID)); // Cannot hide if not dirty message related. mPersistentMessageObserverCaptor.getValue().hidePersistentMessage(mNonDirtyTabMessage); - assertTrue(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyShown(); mPersistentMessageObserverCaptor.getValue().hidePersistentMessage(mDirtyTabMessage); - assertFalse(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyHidden(); // One way latching; hide should only hide it cannot show. createDirtyTabMessageForIds(List.of(EXISTING_TAB_ID)); mPersistentMessageObserverCaptor.getValue().hidePersistentMessage(mDirtyTabMessage); - assertFalse(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyHidden(); } @Test @@ -177,15 +195,15 @@ createDirtyTabMessageForIds(List.of(EXISTING_TAB_ID)); mPersistentMessageObserverCaptor.getValue().displayPersistentMessage(mNonDirtyTabMessage); - assertFalse(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyHidden(); mPersistentMessageObserverCaptor.getValue().displayPersistentMessage(mDirtyTabMessage); - assertTrue(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyShown(); // One way latching; display should only show it cannot hide. createDirtyTabMessageForIds(List.of(NON_EXISTANT_TAB_ID)); mPersistentMessageObserverCaptor.getValue().displayPersistentMessage(mDirtyTabMessage); - assertTrue(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyShown(); } @Test @@ -194,15 +212,15 @@ createDirtyTabMessageForIds(List.of(EXISTING_TAB_ID)); mPersistentMessageObserverCaptor.getValue().displayPersistentMessage(mDirtyTabMessage); - assertTrue(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyShown(); createDirtyTabMessageForIds(List.of(NON_EXISTANT_TAB_ID)); mPersistentMessageObserverCaptor.getValue().hidePersistentMessage(mDirtyTabMessage); - assertFalse(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyHidden(); createDirtyTabMessageForIds(List.of(NON_EXISTANT_TAB_ID, EXISTING_TAB_ID)); mPersistentMessageObserverCaptor.getValue().displayPersistentMessage(mDirtyTabMessage); - assertTrue(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyShown(); } @Test @@ -211,7 +229,7 @@ createDirtyTabMessageForIds(List.of(EXISTING_TAB_ID)); mTabGroupModelFilterObserverCaptor.getValue().didMergeTabToGroup(mTab); - assertFalse(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyHidden(); } @Test @@ -226,7 +244,7 @@ TabLaunchType.FROM_SYNC_BACKGROUND, TabCreationState.LIVE_IN_BACKGROUND, /* markedForSelection= */ false); - assertFalse(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyHidden(); when(mTab.getTabGroupId()).thenReturn(TAB_GROUP_ID); @@ -237,27 +255,39 @@ TabLaunchType.FROM_SYNC_BACKGROUND, TabCreationState.LIVE_IN_BACKGROUND, /* markedForSelection= */ false); - assertTrue(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyShown(); when(mTabModel.getTabById(EXISTING_TAB_ID)).thenReturn(null); mTabModelObserverCaptor.getValue().tabRemoved(mTab); - assertFalse(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyHidden(); when(mTabModel.getTabById(EXISTING_TAB_ID)).thenReturn(mTab); mTabModelObserverCaptor.getValue().tabClosureUndone(mTab); - assertTrue(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyShown(); when(mTabModel.getTabById(EXISTING_TAB_ID)).thenReturn(null); mTabModelObserverCaptor.getValue().onFinishingTabClosure(mTab); - assertFalse(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyHidden(); when(mTabModel.getTabById(EXISTING_TAB_ID)).thenReturn(mTab); mTabModelObserverCaptor.getValue().tabClosureUndone(mTab); - assertTrue(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyShown(); when(mTabModel.getTabById(EXISTING_TAB_ID)).thenReturn(null); mTabModelObserverCaptor.getValue().willCloseTab(mTab, true); - assertFalse(mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get()); + verifyHidden(); + } + + @Test + public void testFallbackTitle() { + when(mTabGroupModelFilter.getTabGroupTitle(ROOT_ID)).thenReturn(null); + initializeBothBackends(); + createDirtyTabMessageForIds(List.of(EXISTING_TAB_ID)); + + // Set to visible. + mPersistentMessageObserverCaptor.getValue().displayPersistentMessage(mDirtyTabMessage); + + verifyShown("3 tabs"); } private void initializeBothBackends() { @@ -287,4 +317,22 @@ Optional.of(PersistentNotificationType.DIRTY_TAB))) .thenReturn(messages); } + + private void verifyHidden() { + TabModelDotInfo tabModelDotInfo = + mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get(); + assertFalse(tabModelDotInfo.showDot); + assertTrue(TextUtils.isEmpty(tabModelDotInfo.tabGroupTitle)); + } + + private void verifyShown() { + verifyShown(TITLE); + } + + private void verifyShown(String expectedTitle) { + TabModelDotInfo tabModelDotInfo = + mTabModelNotificationDotManager.getNotificationDotObservableSupplier().get(); + assertTrue(tabModelDotInfo.showDot); + assertEquals(expectedTitle, tabModelDotInfo.tabGroupTitle); + } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableCoordinator.java index d4267518..f298efe 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableCoordinator.java
@@ -9,6 +9,7 @@ import androidx.annotation.NonNull; import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.toolbar.TabSwitcherDrawable; import org.chromium.chrome.browser.toolbar.TabSwitcherDrawable.TabSwitcherDrawableLocation; @@ -32,7 +33,7 @@ public TabSwitcherPaneDrawableCoordinator( @NonNull Context context, @NonNull TabModelSelector tabModelSelector, - @NonNull ObservableSupplier<Boolean> notificationDotSupplier) { + @NonNull ObservableSupplier<TabModelDotInfo> notificationDotSupplier) { @BrandedColorScheme int brandedColorScheme = BrandedColorScheme.APP_DEFAULT; @TabSwitcherDrawableLocation int tabSwitcherDrawableLocation = TabSwitcherDrawableLocation.HUB_TOOLBAR;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableCoordinatorUnitTest.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableCoordinatorUnitTest.java index 91f3f09d..7fd398cc 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableCoordinatorUnitTest.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableCoordinatorUnitTest.java
@@ -21,6 +21,7 @@ import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.tabmodel.TabModelSelector; /** @@ -31,8 +32,8 @@ public class TabSwitcherPaneDrawableCoordinatorUnitTest { @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule(); - private final ObservableSupplierImpl<Boolean> mNotificationDotSupplier = - new ObservableSupplierImpl<>(false); + private final ObservableSupplierImpl<TabModelDotInfo> mNotificationDotSupplier = + new ObservableSupplierImpl<>(TabModelDotInfo.HIDE); @Mock private TabModelSelector mTabModelSelector;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableMediator.java index 1711dce3..006fe13 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableMediator.java
@@ -12,6 +12,7 @@ import org.chromium.base.Callback; import org.chromium.base.CallbackController; import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.chrome.browser.toolbar.TabSwitcherDrawable; @@ -20,16 +21,16 @@ /** Mediator for the {@link TabSwitcherDrawable} for the {@link TabSwitcherPane}. */ public class TabSwitcherPaneDrawableMediator { private final CallbackController mCallbackController = new CallbackController(); - private final Callback<Boolean> mNotificationDotObserver = this::updateNotificationDot; + private final Callback<TabModelDotInfo> mNotificationDotObserver = this::updateNotificationDot; private final Callback<Integer> mTabCountSupplierObserver = this::updateTabCount; - private final ObservableSupplier<Boolean> mNotificationDotSupplier; + private final ObservableSupplier<TabModelDotInfo> mNotificationDotSupplier; private final PropertyModel mModel; private ObservableSupplier<Integer> mTabCountSupplier; public TabSwitcherPaneDrawableMediator( @NonNull TabModelSelector tabModelSelector, - @NonNull ObservableSupplier<Boolean> notificationDotSupplier, + @NonNull ObservableSupplier<TabModelDotInfo> notificationDotSupplier, @NonNull PropertyModel model) { mNotificationDotSupplier = notificationDotSupplier; mModel = model; @@ -55,8 +56,8 @@ mTabCountSupplier.addObserver(mTabCountSupplierObserver); } - private void updateNotificationDot(boolean showDot) { - mModel.set(SHOW_NOTIFICATION_DOT, showDot); + private void updateNotificationDot(TabModelDotInfo tabModelDotInfo) { + mModel.set(SHOW_NOTIFICATION_DOT, tabModelDotInfo.showDot); } private void updateTabCount(int tabCount) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableMediatorUnitTest.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableMediatorUnitTest.java index 6c05102..3fa85fea3 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneDrawableMediatorUnitTest.java
@@ -33,6 +33,7 @@ import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; @@ -50,8 +51,8 @@ private final ObservableSupplierImpl<Integer> mTabCountSupplier = new ObservableSupplierImpl<>(); - private final ObservableSupplierImpl<Boolean> mNotificationDotSupplier = - new ObservableSupplierImpl<>(false); + private final ObservableSupplierImpl<TabModelDotInfo> mNotificationDotSupplier = + new ObservableSupplierImpl<>(TabModelDotInfo.HIDE); private Context mContext; private PropertyModel mModel; @@ -93,7 +94,7 @@ assertEquals(mTabCountSupplier.get().intValue(), mModel.get(TAB_COUNT)); assertFalse(mModel.get(SHOW_NOTIFICATION_DOT)); - mNotificationDotSupplier.set(true); + mNotificationDotSupplier.set(new TabModelDotInfo(true, "title")); assertTrue(mModel.get(SHOW_NOTIFICATION_DOT)); mediator.destroy();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 31ca2ac5f..f9a8bae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -404,7 +404,7 @@ } private final TabModelNotificationDotManager mTabModelNotificationDotManager = - new TabModelNotificationDotManager(); + new TabModelNotificationDotManager(this); // Supplier for a dependency to inform about the type of intent used to launch Chrome. private final OneshotSupplierImpl<ToolbarIntentMetadata> mIntentMetadataOneshotSupplier = new OneshotSupplierImpl<>();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java index 360d2b33..b1bbd93 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java
@@ -38,6 +38,7 @@ import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.share.ShareDelegateSupplier; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.toolbar.ToolbarManager; import org.chromium.components.browser_ui.share.ShareHelper; import org.chromium.ui.base.ActivityWindowAndroid; @@ -210,7 +211,8 @@ /* bookmarkClickHandler= */ null, /* customTabsBackClickHandler= */ v -> onCloseButtonClick(), /* archivedTabCountSupplier= */ null, - /* tabModelNotificationDotSupplier= */ new ObservableSupplierImpl<Boolean>(false)); + /* tabModelNotificationDotSupplier= */ new ObservableSupplierImpl<TabModelDotInfo>( + TabModelDotInfo.HIDE)); mInitializedToolbarWithNative = true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/StartupMetricsTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/StartupMetricsTracker.java index fb27c84..11083be 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/StartupMetricsTracker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/StartupMetricsTracker.java
@@ -9,6 +9,7 @@ import androidx.annotation.NonNull; +import org.chromium.base.BinderCallsListener; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.task.PostTask; @@ -38,6 +39,8 @@ public class StartupMetricsTracker { private static final long TIME_TO_DRAW_METRIC_RECORDING_DELAY_MS = 2500; + private static final String NTP_COLD_START_HISTOGRAM = + "Startup.Android.Cold.NewTabPage.TimeToFirstDraw"; private boolean mFirstNavigationCommitted; private class TabObserver extends TabModelSelectorTabObserver { @@ -198,7 +201,7 @@ */ public void registerNtpViewObserver(@NonNull View ntpRootView) { if (!mShouldTrackTimeToFirstDraw) return; - trackTimeToFirstDraw(ntpRootView, "Startup.Android.Cold.NewTabPage.TimeToFirstDraw"); + trackTimeToFirstDraw(ntpRootView, NTP_COLD_START_HISTOGRAM); } /** @@ -222,6 +225,9 @@ view, () -> { long timeToFirstDrawMs = SystemClock.uptimeMillis() - mActivityStartTimeMs; + if (NTP_COLD_START_HISTOGRAM.equals(histogram)) { + recordTimeSpentInBinderCold("NewTabPage"); + } // During a cold start, first draw can be triggered while Chrome is in // the background, leading to ablated draw times. This early in the startup // process, events that indicate Chrome has been backgrounded do not run until @@ -260,6 +266,14 @@ "Startup.Android.Experimental." + name + ".Tabbed.ColdStartTracker", ms); } + private void recordTimeSpentInBinderCold(String variant) { + Long binderTimeMs = BinderCallsListener.getInstance().getTimeSpentInBinderCalls(); + if (binderTimeMs != null) { + RecordHistogram.recordMediumTimesHistogram( + "Startup.Android.Cold." + variant + ".TimeSpentInBinder", binderTimeMs); + } + } + private void recordNavigationCommitMetrics(long firstCommitMs) { if (!SimpleStartupForegroundSessionDetector.runningCleanForegroundSession()) return; if (ColdStartTracker.wasColdOnFirstActivityCreationOrNow()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java index eb504dc..c93724fb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
@@ -31,7 +31,7 @@ import org.chromium.chrome.browser.metrics.StartupMetricsTracker; import org.chromium.chrome.browser.ntp.IncognitoNewTabPage; import org.chromium.chrome.browser.ntp.NewTabPage; -import org.chromium.chrome.browser.ntp.NewTabPageUma; +import org.chromium.chrome.browser.ntp.NewTabPageCreationTracker; import org.chromium.chrome.browser.ntp.RecentTabsManager; import org.chromium.chrome.browser.ntp.RecentTabsPage; import org.chromium.chrome.browser.pdf.PdfInfo; @@ -76,7 +76,7 @@ private final OneshotSupplier<ModuleRegistry> mModuleRegistrySupplier; private final ObservableSupplier<EdgeToEdgeController> mEdgeToEdgeControllerSupplier; private final StartupMetricsTracker mStartupMetricsTracker; - private NewTabPageUma mNewTabPageUma; + private NewTabPageCreationTracker mNewTabPageCreationTracker; private NativePageBuilder mNativePageBuilder; private static NativePage sTestPage; @@ -123,7 +123,7 @@ mNativePageBuilder = new NativePageBuilder( mActivity, - this::getNewTabPageUma, + this::getNewTabPageCreationTracker, mBottomSheetController, mBrowserControlsManager, mCurrentTabSupplier, @@ -144,19 +144,19 @@ return mNativePageBuilder; } - private NewTabPageUma getNewTabPageUma() { - if (mNewTabPageUma == null) { - mNewTabPageUma = new NewTabPageUma(mTabModelSelector); - mNewTabPageUma.monitorNtpCreation(); + private NewTabPageCreationTracker getNewTabPageCreationTracker() { + if (mNewTabPageCreationTracker == null) { + mNewTabPageCreationTracker = new NewTabPageCreationTracker(mTabModelSelector); + mNewTabPageCreationTracker.monitorNtpCreation(); } - return mNewTabPageUma; + return mNewTabPageCreationTracker; } @VisibleForTesting static class NativePageBuilder { private final Activity mActivity; private final BottomSheetController mBottomSheetController; - private final Supplier<NewTabPageUma> mUma; + private final Supplier<NewTabPageCreationTracker> mNewTabPageCreationTracker; private final BrowserControlsManager mBrowserControlsManager; private final Supplier<Tab> mCurrentTabSupplier; private final Supplier<SnackbarManager> mSnackbarManagerSupplier; @@ -175,7 +175,7 @@ public NativePageBuilder( Activity activity, - Supplier<NewTabPageUma> uma, + Supplier<NewTabPageCreationTracker> newTabPageCreationTracker, BottomSheetController sheetController, BrowserControlsManager browserControlsManager, Supplier<Tab> currentTabSupplier, @@ -193,7 +193,7 @@ ObservableSupplier<EdgeToEdgeController> edgeToEdgeControllerSupplier, StartupMetricsTracker startupMetricsTracker) { mActivity = activity; - mUma = uma; + mNewTabPageCreationTracker = newTabPageCreationTracker; mBottomSheetController = sheetController; mBrowserControlsManager = browserControlsManager; mCurrentTabSupplier = currentTabSupplier; @@ -228,7 +228,7 @@ mLifecycleDispatcher, mTabModelSelector, DeviceFormFactor.isWindowOnTablet(mWindowAndroid), - mUma.get(), + mNewTabPageCreationTracker.get(), ColorUtils.inNightMode(mActivity), nativePageHost, tab, @@ -480,7 +480,7 @@ /** Destroy and unhook objects at destruction. */ public void destroy() { - if (mNewTabPageUma != null) mNewTabPageUma.destroy(); + if (mNewTabPageCreationTracker != null) mNewTabPageCreationTracker.destroy(); } public static void setPdfPageForTesting(PdfPage pdfPage) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index 910dfbd..f641a49b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -457,7 +457,8 @@ * @param lifecycleDispatcher Activity lifecycle dispatcher. * @param tabModelSelector {@link TabModelSelector} object. * @param isTablet {@code true} if running on a Tablet device. - * @param uma {@link NewTabPageUma} object recording user metrics. + * @param newTabPageCreationTracker {@link NewTabPageCreationTracker} object recording user + * metrics. * @param isInNightMode {@code true} if the night mode setting is on. * @param nativePageHost The host that is showing this new tab page. * @param tab The {@link Tab} that contains this new tab page. @@ -482,7 +483,7 @@ ActivityLifecycleDispatcher lifecycleDispatcher, TabModelSelector tabModelSelector, boolean isTablet, - NewTabPageUma uma, + NewTabPageCreationTracker mNewTabPageCreationTracker, boolean isInNightMode, NativePageHost nativePageHost, Tab tab, @@ -624,7 +625,7 @@ mToolbarHeight = activity.getResources().getDimensionPixelSize(R.dimen.toolbar_height_no_shadow); - uma.recordContentSuggestionsDisplayStatus(profile); + NewTabPageUma.recordContentSuggestionsDisplayStatus(profile); // TODO(twellington): Move this somewhere it can be shared with NewTabPageView? Runnable closeContextMenuCallback = activity::closeContextMenu;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageCreationTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageCreationTracker.java new file mode 100644 index 0000000..17187b5 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageCreationTracker.java
@@ -0,0 +1,55 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.ntp; + +import org.chromium.base.metrics.RecordHistogram; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; +import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; +import org.chromium.components.embedder_support.util.UrlUtilities; + +/** Helper class to track creating new tabs with a NewTabPage. */ +public class NewTabPageCreationTracker { + private final TabModelSelector mTabModelSelector; + private TabCreationRecorder mTabCreationRecorder; + + /** + * Constructor. + * + * @param tabModelSelector Tab model selector to observe tab creation event. + */ + public NewTabPageCreationTracker(TabModelSelector tabModelSelector) { + mTabModelSelector = tabModelSelector; + } + + /** Starts tracking new NTPs opened in a new tab. */ + public void monitorNtpCreation() { + mTabCreationRecorder = new TabCreationRecorder(); + mTabModelSelector.addObserver(mTabCreationRecorder); + } + + /** + * Tracks new NTPs opened in a new tab. Use through {@link + * NewTabPageCreationTracker#monitorNtpCreation(TabModelSelector)}. + */ + private static class TabCreationRecorder implements TabModelSelectorObserver { + @Override + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { + if (tab.isOffTheRecord() || !UrlUtilities.isNtpUrl(tab.getUrl())) { + return; + } + + RecordHistogram.recordEnumeratedHistogram( + "NewTabPage.OpenedInNewTab", tab.getLaunchType(), TabLaunchType.SIZE); + } + } + + /** Destroy and unhook objects at destruction. */ + public void destroy() { + if (mTabCreationRecorder != null) mTabModelSelector.removeObserver(mTabCreationRecorder); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java index 8344b259..ca46f33 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java
@@ -7,17 +7,11 @@ import androidx.annotation.IntDef; import org.chromium.base.metrics.RecordHistogram; -import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.feed.FeedFeatures; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabCreationState; -import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.util.BrowserUiUtils; import org.chromium.chrome.browser.util.BrowserUiUtils.ModuleTypeOnStartAndNtp; -import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.components.embedder_support.util.UrlUtilitiesJni; import org.chromium.components.user_prefs.UserPrefs; import org.chromium.ui.base.PageTransition; @@ -154,19 +148,9 @@ int NUM_ENTRIES = 5; } - private final TabModelSelector mTabModelSelector; - private TabCreationRecorder mTabCreationRecorder; - - /** - * Constructor. - * @param tabModelSelector Tab model selector to observe tab creation event. - */ - public NewTabPageUma(TabModelSelector tabModelSelector) { - mTabModelSelector = tabModelSelector; - } - /** * Records an action taken by the user on the NTP. + * * @param action One of the ACTION_* values defined in this class. */ public static void recordAction(int action) { @@ -210,17 +194,8 @@ "Android.NTP.Impression", impressionType, NUM_NTP_IMPRESSION); } - /** - * Records how often new tabs with a NewTabPage are created. This helps to determine how often - * users navigate back to already opened NTPs. - */ - public void monitorNtpCreation() { - mTabCreationRecorder = new TabCreationRecorder(); - mTabModelSelector.addObserver(mTabCreationRecorder); - } - /** Records Content Suggestions Display Status when NTPs opened. */ - public void recordContentSuggestionsDisplayStatus(Profile profile) { + public static void recordContentSuggestionsDisplayStatus(Profile profile) { @ContentSuggestionsDisplayStatus int status = ContentSuggestionsDisplayStatus.VISIBLE; if (!UserPrefs.get(profile).getBoolean(Pref.ENABLE_SNIPPETS)) { // Disabled by policy. @@ -240,21 +215,4 @@ status, ContentSuggestionsDisplayStatus.NUM_ENTRIES); } - - /** - * Records the number of new NTPs opened in a new tab. Use through {@link - * NewTabPageUma#monitorNtpCreation(TabModelSelector)}. - */ - private static class TabCreationRecorder implements TabModelSelectorObserver { - @Override - public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { - if (!UrlUtilities.isNtpUrl(tab.getUrl())) return; - RecordUserAction.record("MobileNTPOpenedInNewTab"); - } - } - - /** Destroy and unhook objects at destruction. */ - public void destroy() { - if (mTabCreationRecorder != null) mTabModelSelector.removeObserver(mTabCreationRecorder); - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java index 6e0fabf..236263d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java
@@ -12,6 +12,7 @@ import androidx.annotation.VisibleForTesting; import org.chromium.base.Callback; +import org.chromium.base.DeviceInfo; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.data_sharing.DataSharingTabManager; @@ -296,6 +297,10 @@ @Override public boolean isSharingHubEnabled() { + if (DeviceInfo.isAutomotive() + && Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) { + return true; + } return !(mIsCustomTab || Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 8126829..f8709ef 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -115,6 +115,7 @@ import org.chromium.chrome.browser.tab.TabObscuringHandler; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab_ui.TabContentManager; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -1888,7 +1889,7 @@ OnClickListener bookmarkClickHandler, OnClickListener customTabsBackClickHandler, @Nullable ObservableSupplier<Integer> archivedTabCountSupplier, - ObservableSupplier<Boolean> tabModelNotificationDotSupplier) { + ObservableSupplier<TabModelDotInfo> tabModelNotificationDotSupplier) { TraceEvent.begin("ToolbarManager.initializeWithNative"); assert !mInitializedWithNative; assert mTabModelSelectorSupplier.get() != null;
diff --git a/chrome/android/javatests/BUILD.gn b/chrome/android/javatests/BUILD.gn index edf3467..7b1109a 100644 --- a/chrome/android/javatests/BUILD.gn +++ b/chrome/android/javatests/BUILD.gn
@@ -908,6 +908,7 @@ "src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageTest.java", "src/org/chromium/chrome/browser/ntp/MostVisitedTilesPTTest.java", "src/org/chromium/chrome/browser/ntp/NewTabPageColorWithFeedV2Test.java", + "src/org/chromium/chrome/browser/ntp/NewTabPageCreationTest.java", "src/org/chromium/chrome/browser/ntp/NewTabPageLoadTest.java", "src/org/chromium/chrome/browser/ntp/NewTabPageNavigationTest.java", "src/org/chromium/chrome/browser/ntp/NewTabPageTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java index 111ed0a..2073338 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
@@ -22,6 +22,7 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import org.chromium.base.BinderCallsListener; import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordHistogram; @@ -84,6 +85,8 @@ "Startup.Android.Warm.MainIntentTimeToFirstDraw"; private static final String NTP_TIME_TO_FIRST_DRAW_COLD_HISTOGRAM = "Startup.Android.Cold.NewTabPage.TimeToFirstDraw"; + private static final String NTP_COLD_START_BINDER_HISTOGRAM = + "Startup.Android.Cold.NewTabPage.TimeSpentInBinder"; private CustomTabsConnection mConnectionToCleanup; @@ -397,6 +400,36 @@ assertHistogramsRecordedWithForegroundStart(0, TABBED_SUFFIX); } + @Test + @LargeTest + public void testNtpBinderMetricRecordedCorrectly() throws Exception { + // Install BinderCallsListener. + boolean success = + ThreadUtils.runOnUiThreadBlocking( + () -> { + BinderCallsListener listener = BinderCallsListener.getInstance(); + return listener.installListener(); + }); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + // THe API was added in Android 10, but don't skip tests in earlier + // releases to check we don't cause crashes there. + Assert.assertFalse(success); + return; + } + Assert.assertTrue(success); + + HistogramWatcher ntpBinderWatcher = + HistogramWatcher.newBuilder() + .expectAnyRecordTimes(NTP_COLD_START_BINDER_HISTOGRAM, 1) + .build(); + runAndWaitForPageLoadMetricsRecorded( + () -> mTabbedActivityTestRule.startMainActivityWithURL(UrlConstants.NTP_URL)); + waitForHistogram(ntpBinderWatcher); + + // Clean up listener. + BinderCallsListener.setInstanceForTesting(null); + } + /** * Tests that the startup loading histograms are not recorded in case of navigation to the blank * page.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageCreationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageCreationTest.java new file mode 100644 index 0000000..4027507b --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageCreationTest.java
@@ -0,0 +1,62 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.ntp; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import androidx.test.filters.MediumTest; + +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +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.HistogramWatcher; +import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.ui.native_page.NativePage; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule; + +/** Tests for creating a tab with NewTabPage. */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@Batch(Batch.PER_CLASS) +public class NewTabPageCreationTest { + @ClassRule + public static ChromeTabbedActivityTestRule sActivityTestRule = + new ChromeTabbedActivityTestRule(); + + @Rule + public BlankCTATabInitialStateRule mBlankCTATabInitialStateRule = + new BlankCTATabInitialStateRule(sActivityTestRule, false); + + @Test + @MediumTest + public void testCreateNTP() { + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord("NewTabPage.OpenedInNewTab", 2 /* FROM_CHROME_UI */) + .build(); + + ThreadUtils.runOnUiThreadBlocking( + () -> { + sActivityTestRule.getActivity().getCurrentTabCreator().launchNtp(); + }); + + histogramWatcher.pollInstrumentationThreadUntilSatisfied(); + + Tab currentTab = sActivityTestRule.getActivity().getActivityTab(); + assertNotNull(currentTab); + NativePage nativePage = currentTab.getNativePage(); + assertNotNull(nativePage); + assertTrue(nativePage instanceof NewTabPage); + } +}
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 b8b825ffb..078584e 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
@@ -17,6 +17,7 @@ import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant; import static androidx.test.espresso.matcher.ViewMatchers.hasSibling; import static androidx.test.espresso.matcher.ViewMatchers.isChecked; +import static androidx.test.espresso.matcher.ViewMatchers.isClickable; import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withChild; @@ -24,6 +25,7 @@ import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.emptyIterable; @@ -3290,6 +3292,83 @@ settingsActivity, "site_settings_rws_grouped_website_settings_delete_dialog"); } + @Test + @SmallTest + public void deleteSingleSiteDataRemovesRowSingleWebsiteSettings() throws Exception { + final String currentSiteUrl = "one-test.com"; + final String rwsMemberUrl = "two-test.com"; + final SettingsActivity settingsActivity = + SiteSettingsTestUtils.startSingleWebsitePreferences( + getRwsOwnerSiteForUrls(currentSiteUrl, rwsMemberUrl)); + + onView( + allOf( + withText(currentSiteUrl), + hasSibling(withText("http")), + not(isDescendantOfA(isClickable())))) + .check(matches(isDisplayed())); + onView(withText(rwsMemberUrl)).check(matches(isDisplayed())); + + onView( + allOf( + withId(R.id.image_view_widget), + withContentDescription(containsString(rwsMemberUrl)))) + .check(matches(isDisplayed())) + .perform(click()); + onView(withText(R.string.website_reset_confirmation)).check(matches(isDisplayed())); + onView(withText(R.string.website_reset)) + .inRoot(isDialog()) + .check(matches(isDisplayed())) + .perform(click()); + onView(withText(rwsMemberUrl)).check(doesNotExist()); + onView( + allOf( + withText(currentSiteUrl), + hasSibling(withText("http")), + not(isDescendantOfA(isClickable())))) + .check(matches(isDisplayed())); + } + + @Test + @SmallTest + public void deleteSingleSiteDataRemovesRowGroupedWebsiteSettings() throws Exception { + final String currentSiteUrl = "one-test.com"; + final String rwsMemberUrl = "two-test.com"; + + final SettingsActivity settingsActivity = + SiteSettingsTestUtils.startGroupedWebsitesPreferences( + getRwsSiteGroupForUrls(currentSiteUrl, rwsMemberUrl)); + + // RWS row and "Sites under" row will have equivalent views in the view hierarchy. + // The RWS row is higher up on the page and therefore be the first matched. + onView( + allOf( + withText(currentSiteUrl), + hasSibling(withText("http")), + not(isDescendantOfA(isClickable())))) + .check(matches(isDisplayed())); + onView(withText(rwsMemberUrl)).check(matches(isDisplayed())); + + onView( + allOf( + withId(R.id.image_view_widget), + withContentDescription(containsString(rwsMemberUrl)))) + .check(matches(isDisplayed())) + .perform(click()); + onView(withText(R.string.website_reset_confirmation)).check(matches(isDisplayed())); + onView(withText(R.string.website_reset)) + .inRoot(isDialog()) + .check(matches(isDisplayed())) + .perform(click()); + onView(withText(rwsMemberUrl)).check(doesNotExist()); + onView( + allOf( + withText(currentSiteUrl), + hasSibling(withText("http")), + not(isDescendantOfA(isClickable())))) + .check(matches(isDisplayed())); + } + // TODO(crbug.com/396463421): Remove once RWS UI V2 launched. @Test @SmallTest
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/share/ShareDelegateImplUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/share/ShareDelegateImplUnitTest.java index b7e4cc7..022a5ae9 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/share/ShareDelegateImplUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/share/ShareDelegateImplUnitTest.java
@@ -43,6 +43,7 @@ import org.chromium.chrome.browser.share.share_sheet.ShareSheetCoordinator; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.test.AutomotiveContextWrapperTestRule; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.device_lock.DeviceLockActivityLauncher; import org.chromium.components.browser_ui.share.ShareParams; @@ -67,6 +68,10 @@ public class ShareDelegateImplUnitTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule + public AutomotiveContextWrapperTestRule mAutomotiveContextWrapperTestRule = + new AutomotiveContextWrapperTestRule(); + @Mock private BottomSheetController mBottomSheetController; @Mock private Profile mProfile; @Mock private Tab mTab; @@ -153,6 +158,8 @@ @Test @Config(sdk = 34) public void shareWithAndroidShareSheetForU() { + mAutomotiveContextWrapperTestRule.setIsAutomotive(false); + Assert.assertFalse("ShareHub enabled.", mShareDelegate.isSharingHubEnabled()); HistogramWatcher histogramWatcher = @@ -180,6 +187,23 @@ } @Test + public void share_automotive_useCustomShareSheet() { + mAutomotiveContextWrapperTestRule.setIsAutomotive(true); + Assert.assertTrue( + "Custom share sheet should still be used on U- auto devices.", + mShareDelegate.isSharingHubEnabled()); + } + + @Test + @Config(sdk = 35) + public void share_automotiveV_useAndroidShareSheet() { + mAutomotiveContextWrapperTestRule.setIsAutomotive(true); + Assert.assertFalse( + "Automotive devices should be using the OS share sheet on V+.", + mShareDelegate.isSharingHubEnabled()); + } + + @Test public void testGetShareContentType_link() { ShareParams params = new ShareParams.Builder(mWindowAndroid, "", JUnitTestGURLs.EXAMPLE_URL.getSpec())
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7aa5cd0..83eb6d1a 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -10539,13 +10539,6 @@ FEATURE_VALUE_TYPE(chromeos::features::kCrosMall)}, #endif // BUILDFLAG(IS_CHROMEOS) - {"autofill-enable-vcn-gray-out-for-merchant-opt-out", - flag_descriptions::kAutofillEnableVcnGrayOutForMerchantOptOutName, - flag_descriptions::kAutofillEnableVcnGrayOutForMerchantOptOutDescription, - kOsAll, - FEATURE_VALUE_TYPE( - autofill::features::kAutofillEnableVcnGrayOutForMerchantOptOut)}, - #if BUILDFLAG(IS_MAC) {"reduce-ip-address-change-notification", flag_descriptions::kReduceIPAddressChangeNotificationName,
diff --git a/chrome/browser/accessibility/embedded_a11y_extension_loader.cc b/chrome/browser/accessibility/embedded_a11y_extension_loader.cc index 84e31c1..297f465 100644 --- a/chrome/browser/accessibility/embedded_a11y_extension_loader.cc +++ b/chrome/browser/accessibility/embedded_a11y_extension_loader.cc
@@ -10,7 +10,6 @@ #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/component_loader.h" -#include "chrome/browser/extensions/extension_service.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension_constants.h" #include "content/public/browser/browser_accessibility_state.h" @@ -18,7 +17,6 @@ #include "content/public/browser/browser_thread.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_file_task_runner.h" -#include "extensions/browser/extension_system.h" #include "extensions/common/extension_l10n_util.h" #include "extensions/common/file_util.h" @@ -57,19 +55,6 @@ return manifest; } -extensions::ComponentLoader* GetComponentLoader(Profile* profile) { - auto* extension_system = extensions::ExtensionSystem::Get(profile); - if (!extension_system) { - // May be missing on the Lacros login profile. - return nullptr; - } - auto* extension_service = extension_system->extension_service(); - if (!extension_service) { - return nullptr; - } - return extension_service->component_loader(); -} - } // namespace EmbeddedA11yExtensionLoader::ExtensionInfo::ExtensionInfo( @@ -237,7 +222,7 @@ void EmbeddedA11yExtensionLoader::MaybeRemoveExtension( Profile* profile, const std::string& extension_id) { - auto* component_loader = GetComponentLoader(profile); + auto* component_loader = extensions::ComponentLoader::Get(profile); if (!component_loader || !component_loader->Exists(extension_id)) { return; } @@ -254,7 +239,7 @@ const base::FilePath::CharType* manifest_name, bool should_localize) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - auto* component_loader = GetComponentLoader(profile); + auto* component_loader = extensions::ComponentLoader::Get(profile); if (!component_loader || component_loader->Exists(extension_id)) { return; }
diff --git a/chrome/browser/accessibility/embedded_a11y_extension_loader_browsertest.cc b/chrome/browser/accessibility/embedded_a11y_extension_loader_browsertest.cc index 2f15adf..33dcaf8 100644 --- a/chrome/browser/accessibility/embedded_a11y_extension_loader_browsertest.cc +++ b/chrome/browser/accessibility/embedded_a11y_extension_loader_browsertest.cc
@@ -8,7 +8,6 @@ #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/component_loader.h" -#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile_test_util.h" #include "chrome/browser/profiles/profile_window.h" #include "chrome/browser/ui/browser.h" @@ -16,7 +15,6 @@ #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/browser_test.h" #include "content/public/test/test_utils.h" -#include "extensions/browser/extension_system.h" class EmbeddedA11yExtensionLoaderTest : public InProcessBrowserTest { public: @@ -40,11 +38,7 @@ void WaitForExtensionLoaded(Profile* profile, const std::string& extension_id) { - extensions::ComponentLoader* component_loader = - extensions::ExtensionSystem::Get(profile) - ->extension_service() - ->component_loader(); - + auto* component_loader = extensions::ComponentLoader::Get(profile); while (!component_loader->Exists(extension_id)) { waiter_ = std::make_unique<base::RunLoop>(); waiter_->Run(); @@ -55,10 +49,7 @@ void WaitForExtensionUnloaded(Profile* profile, const std::string& extension_id) { - extensions::ComponentLoader* component_loader = - extensions::ExtensionSystem::Get(profile) - ->extension_service() - ->component_loader(); + auto* component_loader = extensions::ComponentLoader::Get(profile); while (component_loader->Exists(extension_id)) { waiter_ = std::make_unique<base::RunLoop>(); waiter_->Run();
diff --git a/chrome/browser/accessibility/tree_fixing/ax_tree_fixing_services_router.cc b/chrome/browser/accessibility/tree_fixing/ax_tree_fixing_services_router.cc index e47d31f..5a0a572 100644 --- a/chrome/browser/accessibility/tree_fixing/ax_tree_fixing_services_router.cc +++ b/chrome/browser/accessibility/tree_fixing/ax_tree_fixing_services_router.cc
@@ -17,6 +17,7 @@ #include "content/public/browser/render_widget_host_iterator.h" #include "content/public/browser/web_contents.h" #include "ui/accessibility/accessibility_features.h" +#include "ui/accessibility/ax_tree_id.h" #include "ui/accessibility/ax_tree_update.h" #if BUILDFLAG(IS_CHROMEOS) @@ -45,7 +46,7 @@ web_contents()->RequestAXTreeSnapshotWithinBrowserProcess(), base::BindOnce(&AXTreeFixingServicesRouter:: AXTreeFixingWebContentsObserver::OnMainNodeIdentified, - base::Unretained(this))); + weak_ptr_factory_.GetWeakPtr())); // If the request was not processed, it likely means that the accessibility // engine is still spinning-up (e.g. no root BrowserAccessibilityManager yet). @@ -56,13 +57,13 @@ FROM_HERE, base::BindOnce(&AXTreeFixingServicesRouter:: AXTreeFixingWebContentsObserver::TryIdentifyMainNode, - base::Unretained(this)), + weak_ptr_factory_.GetWeakPtr()), base::Seconds(retry_attempts_)); } } void AXTreeFixingServicesRouter::AXTreeFixingWebContentsObserver:: - OnMainNodeIdentified(ui::AXTreeID tree_id, ui::AXNodeID node_id) { + OnMainNodeIdentified(const ui::AXTreeID& tree_id, ui::AXNodeID node_id) { retry_attempts_ = 0; web_contents()->ApplyAXTreeFixingResult(tree_id, node_id, ax::mojom::Role::kMain); @@ -75,7 +76,7 @@ pref_change_registrar_.Add( prefs::kAccessibilityAXTreeFixingEnabled, base::BindRepeating(&AXTreeFixingServicesRouter::ToggleEnabledState, - weak_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr())); // If the AXTreeFixing feature flag is not enabled, do not initialize. if (!features::IsAXTreeFixingEnabled()) { @@ -88,7 +89,7 @@ accessibility_status_subscription_ = accessibility_manager->RegisterCallback(base::BindRepeating( &AXTreeFixingServicesRouter::OnAccessibilityStatusEvent, - base::Unretained(this))); + weak_ptr_factory_.GetWeakPtr())); } #else ax_mode_observation_.Observe(&ui::AXPlatform::GetInstance()); @@ -141,9 +142,10 @@ next_screen_ai_request_id_++; } -void AXTreeFixingServicesRouter::OnMainNodeIdentified(ui::AXTreeID tree_id, - ui::AXNodeID node_id, - int request_id) { +void AXTreeFixingServicesRouter::OnMainNodeIdentified( + const ui::AXTreeID& tree_id, + ui::AXNodeID node_id, + int request_id) { CHECK(!pending_screen_ai_callbacks_.empty()); // Find the callback associated with the returned request ID, and call it with
diff --git a/chrome/browser/accessibility/tree_fixing/ax_tree_fixing_services_router.h b/chrome/browser/accessibility/tree_fixing/ax_tree_fixing_services_router.h index 3d1085c..ba81e7b7 100644 --- a/chrome/browser/accessibility/tree_fixing/ax_tree_fixing_services_router.h +++ b/chrome/browser/accessibility/tree_fixing/ax_tree_fixing_services_router.h
@@ -20,6 +20,7 @@ #include "components/prefs/pref_change_registrar.h" #include "content/public/browser/web_contents_observer.h" #include "ui/accessibility/ax_mode.h" +#include "ui/accessibility/ax_node_id_forward.h" #if BUILDFLAG(IS_CHROMEOS) #include "base/callback_list.h" @@ -42,13 +43,14 @@ } // namespace content namespace ui { +class AXTreeID; struct AXTreeUpdate; } // namespace ui namespace tree_fixing { using MainNodeIdentificationCallback = - base::OnceCallback<void(ui::AXTreeID, ui::AXNodeID)>; + base::OnceCallback<void(const ui::AXTreeID&, ui::AXNodeID)>; using ScreenshotCallback = base::OnceCallback<void(SkBitmap)>; @@ -84,10 +86,13 @@ private: void TryIdentifyMainNode(); - void OnMainNodeIdentified(ui::AXTreeID tree_id, ui::AXNodeID node_id); + void OnMainNodeIdentified(const ui::AXTreeID& tree_id, + ui::AXNodeID node_id); uint32_t retry_attempts_ = 0; raw_ptr<AXTreeFixingServicesRouter> router_; + base::WeakPtrFactory<AXTreeFixingWebContentsObserver> weak_ptr_factory_{ + this}; }; explicit AXTreeFixingServicesRouter(Profile* profile); @@ -114,7 +119,7 @@ private: // AXTreeFixingScreenAIService::MainNodeIdentificationDelegate overrides: - void OnMainNodeIdentified(ui::AXTreeID tree_id, + void OnMainNodeIdentified(const ui::AXTreeID& tree_id, ui::AXNodeID node_id, int request_id) override; void OnServiceStateChanged(bool service_ready) override; @@ -160,7 +165,7 @@ base::ScopedObservation<ui::AXPlatform, ui::AXModeObserver> ax_mode_observation_{this}; #endif // BUILDFLAG(IS_CHROMEOS) - base::WeakPtrFactory<AXTreeFixingServicesRouter> weak_factory_{this}; + base::WeakPtrFactory<AXTreeFixingServicesRouter> weak_ptr_factory_{this}; }; } // namespace tree_fixing
diff --git a/chrome/browser/accessibility/tree_fixing/internal/ax_tree_fixing_screen_ai_service.h b/chrome/browser/accessibility/tree_fixing/internal/ax_tree_fixing_screen_ai_service.h index f9cf77a7..44c56b4cbb 100644 --- a/chrome/browser/accessibility/tree_fixing/internal/ax_tree_fixing_screen_ai_service.h +++ b/chrome/browser/accessibility/tree_fixing/internal/ax_tree_fixing_screen_ai_service.h
@@ -52,7 +52,7 @@ // requests in parallel and uniquely identify each response. It is the // responsibility of the client to handle the logic behind a request_id, // this service simply passes the id through. - virtual void OnMainNodeIdentified(ui::AXTreeID tree_id, + virtual void OnMainNodeIdentified(const ui::AXTreeID& tree_id, ui::AXNodeID node_id, int request_id) = 0;
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java index 0d31577..5954189 100644 --- a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java +++ b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
@@ -71,11 +71,14 @@ import androidx.annotation.DrawableRes; import androidx.annotation.Px; import androidx.appcompat.app.AppCompatActivity; +import androidx.browser.auth.AuthTabCallback; import androidx.browser.auth.AuthTabColorSchemeParams; import androidx.browser.auth.AuthTabIntent; +import androidx.browser.auth.AuthTabSession; import androidx.browser.customtabs.CustomTabsCallback; import androidx.browser.customtabs.CustomTabsClient; import androidx.browser.customtabs.CustomTabsIntent; +import androidx.browser.customtabs.CustomTabsService; import androidx.browser.customtabs.CustomTabsServiceConnection; import androidx.browser.customtabs.CustomTabsSession; import androidx.browser.customtabs.EngagementSignalsCallback; @@ -153,6 +156,7 @@ private static final int DEFAULT_BREAKPOINT = 840; private static CustomTabsClient sClient; private AutoCompleteTextView mEditUrl; + private AuthTabSession mAuthTabSession; private CustomTabsSession mCustomTabsSession; private CustomTabsServiceConnection mConnection; private String mPackageNameToBind; @@ -261,6 +265,30 @@ } }; + private static class AuthTabNavigationCallback implements AuthTabCallback { + @Override + public void onExtraCallback(String callbackName, Bundle args) {} + + @Override + public Bundle onExtraCallbackWithResult(String callbackName, Bundle args) { + // Return a signal to signal that the callback was successfully handled. + Bundle result = new Bundle(); + result.putBoolean(CustomTabsService.KEY_SUCCESS, true); + + return result; + } + + @Override + public void onNavigationEvent(int navigationEvent, Bundle extras) { + Log.w(TAG, "onNavigationEvent: Code = " + navigationEvent); + } + + @Override + public void onWarmupCompleted(Bundle extras) { + Log.w(TAG, "onWarmUpCompleted"); + } + } + private static class NavigationCallback extends CustomTabsCallback { @Override public void onNavigationEvent(int navigationEvent, @Nullable Bundle extras) { @@ -953,6 +981,16 @@ return mCustomTabsSession; } + private @Nullable AuthTabSession getAuthSession() { + if (sClient == null) { + mAuthTabSession = null; + } else if (mAuthTabSession == null) { + mAuthTabSession = sClient.newAuthTabSession(new AuthTabNavigationCallback(), null); + SessionHelper.setCurrentAuthSession(mAuthTabSession); + } + return mAuthTabSession; + } + private void bindCustomTabsService() { if (sClient != null) return; @@ -1198,6 +1236,7 @@ Bitmap closeIcon = BitmapFactory.decodeResource(getResources(), closeIconId); AuthTabIntent authIntent = new AuthTabIntent.Builder() + .setSession(getAuthSession()) .setColorScheme(colorScheme) .setDefaultColorSchemeParams(builder.build()) .setCloseButtonIcon(closeIcon)
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/SessionHelper.java b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/SessionHelper.java index fa473db3..97e10de 100644 --- a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/SessionHelper.java +++ b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/SessionHelper.java
@@ -4,6 +4,7 @@ package org.chromium.customtabsclient; +import androidx.browser.auth.AuthTabSession; import androidx.browser.customtabs.CustomTabsSession; import org.chromium.build.annotations.NullMarked; @@ -12,12 +13,13 @@ import java.lang.ref.WeakReference; /** - * A class that keeps tracks of the current {@link CustomTabsSession} and helps other components of - * the app to get access to the current session. + * A class that keeps tracks of the current {@link CustomTabsSession} or {@link AuthTabSession} and + * helps other components of the app to get access to the current session. */ @NullMarked public class SessionHelper { private static @Nullable WeakReference<CustomTabsSession> sCurrentSession; + private static @Nullable WeakReference<AuthTabSession> sCurrentAuthTabSession; /** * @return The current {@link CustomTabsSession} object. @@ -28,9 +30,24 @@ /** * Sets the current session to the given one. + * * @param session The current session. */ public static void setCurrentSession(@Nullable CustomTabsSession session) { sCurrentSession = new WeakReference<CustomTabsSession>(session); } + + /** Returns the current {@link AuthTabSession} object. */ + public static @Nullable AuthTabSession getCurrentAuthSession() { + return sCurrentAuthTabSession == null ? null : sCurrentAuthTabSession.get(); + } + + /** + * Sets the current session to the given one. + * + * @param session The current session. + */ + public static void setCurrentAuthSession(@Nullable AuthTabSession session) { + sCurrentAuthTabSession = new WeakReference<AuthTabSession>(session); + } }
diff --git a/chrome/browser/ash/accessibility/accessibility_common_browsertest.cc b/chrome/browser/ash/accessibility/accessibility_common_browsertest.cc index 6778f6c9..ca7a8252 100644 --- a/chrome/browser/ash/accessibility/accessibility_common_browsertest.cc +++ b/chrome/browser/ash/accessibility/accessibility_common_browsertest.cc
@@ -7,7 +7,6 @@ #include "chrome/browser/ash/accessibility/accessibility_manager.h" #include "chrome/browser/ash/accessibility/accessibility_test_utils.h" #include "chrome/browser/extensions/component_loader.h" -#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/test/base/in_process_browser_test.h" @@ -16,7 +15,6 @@ #include "content/public/test/browser_test.h" #include "content/public/test/test_utils.h" #include "extensions/browser/extension_host_test_helper.h" -#include "extensions/browser/extension_system.h" #include "extensions/common/features/feature_channel.h" #include "ui/accessibility/accessibility_features.h" @@ -43,10 +41,8 @@ } bool DoesComponentExtensionExist(const std::string& id) { - return extensions::ExtensionSystem::Get( + return extensions::ComponentLoader::Get( AccessibilityManager::Get()->profile()) - ->extension_service() - ->component_loader() ->Exists(id); }
diff --git a/chrome/browser/ash/accessibility/accessibility_extension_loader.cc b/chrome/browser/ash/accessibility/accessibility_extension_loader.cc index e87ea6a..12ed70c 100644 --- a/chrome/browser/ash/accessibility/accessibility_extension_loader.cc +++ b/chrome/browser/ash/accessibility/accessibility_extension_loader.cc
@@ -46,9 +46,7 @@ // If the extension was already enabled, but not for this profile, add it // to this profile. - auto* extension_service = - extensions::ExtensionSystem::Get(browser_context_)->extension_service(); - auto* component_loader = extension_service->component_loader(); + auto* component_loader = extensions::ComponentLoader::Get(browser_context_); if (!component_loader->Exists(extension_id_)) { LoadExtension(browser_context_, std::move(done_callback)); } @@ -106,7 +104,7 @@ weak_ptr_factory_.GetWeakPtr(), browser_context, std::move(done_cb)); } - extension_service->component_loader() + extensions::ComponentLoader::Get(browser_context) ->AddComponentFromDirWithManifestFilename( extension_path_, extension_id_.c_str(), manifest_filename_, guest_manifest_filename_, std::move(done_cb)); @@ -123,7 +121,7 @@ extension_service->UninstallExtension( extension_id_, extensions::UninstallReason::UNINSTALL_REASON_REINSTALL, &error); - extension_service->component_loader()->Reload(extension_id_); + extensions::ComponentLoader::Get(browser_context)->Reload(extension_id_); if (done_cb) std::move(done_cb).Run(); @@ -131,9 +129,7 @@ void AccessibilityExtensionLoader::UnloadExtension( content::BrowserContext* browser_context) { - auto* extension_service = - extensions::ExtensionSystem::Get(browser_context)->extension_service(); - extension_service->component_loader()->Remove(extension_id_); + extensions::ComponentLoader::Get(browser_context)->Remove(extension_id_); } } // namespace ash
diff --git a/chrome/browser/ash/accessibility/accessibility_manager.cc b/chrome/browser/ash/accessibility/accessibility_manager.cc index aafcf86..371e86c 100644 --- a/chrome/browser/ash/accessibility/accessibility_manager.cc +++ b/chrome/browser/ash/accessibility/accessibility_manager.cc
@@ -58,7 +58,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/api/braille_display_private/stub_braille_controller.h" #include "chrome/browser/extensions/component_loader.h" -#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/lifetime/termination_notification.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h" @@ -2297,10 +2296,7 @@ if (!profile_) return; - extensions::ComponentLoader* component_loader = - extensions::ExtensionSystem::Get(profile_) - ->extension_service() - ->component_loader(); + auto* component_loader = extensions::ComponentLoader::Get(profile_); if (component_loader->Exists(extension_misc::kEnhancedNetworkTtsExtensionId)) return; @@ -2334,10 +2330,7 @@ if (!profile_) return; - extensions::ComponentLoader* component_loader = - extensions::ExtensionSystem::Get(profile_) - ->extension_service() - ->component_loader(); + auto* component_loader = extensions::ComponentLoader::Get(profile_); if (component_loader->Exists(extension_misc::kEnhancedNetworkTtsExtensionId)) component_loader->Remove(extension_misc::kEnhancedNetworkTtsExtensionId); }
diff --git a/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc b/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc index a5f85527..ab603f8 100644 --- a/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc +++ b/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc
@@ -30,7 +30,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/api/braille_display_private/mock_braille_controller.h" #include "chrome/browser/extensions/component_loader.h" -#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/prefs/pref_service_syncable_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -920,10 +919,8 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, EnhancedNetworkVoicesExtensionLoadedWhenNeeded) { - extensions::ComponentLoader* component_loader = - extensions::ExtensionSystem::Get(browser()->profile()) - ->extension_service() - ->component_loader(); + auto* component_loader = + extensions::ComponentLoader::Get(browser()->profile()); // Not loaded yet. EXPECT_FALSE(
diff --git a/chrome/browser/ash/login/existing_user_controller.cc b/chrome/browser/ash/login/existing_user_controller.cc index d5b44369..af689b3 100644 --- a/chrome/browser/ash/login/existing_user_controller.cc +++ b/chrome/browser/ash/login/existing_user_controller.cc
@@ -796,9 +796,10 @@ user_context.GetAccountId(), true)); } - if (user_context.GetUserType() == user_manager::UserType::kPublicAccount) { - SYSLOG(INFO) << "MGS: Finished login, starting session to load the profile"; - } + const bool is_managed_guest_session = + user_context.GetUserType() == user_manager::UserType::kPublicAccount; + SYSLOG(INFO) << "(LOGIN) " << (is_managed_guest_session ? "(MGS) " : "") + << "Finished login, starting session to load the profile."; UserSessionManager::StartSessionType start_session_type = UserAddingScreen::Get()->IsRunning() @@ -914,9 +915,10 @@ return; } - if (user_context.GetUserType() == user_manager::UserType::kPublicAccount) { - SYSLOG(INFO) << "MGS: Session started, the profile is ready"; - } + const bool is_managed_guest_session = + user_context.GetUserType() == user_manager::UserType::kPublicAccount; + SYSLOG(INFO) << "(LOGIN) " << (is_managed_guest_session ? "(MGS) " : "") + << "Session started, the profile is ready "; // Inform `auth_status_consumers_` about successful login. // TODO(nkostylev): Pass UserContext back crbug.com/424550
diff --git a/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.cc b/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.cc index 552ac7f4..48c0472 100644 --- a/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.cc +++ b/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.cc
@@ -12,6 +12,7 @@ #include "base/check.h" #include "base/functional/callback_helpers.h" #include "base/metrics/histogram_functions.h" +#include "base/syslog_logging.h" #include "base/time/default_clock.h" #include "base/trace_event/trace_event.h" #include "chrome/browser/ash/login/auth/chrome_safe_mode_delegate.h" @@ -127,6 +128,7 @@ } void LockScreenReauthManager::ForceOnlineReauth() { + SYSLOG(INFO) << "(LOGIN) LoginScreenReauthManager::ForceOnlineReauth"; const auto account_id = primary_user_->GetAccountId(); screenlock_bridge_->lock_handler()->SetAuthType( account_id, proximity_auth::mojom::AuthType::ONLINE_SIGN_IN, u""); @@ -134,8 +136,8 @@ const bool auto_start_reauth = primary_profile_->GetPrefs()->GetBoolean( ::prefs::kLockScreenAutoStartOnlineReauth); if (auto_start_reauth) { - // TODO(b/333882432): Remove this log after the bug fixed. - LOG(WARNING) << "b/333882432: LoginScreenReauthManager::ForceOnlineReauth"; + SYSLOG(INFO) << "(LOGIN) LoginScreenReauthManager::ForceOnlineReauth " + "ShowGaiaSignin()"; Shell::Get()->login_screen_controller()->ShowGaiaSignin( /*prefilled_account=*/account_id); } @@ -217,17 +219,21 @@ } void LockScreenReauthManager::OnAuthSuccess(const UserContext& user_context) { + SYSLOG(INFO) << "(LOGIN) LoginScreenReauthManager::OnAuthSuccess"; if (user_context.GetAccountId() != primary_user_->GetAccountId()) { // Tried to re-authenicate with non-primary user: the authentication was // successful but we are allowed to unlock only with valid credentials of // the user who locked the screen. In this case show customized version // of first re-auth flow dialog with an error message. - LOG(FATAL) << "Different user is unlocking the device"; + const std::string msg = "(LOGIN) Different user is unlocking the device "; + SYSLOG(INFO) << msg; + LOG(FATAL) << msg; } ResetOnlineReauth(); SendLockscreenReauthReason(); if (is_reauth_required_by_saml_token_mismatch_) { + SYSLOG(INFO) << "(LOGIN) Reauth due to SAML token mismatch. Fetch token. "; in_session_password_sync_manager_.FetchTokenAsync(); }
diff --git a/chrome/browser/ash/login/reauth_stats.cc b/chrome/browser/ash/login/reauth_stats.cc index 4b214c3..3a8cd5c6 100644 --- a/chrome/browser/ash/login/reauth_stats.cc +++ b/chrome/browser/ash/login/reauth_stats.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/metrics/histogram_functions.h" +#include "base/syslog_logging.h" #include "chrome/browser/browser_process.h" #include "components/user_manager/known_user.h" @@ -29,7 +30,7 @@ if (GetReauthReason(known_user, account_id) == reason) return; - LOG(WARNING) << "Reauth reason updated: " << static_cast<int>(reason); + SYSLOG(WARNING) << "Reauth reason updated: " << static_cast<int>(reason); known_user.UpdateReauthReason(account_id, static_cast<int>(reason)); }
diff --git a/chrome/browser/autocomplete/tab_matcher_desktop.cc b/chrome/browser/autocomplete/tab_matcher_desktop.cc index bdb2932a..563dcffe 100644 --- a/chrome/browser/autocomplete/tab_matcher_desktop.cc +++ b/chrome/browser/autocomplete/tab_matcher_desktop.cc
@@ -86,6 +86,27 @@ return false; } +bool TabMatcherDesktop::IsTabOpenWithSameTitleOrSimilarURL( + const std::u16string& title, + const GURL& url, + const GURL::Replacements& replacements, + bool exclude_active_tab) const { + auto strip_url = [&](const GURL& url) -> GURL { + return AutocompleteMatch::GURLToStrippedGURL( + url.ReplaceComponents(replacements), AutocompleteInput(), + template_url_service_, std::u16string(), + /*keep_search_intent_params=*/false); + }; + + for (auto* web_contents : GetOpenWebContents(exclude_active_tab)) { + if (title == web_contents->GetTitle() || + strip_url(url) == strip_url(web_contents->GetLastCommittedURL())) { + return true; + } + } + return false; +} + std::vector<TabMatcher::TabWrapper> TabMatcherDesktop::GetOpenTabs( const AutocompleteInput* input) const { std::vector<TabMatcher::TabWrapper> open_tabs;
diff --git a/chrome/browser/autocomplete/tab_matcher_desktop.h b/chrome/browser/autocomplete/tab_matcher_desktop.h index 6dac770..93cb8f0 100644 --- a/chrome/browser/autocomplete/tab_matcher_desktop.h +++ b/chrome/browser/autocomplete/tab_matcher_desktop.h
@@ -22,6 +22,11 @@ bool IsTabOpenWithURL(const GURL& gurl, const AutocompleteInput* input, bool exclude_active_tab = true) const override; + bool IsTabOpenWithSameTitleOrSimilarURL( + const std::u16string& title, + const GURL& url, + const GURL::Replacements& replacements, + bool exclude_active_tab) const override; std::vector<TabMatcher::TabWrapper> GetOpenTabs( const AutocompleteInput* input) const override;
diff --git a/chrome/browser/autocomplete/tab_matcher_desktop_unittest.cc b/chrome/browser/autocomplete/tab_matcher_desktop_unittest.cc index 7377f6d7..94205a3 100644 --- a/chrome/browser/autocomplete/tab_matcher_desktop_unittest.cc +++ b/chrome/browser/autocomplete/tab_matcher_desktop_unittest.cc
@@ -8,6 +8,7 @@ #include "chrome/test/base/browser_with_test_window_test.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/search_engines/template_url_service.h" +#include "content/public/browser/navigation_entry.h" #include "testing/gtest/include/gtest/gtest.h" using TabMatcherDesktopTest = BrowserWithTestWindowTest; @@ -144,3 +145,54 @@ nullptr, /*exclude_active_tab =*/true)); } + +TEST_F(TabMatcherDesktopTest, IsTabOpenWithSameTitleOrSimilarURL) { + std::unique_ptr<TemplateURLService> turl_service = + TemplateURLServiceTestUtil::CreateTemplateURLServiceForTesting( + profile(), kServiceInitializers); + TabMatcherDesktop matcher(turl_service.get(), profile()); + + GURL foo("http://foo.org/path/#ref"); + AddTab(browser(), foo); + auto* tab_1 = browser()->tab_strip_model()->GetWebContentsAt(0); + content::NavigationEntry* entry = tab_1->GetController().GetVisibleEntry(); + tab_1->UpdateTitleForEntry(entry, u"Test"); + GURL bar("http://bar.org"); + AddTab(browser(), bar); + auto* tab_2 = browser()->tab_strip_model()->GetWebContentsAt(1); + content::NavigationEntry* entry_2 = tab_2->GetController().GetVisibleEntry(); + tab_2->UpdateTitleForEntry(entry_2, u"Testing"); + + GURL::Replacements replacements; + replacements.ClearQuery(); + + // Tabs with same title and url should be considered matches. + EXPECT_TRUE(matcher.IsTabOpenWithSameTitleOrSimilarURL( + u"Testing", GURL("http://bar.org"), replacements, + /*exclude_active_tab =*/false)); + + // Tabs with same title should be considered matches even if urls are + // different. + EXPECT_TRUE(matcher.IsTabOpenWithSameTitleOrSimilarURL( + u"Testing", GURL("http://different.org"), replacements, + /*exclude_active_tab =*/false)); + + // Sites with same path and different refs should be considered matches. + EXPECT_TRUE(matcher.IsTabOpenWithSameTitleOrSimilarURL( + u"Different name", GURL("http://foo.org/path/#differentref"), + replacements, + /*exclude_active_tab =*/false)); + + // Sites with different path should not be considered matches. + EXPECT_FALSE(matcher.IsTabOpenWithSameTitleOrSimilarURL( + u"Different name", GURL("http://foo.org/differentpath/#ref"), + replacements, + /*exclude_active_tab =*/false)); + + // Sites with same match and different refs and query params should be + // considered matches. + EXPECT_TRUE(matcher.IsTabOpenWithSameTitleOrSimilarURL( + u"Different name", GURL("http://foo.org/path/#ref?param=123"), + replacements, + /*exclude_active_tab =*/false)); +}
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelper.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelper.java index da3a775..590f31e 100644 --- a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelper.java +++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelper.java
@@ -8,17 +8,19 @@ import androidx.activity.OnBackPressedDispatcher; import androidx.lifecycle.LifecycleOwner; +import org.chromium.build.annotations.NullMarked; import org.chromium.components.browser_ui.widget.gesture.BackPressHandler; /** - * Helper class for back press event handling via {@link OnBackPressedDisptacher}. This is - * a recommended way over {@link Activity#onBackPressed}. Refer to the Android developer's guide + * Helper class for back press event handling via {@link OnBackPressedDisptacher}. This is a + * recommended way over {@link Activity#onBackPressed}. Refer to the Android developer's guide * {@link https://developer.android.com/guide/navigation/navigation-custom-back}. */ +@NullMarked public final class BackPressHelper { /** * @deprecated Handles back press event. #onBackPressed is deprecated starting from U. Prefer - * {@link BackPressHandler} whenever possible. + * {@link BackPressHandler} whenever possible. */ public interface ObsoleteBackPressedHandler { /**
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManager.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManager.java index bbaefd5b..d6b74f3 100644 --- a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManager.java +++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressManager.java
@@ -4,12 +4,13 @@ package org.chromium.chrome.browser.back_press; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.annotation.SuppressLint; import android.util.SparseIntArray; import androidx.activity.BackEventCompat; import androidx.activity.OnBackPressedCallback; -import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import org.chromium.base.Callback; @@ -17,6 +18,8 @@ import org.chromium.base.lifetime.Destroyable; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.supplier.Supplier; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.components.browser_ui.widget.gesture.BackPressHandler; import org.chromium.components.browser_ui.widget.gesture.BackPressHandler.BackPressResult; @@ -35,6 +38,7 @@ * BackPressHandler} with the new defined {@link Type}. * </ol> */ +@NullMarked public class BackPressManager implements Destroyable { private static final SparseIntArray sMetricsMap; private static final int sMetricsMaxValue; @@ -71,14 +75,14 @@ } private class OnBackPressedCallbackImpl extends OnBackPressedCallback { - private BackPressHandler mActiveHandler; - private BackEventCompat mLastBackEvent; + private @Nullable BackPressHandler mActiveHandler; + private @Nullable BackEventCompat mLastBackEvent; public OnBackPressedCallbackImpl(boolean enabled) { super(enabled); } - public void willRemoveHandler(@NonNull BackPressHandler handler) { + public void willRemoveHandler(BackPressHandler handler) { if (handler == mActiveHandler) { handleOnBackCancelled(); } @@ -126,7 +130,7 @@ // Following methods are only triggered on API 34+. @Override - public void handleOnBackStarted(@NonNull BackEventCompat backEvent) { + public void handleOnBackStarted(BackEventCompat backEvent) { mActiveHandler = getEnabledBackPressHandler(); assert mActiveHandler != null; mActiveHandler.handleOnBackStarted(backEvent); @@ -142,7 +146,7 @@ } @Override - public void handleOnBackProgressed(@NonNull BackEventCompat backEvent) { + public void handleOnBackProgressed(BackEventCompat backEvent) { if (mActiveHandler == null) return; mActiveHandler.handleOnBackProgressed(backEvent); } @@ -157,14 +161,14 @@ "Android.BackPress.Intercept.CustomTab.SeparateTask"; static final String FAILURE_HISTOGRAM = "Android.BackPress.Failure"; - private final BackPressHandler[] mHandlers = new BackPressHandler[Type.NUM_TYPES]; + private final @Nullable BackPressHandler[] mHandlers = new BackPressHandler[Type.NUM_TYPES]; private final boolean mUseSystemBack; private boolean mHasSystemBackArm; - private final Callback<Boolean>[] mObserverCallbacks = new Callback[Type.NUM_TYPES]; + private final @Nullable Callback<Boolean>[] mObserverCallbacks = new Callback[Type.NUM_TYPES]; private Runnable mFallbackOnBackPressed; private int mLastCalledHandlerType = -1; - private Runnable mOnBackPressed; + private @Nullable Runnable mOnBackPressed; private Supplier<Boolean> mIsGestureNavEnabledSupplier = () -> false; /** @@ -217,16 +221,18 @@ public void addHandler(BackPressHandler handler, @Type int type) { assert mHandlers[type] == null : "Each type can have at most one handler"; mHandlers[type] = handler; - mObserverCallbacks[type] = (t) -> backPressStateChanged(); - handler.getHandleBackPressChangedSupplier().addObserver(mObserverCallbacks[type]); + Callback<Boolean> observerCallback = (t) -> backPressStateChanged(); + mObserverCallbacks[type] = observerCallback; + handler.getHandleBackPressChangedSupplier().addObserver(observerCallback); backPressStateChanged(); } /** * Remove a registered handler. The methods of handler will not be called any more. + * * @param handler {@link BackPressHandler} to be removed. */ - public void removeHandler(@NonNull BackPressHandler handler) { + public void removeHandler(BackPressHandler handler) { for (int i = 0; i < mHandlers.length; i++) { if (mHandlers[i] == handler) { removeHandler(i); @@ -241,6 +247,9 @@ * @param type {@link Type} to be removed. */ public void removeHandler(@Type int type) { + assumeNonNull(mHandlers[type]); + assumeNonNull(mObserverCallbacks[type]); + BackPressHandler handler = mHandlers[type]; mCallback.willRemoveHandler(handler); handler.getHandleBackPressChangedSupplier().removeObserver(mObserverCallbacks[type]); @@ -311,7 +320,7 @@ } @VisibleForTesting - BackPressHandler getEnabledBackPressHandler() { + @Nullable BackPressHandler getEnabledBackPressHandler() { for (int i = 0; i < mHandlers.length; i++) { BackPressHandler handler = mHandlers[i]; if (handler == null) continue; @@ -375,7 +384,7 @@ return false; } - public BackPressHandler[] getHandlersForTesting() { + public @Nullable BackPressHandler[] getHandlersForTesting() { return mHandlers; }
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressMetrics.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressMetrics.java index 23039e7..5929e1c 100644 --- a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressMetrics.java +++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressMetrics.java
@@ -10,6 +10,7 @@ import androidx.annotation.IntDef; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.build.annotations.NullMarked; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.components.browser_ui.widget.gesture.BackPressHandler.Type; import org.chromium.ui.UiUtils; @@ -22,6 +23,7 @@ * A utility class to record back press related histograms. TODO(crbug.com/41481803): Move other * histogram recording to this class. */ +@NullMarked public class BackPressMetrics { private static final String EDGE_HISTOGRAM = "Android.BackPress.SwipeEdge"; private static final String TAB_HISTORY_EDGE_HISTOGRAM =
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/CloseListenerManager.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/CloseListenerManager.java index c8d7b78..433d5999 100644 --- a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/CloseListenerManager.java +++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/CloseListenerManager.java
@@ -4,10 +4,14 @@ package org.chromium.chrome.browser.back_press; +import static org.chromium.build.NullUtil.assumeNonNull; + import org.chromium.base.Callback; 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.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabObserver; @@ -19,13 +23,14 @@ * Class responsible for ensuring a web-exposed CloseWatcher is able to intercept a back gesture and * perform an app-specific behavior. */ +@NullMarked public class CloseListenerManager implements BackPressHandler, Destroyable { private final ObservableSupplierImpl<Boolean> mBackPressChangedSupplier = new ObservableSupplierImpl<>(); private final ObservableSupplier<Tab> mActivityTabSupplier; private final Callback<Tab> mOnTabChanged = this::onTabChanged; - private Tab mTab; - private TabObserver mTabObserver; + private @Nullable Tab mTab; + private @Nullable TabObserver mTabObserver; public CloseListenerManager(ObservableSupplier<Tab> activityTabSupplier) { mActivityTabSupplier = activityTabSupplier; @@ -50,6 +55,7 @@ public void destroy() { mActivityTabSupplier.removeObserver(mOnTabChanged); if (mTabObserver != null) { + assumeNonNull(mTab); mTab.removeObserver(mTabObserver); mTabObserver = null; mTab = null; @@ -63,6 +69,7 @@ private void updateObserver() { if (mTabObserver != null) { + assumeNonNull(mTab); mTab.removeObserver(mTabObserver); mTabObserver = null; } @@ -93,7 +100,7 @@ return getFocusedFrameIfCloseWatcherActive() != null; } - private RenderFrameHost getFocusedFrameIfCloseWatcherActive() { + private @Nullable RenderFrameHost getFocusedFrameIfCloseWatcherActive() { Tab tab = mActivityTabSupplier.get(); if (tab == null) return null; WebContents contents = tab.getWebContents();
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandler.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandler.java index d6a383c..5d8f37f 100644 --- a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandler.java +++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandler.java
@@ -16,6 +16,8 @@ import org.chromium.base.metrics.RecordHistogram; 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.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabAssociatedApp; import org.chromium.chrome.browser.ui.native_page.NativePage; @@ -28,6 +30,7 @@ * The back press handler as the final step of back press handling. This is always enabled in order * to manually minimize app and close tab if necessary. */ +@NullMarked public class MinimizeAppAndCloseTabBackPressHandler implements BackPressHandler, Destroyable { static final String HISTOGRAM = "Android.BackPress.MinimizeAppAndCloseTab"; static final String HISTOGRAM_CUSTOM_TAB_SAME_TASK = @@ -44,12 +47,12 @@ private final ObservableSupplierImpl<Boolean> mNonSystemBackPressSupplier = new ObservableSupplierImpl<>(); private final Predicate<Tab> mBackShouldCloseTab; - private final Callback<Tab> mSendToBackground; + private final Callback<@Nullable Tab> mSendToBackground; private final Callback<Tab> mOnTabChanged = this::onTabChanged; private final ObservableSupplier<Tab> mActivityTabSupplier; private final boolean mUseSystemBack; - private static Integer sVersionForTesting; + private static @Nullable Integer sVersionForTesting; @IntDef({ MinimizeAppAndCloseTabType.MINIMIZE_APP, @@ -96,7 +99,7 @@ public MinimizeAppAndCloseTabBackPressHandler( ObservableSupplier<Tab> activityTabSupplier, Predicate<Tab> backShouldCloseTab, - Callback<Tab> sendToBackground) { + Callback<@Nullable Tab> sendToBackground) { mBackShouldCloseTab = backShouldCloseTab; mSendToBackground = sendToBackground; mActivityTabSupplier = activityTabSupplier;
diff --git a/chrome/browser/bitmap_fetcher/bitmap_fetcher_browsertest.cc b/chrome/browser/bitmap_fetcher/bitmap_fetcher_browsertest.cc index cd9fdd4..ae693e69 100644 --- a/chrome/browser/bitmap_fetcher/bitmap_fetcher_browsertest.cc +++ b/chrome/browser/bitmap_fetcher/bitmap_fetcher_browsertest.cc
@@ -156,7 +156,7 @@ // an image in a callback to OnImageDecoded(). fetcher.Init( net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, - network::mojom::CredentialsMode::kInclude); + network::mojom::CredentialsMode::kOmit); fetcher.Start(browser() ->profile() ->GetDefaultStoragePartition() @@ -202,7 +202,7 @@ fetcher.Init( net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, - network::mojom::CredentialsMode::kInclude); + network::mojom::CredentialsMode::kOmit); fetcher.Start(browser() ->profile() ->GetDefaultStoragePartition() @@ -222,7 +222,7 @@ fetcher.Init( net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, - network::mojom::CredentialsMode::kInclude); + network::mojom::CredentialsMode::kOmit); fetcher.Start(browser() ->profile() ->GetDefaultStoragePartition() @@ -242,7 +242,7 @@ fetcher.Init( net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, - network::mojom::CredentialsMode::kInclude); + network::mojom::CredentialsMode::kOmit); fetcher.Start(browser() ->profile() ->GetDefaultStoragePartition() @@ -265,7 +265,7 @@ fetcher.Init( net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, - network::mojom::CredentialsMode::kInclude); + network::mojom::CredentialsMode::kOmit); fetcher.Start(browser() ->profile() ->GetDefaultStoragePartition() @@ -295,7 +295,7 @@ fetcher.Init( net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, - network::mojom::CredentialsMode::kInclude); + network::mojom::CredentialsMode::kOmit); fetcher.Start(browser() ->profile() ->GetDefaultStoragePartition() @@ -345,7 +345,7 @@ BitmapFetcher fetcher(image_url, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); fetcher.Init(net::ReferrerPolicy::NEVER_CLEAR, - network::mojom::CredentialsMode::kInclude, + network::mojom::CredentialsMode::kOmit, net::HttpRequestHeaders(), /*initiator=*/url::Origin::Create(image_url)); fetcher.Start(browser()
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 832610d..9755339 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -6188,9 +6188,7 @@ std::vector<std::unique_ptr<blink::URLLoaderThrottle>> ChromeContentBrowserClient::CreateURLLoaderThrottlesForKeepAlive( - const network::ResourceRequest& request, content::BrowserContext* browser_context, - const base::RepeatingCallback<content::WebContents*()>& wc_getter, content::FrameTreeNodeId frame_tree_node_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -6200,15 +6198,6 @@ Profile* profile = Profile::FromBrowserContext(browser_context); DCHECK(profile); -#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) - if (auto safe_browsing_throttle = MaybeCreateSafeBrowsingURLLoaderThrottle( - request, browser_context, wc_getter, frame_tree_node_id, - /*navigation_id=*/std::nullopt, profile); - safe_browsing_throttle) { - result.push_back(std::move(safe_browsing_throttle)); - } -#endif - #if BUILDFLAG(IS_ANDROID) auto [client_data_header, unused_is_custom_tab] = GetClientDataHeader(frame_tree_node_id); @@ -7205,17 +7194,16 @@ return content::VideoOverlayWindow::Create(controller); } -media::PictureInPictureEventsInfo::AutoPipReason -ChromeContentBrowserClient::GetAutoPipReason( +media::PictureInPictureEventsInfo::AutoPipInfo +ChromeContentBrowserClient::GetAutoPipInfo( const content::WebContents& web_contents) const { #if BUILDFLAG(IS_ANDROID) - return media::PictureInPictureEventsInfo::AutoPipReason::kUnknown; + return media::PictureInPictureEventsInfo::AutoPipInfo(); #else auto* auto_pip_tab_helper = AutoPictureInPictureTabHelper::FromWebContents(&web_contents); - return auto_pip_tab_helper - ? auto_pip_tab_helper->GetAutoPipTriggerReason() - : media::PictureInPictureEventsInfo::AutoPipReason::kUnknown; + return auto_pip_tab_helper ? auto_pip_tab_helper->GetAutoPipInfo() + : media::PictureInPictureEventsInfo::AutoPipInfo(); #endif // BUILDFLAG(IS_ANDROID) }
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index c7cfc32..0535ba1 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -652,9 +652,7 @@ std::optional<int64_t> navigation_id) override; std::vector<std::unique_ptr<blink::URLLoaderThrottle>> CreateURLLoaderThrottlesForKeepAlive( - const network::ResourceRequest& request, content::BrowserContext* browser_context, - const base::RepeatingCallback<content::WebContents*()>& wc_getter, content::FrameTreeNodeId frame_tree_node_id) override; mojo::PendingRemote<network::mojom::URLLoaderFactory> CreateNonNetworkNavigationURLLoaderFactory( @@ -811,7 +809,7 @@ std::unique_ptr<content::VideoOverlayWindow> CreateWindowForVideoPictureInPicture( content::VideoPictureInPictureWindowController* controller) override; - media::PictureInPictureEventsInfo::AutoPipReason GetAutoPipReason( + media::PictureInPictureEventsInfo::AutoPipInfo GetAutoPipInfo( const content::WebContents& web_contents) const override; void RegisterRendererPreferenceWatcher( content::BrowserContext* browser_context,
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc index 13fbc1cd..9abff07 100644 --- a/chrome/browser/chrome_content_browser_client_unittest.cc +++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -359,7 +359,7 @@ url::Origin::Create(GURL("c.test")))); } -TEST_F(ChromeContentBrowserClientWindowTest, GetAutoPipReason) { +TEST_F(ChromeContentBrowserClientWindowTest, GetAutoPipInfo_AutoPipReason) { ChromeContentBrowserClient client; const GURL url("https://www.google.com"); @@ -378,18 +378,18 @@ AutoPictureInPictureTabHelper::FromWebContents(web_contents); ASSERT_NE(nullptr, tab_helper); EXPECT_EQ(media::PictureInPictureEventsInfo::AutoPipReason::kUnknown, - client.GetAutoPipReason(*web_contents)); + client.GetAutoPipInfo(*web_contents).auto_pip_reason); tab_helper->set_auto_pip_trigger_reason_for_testing( media::PictureInPictureEventsInfo::AutoPipReason::kVideoConferencing); EXPECT_EQ( media::PictureInPictureEventsInfo::AutoPipReason::kVideoConferencing, - client.GetAutoPipReason(*web_contents)); + client.GetAutoPipInfo(*web_contents).auto_pip_reason); tab_helper->set_auto_pip_trigger_reason_for_testing( media::PictureInPictureEventsInfo::AutoPipReason::kMediaPlayback); EXPECT_EQ(media::PictureInPictureEventsInfo::AutoPipReason::kMediaPlayback, - client.GetAutoPipReason(*web_contents)); + client.GetAutoPipInfo(*web_contents).auto_pip_reason); } #endif // !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.cc b/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.cc index 49a7310..0a07435 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.cc +++ b/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.cc
@@ -106,7 +106,6 @@ public: explicit DlpWidgetDelegate(DlpDataTransferNotifier* notifier) : notifier_(notifier) { - SetOwnedByWidget(false); SetFocusTraversesOut(true); }
diff --git a/chrome/browser/contextual_cueing/contextual_cueing_service.cc b/chrome/browser/contextual_cueing/contextual_cueing_service.cc index d1a6050b..c23f281d 100644 --- a/chrome/browser/contextual_cueing/contextual_cueing_service.cc +++ b/chrome/browser/contextual_cueing/contextual_cueing_service.cc
@@ -174,12 +174,17 @@ // Temporary trigger for suggestions request, to be removed when UI is ready. if (activity == tabs::GlicNudgeActivity::kNudgeClicked && base::FeatureList::IsEnabled(kGlicZeroStateSuggestions)) { - ZeroStateSuggestionsPageData::CreateForPage( - web_contents->GetPrimaryPage(), web_contents, - optimization_guide_keyed_service_, /*is_fre=*/false, base::DoNothing()); + GetContextualGlicZeroStateSuggestions(web_contents, /*is_fre=*/false, + base::DoNothing()); } } +void ContextualCueingService::PrepareToFetchContextualGlicZeroStateSuggestions( + content::WebContents* web_contents) { + // This call preflights grabbing the page content. + ZeroStateSuggestionsPageData::CreateForPage(web_contents->GetPrimaryPage()); +} + void ContextualCueingService::GetContextualGlicZeroStateSuggestions( content::WebContents* web_contents, bool is_fre, @@ -187,11 +192,12 @@ // TODO(crbug.com/405988283): Add branch for hints suggestions. // Remote suggestions generation. - ZeroStateSuggestionsPageData::CreateForPage( - web_contents->GetPrimaryPage(), web_contents, - optimization_guide_keyed_service_, is_fre, - base::BindOnce(&ContextualCueingService::OnSuggestionsReceived, - GetWeakPtr(), web_contents, std::move(callback))); + ZeroStateSuggestionsPageData* page_data = + ZeroStateSuggestionsPageData::GetOrCreateForPage( + web_contents->GetPrimaryPage()); + page_data->FetchSuggestions( + is_fre, base::BindOnce(&ContextualCueingService::OnSuggestionsReceived, + GetWeakPtr(), web_contents, std::move(callback))); } void ContextualCueingService::OnSuggestionsReceived(
diff --git a/chrome/browser/contextual_cueing/contextual_cueing_service.h b/chrome/browser/contextual_cueing/contextual_cueing_service.h index 327f232..451f175 100644 --- a/chrome/browser/contextual_cueing/contextual_cueing_service.h +++ b/chrome/browser/contextual_cueing/contextual_cueing_service.h
@@ -68,6 +68,13 @@ return weak_ptr_factory_.GetWeakPtr(); } + // Informs `this` to prepare fetching for zero state suggestions for GLIC. + // Note that this *will not* actually do the fetch and it is intended for the + // caller to call `GetContextualGlicZeroStateSuggestions` to actually fetch + // the suggestions. + void PrepareToFetchContextualGlicZeroStateSuggestions( + content::WebContents* web_contents); + // Returns zero state suggestions for GLIC. void GetContextualGlicZeroStateSuggestions(content::WebContents* web_contents, bool is_fre,
diff --git a/chrome/browser/contextual_cueing/contextual_cueing_service_browsertest.cc b/chrome/browser/contextual_cueing/contextual_cueing_service_browsertest.cc index 8d464e3..b91d260 100644 --- a/chrome/browser/contextual_cueing/contextual_cueing_service_browsertest.cc +++ b/chrome/browser/contextual_cueing/contextual_cueing_service_browsertest.cc
@@ -2,11 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/contextual_cueing/contextual_cueing_service.h" + +#include <optional> +#include <string> +#include <vector> + +#include "base/test/metrics/histogram_tester.h" +#include "base/test/test_future.h" #include "chrome/browser/contextual_cueing/contextual_cueing_features.h" #include "chrome/browser/contextual_cueing/contextual_cueing_service_factory.h" #include "chrome/browser/extensions/keyed_services/browser_context_keyed_service_factories.h" +#include "chrome/browser/optimization_guide/browser_test_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "content/public/test/browser_test.h" namespace contextual_cueing { @@ -38,6 +48,59 @@ browser()->profile())); } +IN_PROC_BROWSER_TEST_F(ContextualCueingServiceBrowserTestZSSFlag, + PrepareFetchesPageContentButNoModelExecution) { + base::HistogramTester histogram_tester; + + auto* service = + ContextualCueingServiceFactory::GetForProfile(browser()->profile()); + + ASSERT_TRUE(embedded_test_server()->Start()); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), + embedded_test_server()->GetURL("/optimization_guide/zss_page.html"))); + + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + service->PrepareToFetchContextualGlicZeroStateSuggestions(web_contents); + + optimization_guide::RetryForHistogramUntilCountReached( + &histogram_tester, + "ContextualCueing.ZeroStateSuggestions.ContextExtractionDone", 1); + + histogram_tester.ExpectUniqueSample( + "ContextualCueing.ZeroStateSuggestions.ContextExtractionDone", true, 1); + histogram_tester.ExpectTotalCount( + "OptimizationGuide.ModelExecutionFetcher.RequestStatus." + "ZeroStateSuggestions", + 0); +} + +IN_PROC_BROWSER_TEST_F(ContextualCueingServiceBrowserTestZSSFlag, + GetFetchesSuggestions) { + base::HistogramTester histogram_tester; + + auto* service = + ContextualCueingServiceFactory::GetForProfile(browser()->profile()); + + ASSERT_TRUE(embedded_test_server()->Start()); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), + embedded_test_server()->GetURL("/optimization_guide/zss_page.html"))); + + base::test::TestFuture<std::optional<std::vector<std::string>>> future; + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + service->GetContextualGlicZeroStateSuggestions(web_contents, /*is_fre=*/true, + future.GetCallback()); + ASSERT_TRUE(future.Wait()); + + histogram_tester.ExpectUniqueSample( + "ContextualCueing.ZeroStateSuggestions.ContextExtractionDone", true, 1); + histogram_tester.ExpectTotalCount( + "OptimizationGuide.ModelExecutionFetcher.RequestStatus." + "ZeroStateSuggestions", + 1); +} + class ContextualCueingServiceBrowserTestCCFlag : public ContextualCueingServiceBrowserTest { public:
diff --git a/chrome/browser/contextual_cueing/zero_state_suggestions_page_data.cc b/chrome/browser/contextual_cueing/zero_state_suggestions_page_data.cc index 1e83956f..2847e888 100644 --- a/chrome/browser/contextual_cueing/zero_state_suggestions_page_data.cc +++ b/chrome/browser/contextual_cueing/zero_state_suggestions_page_data.cc
@@ -4,10 +4,13 @@ #include "chrome/browser/contextual_cueing/zero_state_suggestions_page_data.h" +#include "base/metrics/histogram_macros_local.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/content_extraction/inner_text.h" #include "chrome/browser/contextual_cueing/contextual_cueing_features.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" +#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" +#include "chrome/browser/profiles/profile.h" #include "components/optimization_guide/core/model_execution/optimization_guide_model_execution_error.h" #include "components/optimization_guide/core/optimization_guide_common.mojom.h" #include "components/optimization_guide/core/optimization_guide_logger.h" @@ -17,28 +20,18 @@ namespace contextual_cueing { -ZeroStateSuggestionsPageData::ZeroStateSuggestionsPageData( - content::Page& page, - content::WebContents* web_contents, - OptimizationGuideKeyedService* ogks, - bool is_fre, - GlicSuggestionsCallback suggestions_callback) - : content::PageUserData<ZeroStateSuggestionsPageData>(page), - begin_time_(base::TimeTicks::Now()), - optimization_guide_keyed_service_(ogks), - suggestions_callback_(std::move(suggestions_callback)) { +ZeroStateSuggestionsPageData::ZeroStateSuggestionsPageData(content::Page& page) + : content::PageUserData<ZeroStateSuggestionsPageData>(page) { CHECK(base::FeatureList::IsEnabled(kGlicZeroStateSuggestions)); CHECK(kExtractInnerTextForZeroStateSuggestions.Get() || kExtractAnnotatedPageContentForZeroStateSuggestions.Get()); - suggestions_request_.set_is_fre(is_fre); - optimization_guide::proto::PageContext* page_context = - suggestions_request_.mutable_page_context(); - const GURL& page_url = web_contents->GetLastCommittedURL(); - if (!page_url.is_empty() && page_url.is_valid()) { - page_context->set_url(page_url.spec()); - } - page_context->set_title(base::UTF16ToUTF8(web_contents->GetTitle())); + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(&(page.GetMainDocument())); + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + optimization_guide_keyed_service_ = + OptimizationGuideKeyedServiceFactory::GetForProfile(profile); if (kExtractAnnotatedPageContentForZeroStateSuggestions.Get()) { blink::mojom::AIPageContentOptionsPtr ai_page_content_options; @@ -71,6 +64,18 @@ ZeroStateSuggestionsPageData::~ZeroStateSuggestionsPageData() = default; +void ZeroStateSuggestionsPageData::FetchSuggestions( + bool is_fre, + GlicSuggestionsCallback callback) { + begin_time_ = base::TimeTicks::Now(); + + suggestions_request_ = optimization_guide::proto:: + ZeroStateSuggestionsRequest::default_instance(); + suggestions_request_->set_is_fre(is_fre); + suggestions_callback_ = std::move(callback); + RequestSuggestionsIfComplete(); +} + void ZeroStateSuggestionsPageData::OnReceivedAnnotatedPageContent( std::optional<optimization_guide::AIPageContentResult> content) { annotated_page_content_ = std::move(content); @@ -91,23 +96,41 @@ if (!work_done) { return; } + + LOCAL_HISTOGRAM_BOOLEAN( + "ContextualCueing.ZeroStateSuggestions.ContextExtractionDone", true); + + if (!suggestions_request_) { + return; + } + if (!has_page_context) { std::move(suggestions_callback_).Run(std::nullopt); return; } + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(&page().GetMainDocument()); + + optimization_guide::proto::PageContext* page_context = + suggestions_request_->mutable_page_context(); + const GURL& page_url = web_contents->GetLastCommittedURL(); + if (!page_url.is_empty() && page_url.is_valid()) { + page_context->set_url(page_url.spec()); + } + page_context->set_title(base::UTF16ToUTF8(web_contents->GetTitle())); + if (annotated_page_content_) { - *suggestions_request_.mutable_page_context() - ->mutable_annotated_page_content() = annotated_page_content_->proto; + *page_context->mutable_annotated_page_content() = + annotated_page_content_->proto; } if (inner_text_result_) { - suggestions_request_.mutable_page_context()->set_inner_text( - inner_text_result_->inner_text); + page_context->set_inner_text(inner_text_result_->inner_text); } optimization_guide_keyed_service_->ExecuteModel( optimization_guide::ModelBasedCapabilityKey::kZeroStateSuggestions, - suggestions_request_, + *suggestions_request_, /*execution_timeout=*/std::nullopt, base::BindOnce(&ZeroStateSuggestionsPageData::OnModelExecutionResponse, weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/contextual_cueing/zero_state_suggestions_page_data.h b/chrome/browser/contextual_cueing/zero_state_suggestions_page_data.h index 4992fe04..29f692f 100644 --- a/chrome/browser/contextual_cueing/zero_state_suggestions_page_data.h +++ b/chrome/browser/contextual_cueing/zero_state_suggestions_page_data.h
@@ -12,10 +12,6 @@ class OptimizationGuideKeyedService; -namespace content { -class WebContents; -} // namespace content - namespace content_extraction { struct InnerTextResult; } // namespace content_extraction @@ -42,15 +38,15 @@ delete; ~ZeroStateSuggestionsPageData() override; + // Explicitly fetch suggestions for this page. + void FetchSuggestions(bool is_fre, GlicSuggestionsCallback callback); + private: friend class content::PageUserData<ZeroStateSuggestionsPageData>; friend class ZeroStateSuggestionsPageDataTest; - ZeroStateSuggestionsPageData(content::Page& page, - content::WebContents* web_contents, - OptimizationGuideKeyedService* ogks, - bool is_fre, - GlicSuggestionsCallback callback); + // Note that this constructor initiates extracting page content. + explicit ZeroStateSuggestionsPageData(content::Page& page); // Called when inner text is extracted. void OnReceivedInnerText( @@ -74,7 +70,8 @@ bool annotated_page_content_done_ = false; std::optional<optimization_guide::AIPageContentResult> annotated_page_content_; - optimization_guide::proto::ZeroStateSuggestionsRequest suggestions_request_; + std::optional<optimization_guide::proto::ZeroStateSuggestionsRequest> + suggestions_request_; // Timestamp of when `this` is created, i.e. before any fetch or request // is sent.
diff --git a/chrome/browser/contextual_cueing/zero_state_suggestions_page_data_browsertest.cc b/chrome/browser/contextual_cueing/zero_state_suggestions_page_data_browsertest.cc index 103a5cf..af0e9778 100644 --- a/chrome/browser/contextual_cueing/zero_state_suggestions_page_data_browsertest.cc +++ b/chrome/browser/contextual_cueing/zero_state_suggestions_page_data_browsertest.cc
@@ -4,9 +4,12 @@ #include "chrome/browser/contextual_cueing/zero_state_suggestions_page_data.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/test_future.h" #include "chrome/browser/contextual_cueing/contextual_cueing_features.h" +#include "chrome/browser/optimization_guide/browser_test_util.h" #include "chrome/browser/optimization_guide/mock_optimization_guide_keyed_service.h" +#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" @@ -53,10 +56,35 @@ /*disabled_features=*/{}); } + void SetUpBrowserContextKeyedServices( + content::BrowserContext* browser_context) override { + mock_optimization_guide_keyed_service_ = + static_cast<testing::NiceMock<MockOptimizationGuideKeyedService>*>( + OptimizationGuideKeyedServiceFactory::GetInstance() + ->SetTestingFactoryAndUse( + browser_context, + base::BindRepeating([](content::BrowserContext* context) + -> std::unique_ptr<KeyedService> { + return std::make_unique<testing::NiceMock< + MockOptimizationGuideKeyedService>>(); + }))); + } + + void PostRunTestOnMainThread() override { + mock_optimization_guide_keyed_service_ = nullptr; + InProcessBrowserTest::PostRunTestOnMainThread(); + } + ContentExtraction GetContentExtraction() const { return GetParam(); } + MockOptimizationGuideKeyedService& mock_optimization_guide_keyed_service() { + return *mock_optimization_guide_keyed_service_; + } + private: base::test::ScopedFeatureList scoped_feature_list_; + raw_ptr<testing::NiceMock<MockOptimizationGuideKeyedService>> + mock_optimization_guide_keyed_service_; }; INSTANTIATE_TEST_SUITE_P( @@ -68,9 +96,9 @@ ContentExtraction::kFetchInnerTextAndAnnotatedPageContent)); IN_PROC_BROWSER_TEST_P(ZeroStateSuggestionsPageDataBrowserTest, BasicFlow) { - auto fake_optimization_guide_keyed_service = - testing::NiceMock<MockOptimizationGuideKeyedService>(); - ON_CALL(fake_optimization_guide_keyed_service, ExecuteModel(_, _, _, _)) + base::HistogramTester histogram_tester; + + ON_CALL(mock_optimization_guide_keyed_service(), ExecuteModel(_, _, _, _)) .WillByDefault(WithArgs<1, 3>( [&](const google::protobuf::MessageLite& request_metadata, optimization_guide::OptimizationGuideModelExecutionResultCallback @@ -118,14 +146,37 @@ base::test::TestFuture<std::optional<std::vector<std::string>>> future; - ZeroStateSuggestionsPageData::CreateForPage( - web_contents->GetPrimaryPage(), web_contents, - &fake_optimization_guide_keyed_service, /*is_fre=*/false, - future.GetCallback()); + auto* page_data = ZeroStateSuggestionsPageData::GetOrCreateForPage( + web_contents->GetPrimaryPage()); + page_data->FetchSuggestions(/*is_fre=*/false, future.GetCallback()); ASSERT_TRUE(future.Wait()); EXPECT_EQ("suggestion 1", future.Get().value()[0]); EXPECT_EQ("suggestion 2", future.Get().value()[1]); EXPECT_EQ("suggestion 3", future.Get().value()[2]); + histogram_tester.ExpectUniqueSample( + "ContextualCueing.ZeroStateSuggestions.ContextExtractionDone", true, 1); +} + +IN_PROC_BROWSER_TEST_P(ZeroStateSuggestionsPageDataBrowserTest, + CreateDataDoesNotFetchWithoutExplicitCall) { + base::HistogramTester histogram_tester; + + EXPECT_CALL(mock_optimization_guide_keyed_service(), ExecuteModel).Times(0); + + ASSERT_TRUE(embedded_test_server()->Start()); + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), + embedded_test_server()->GetURL("/optimization_guide/zss_page.html"))); + + ZeroStateSuggestionsPageData::CreateForPage(web_contents->GetPrimaryPage()); + + optimization_guide::RetryForHistogramUntilCountReached( + &histogram_tester, + "ContextualCueing.ZeroStateSuggestions.ContextExtractionDone", 1); + + histogram_tester.ExpectUniqueSample( + "ContextualCueing.ZeroStateSuggestions.ContextExtractionDone", true, 1); } } // namespace contextual_cueing
diff --git a/chrome/browser/device_api/device_service_impl.cc b/chrome/browser/device_api/device_service_impl.cc index a15e2e77..2722b61 100644 --- a/chrome/browser/device_api/device_service_impl.cc +++ b/chrome/browser/device_api/device_service_impl.cc
@@ -8,6 +8,7 @@ #include "base/check_deref.h" #include "base/check_is_test.h" #include "base/containers/contains.h" +#include "base/feature_list.h" #include "base/functional/bind.h" #include "build/build_config.h" #include "chrome/browser/app_mode/app_mode_utils.h" @@ -23,12 +24,14 @@ #include "chrome/browser/web_applications/web_app_filter.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" +#include "chrome/browser/web_applications/web_app_tab_helper.h" #include "chrome/common/pref_names.h" #include "components/permissions/features.h" #include "components/prefs/pref_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "third_party/blink/public/common/features_generated.h" #include "url/gurl.h" #include "url/origin.h" @@ -164,6 +167,39 @@ return IsForceInstalledOrigin(host, origin); } +bool IsIwa(content::RenderFrameHost& host) { + if (auto* web_app_id = web_app::WebAppTabHelper::GetAppId( + content::WebContents::FromRenderFrameHost(&host))) { + return web_app::WebAppProvider::GetForWebApps(GetProfile(host)) + ->registrar_unsafe() + .IsIsolated(*web_app_id); + } + return false; +} + +bool IsPermissionsPolicyFeatureEnabled() { + return base::FeatureList::IsEnabled( + blink::features::kDeviceAttributesPermissionPolicy); +} + +bool IsAllowedByPermissionsPolicy(content::RenderFrameHost& host) { + if (!IsPermissionsPolicyFeatureEnabled()) { + return true; + } + return host.IsFeatureEnabled( + network::mojom::PermissionsPolicyFeature::kDeviceAttributes); +} + +bool IsBlockedByAdminPolicy(content::RenderFrameHost& host, + const url::Origin& origin) { + if (IsPermissionsPolicyFeatureEnabled() && IsIwa(host)) { + return false; + } + return !policy::IsOriginInAllowlist( + origin.GetURL(), GetPrefs(host), + prefs::kDeviceAttributesAllowedForOrigins); +} + } // namespace DeviceServiceImpl::DeviceServiceImpl( @@ -213,6 +249,11 @@ // user. return; } + if (!IsAllowedByPermissionsPolicy(*host)) { + mojo::ReportBadMessage( + "Permissions policy blocks access to Device Attribtes."); + return; + } // The object is bound to the lifetime of |host| and the mojo // connection. See DocumentService for details. new DeviceServiceImpl(*host, std::move(receiver), @@ -294,9 +335,7 @@ return; } - if (!policy::IsOriginInAllowlist(origin().GetURL(), - GetPrefs(render_frame_host()), - prefs::kDeviceAttributesAllowedForOrigins)) { + if (IsBlockedByAdminPolicy(render_frame_host(), origin())) { device_attribute_api_->ReportNotAllowedError(std::move(callback)); return; }
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc index 51db30b..3a84e112 100644 --- a/chrome/browser/devtools/devtools_browsertest.cc +++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -1862,8 +1862,8 @@ RunTest("testConsoleContextNames", kPageWithContentScript); } -// TODO(crbug.com/40930033): Flaky on Linux and ChromeOS Tests. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) +// TODO(crbug.com/40930033): Flaky on Linux, ChromeOS, and macOS Tests. +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) #define MAYBE_CantInspectNewTabPage DISABLED_CantInspectNewTabPage #else #define MAYBE_CantInspectNewTabPage CantInspectNewTabPage
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc index afaa15a3..0b43b82 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_browsertest.cc
@@ -50,57 +50,6 @@ namespace enterprise_connectors { -namespace { - -constexpr base::TimeDelta kNoDelay = base::Seconds(0); -constexpr base::TimeDelta kSmallDelay = base::Milliseconds(300); -constexpr base::TimeDelta kNormalDelay = base::Milliseconds(500); - -constexpr char kBlockingScansForDlpAndMalware[] = R"( -{ - "service_provider": "google", - "enable": [ - { - "url_list": ["*"], - "tags": ["dlp", "malware"] - } - ], - "block_until_verdict": 1 -})"; - -constexpr char kBlockingScansForDlp[] = R"( -{ - "service_provider": "google", - "enable": [ - { - "url_list": ["*"], - "tags": ["dlp"] - } - ], - "block_until_verdict": 1 -})"; - -constexpr char kBlockingScansForDlpAndMalwareWithCustomMessage[] = R"( -{ - "service_provider": "google", - "enable": [ - { - "url_list": ["*"], - "tags": ["dlp", "malware"] - } - ], - "block_until_verdict": 1, - "custom_messages": [{ - "message": "Custom message", - "learn_more_url": "http://www.example.com/", - "tag": "dlp" - }] -})"; - -std::string text() { - return std::string(100, 'a'); -} - // Tests the behavior of the dialog in the following ways: // - It shows the appropriate buttons depending on its state. // - It transitions from states in the correct order. @@ -329,6 +278,57 @@ views::test::AXEventCounter ax_event_counter_; }; +namespace { + +constexpr base::TimeDelta kNoDelay = base::Seconds(0); +constexpr base::TimeDelta kSmallDelay = base::Milliseconds(300); +constexpr base::TimeDelta kNormalDelay = base::Milliseconds(500); + +constexpr char kBlockingScansForDlpAndMalware[] = R"( +{ + "service_provider": "google", + "enable": [ + { + "url_list": ["*"], + "tags": ["dlp", "malware"] + } + ], + "block_until_verdict": 1 +})"; + +constexpr char kBlockingScansForDlp[] = R"( +{ + "service_provider": "google", + "enable": [ + { + "url_list": ["*"], + "tags": ["dlp"] + } + ], + "block_until_verdict": 1 +})"; + +constexpr char kBlockingScansForDlpAndMalwareWithCustomMessage[] = R"( +{ + "service_provider": "google", + "enable": [ + { + "url_list": ["*"], + "tags": ["dlp", "malware"] + } + ], + "block_until_verdict": 1, + "custom_messages": [{ + "message": "Custom message", + "learn_more_url": "http://www.example.com/", + "tag": "dlp" + }] +})"; + +std::string text() { + return std::string(100, 'a'); +} + // Tests the behavior of the dialog in the following ways: // - It closes when the "Cancel" button is clicked. // - It returns a negative verdict on the scanned content.
diff --git a/chrome/browser/enterprise/reporting/report_scheduler_android.cc b/chrome/browser/enterprise/reporting/report_scheduler_android.cc index 38d4812..9e529190 100644 --- a/chrome/browser/enterprise/reporting/report_scheduler_android.cc +++ b/chrome/browser/enterprise/reporting/report_scheduler_android.cc
@@ -23,6 +23,10 @@ return prefs_; } +void ReportSchedulerAndroid::OnInitializationCompleted() { + // No-op. +} + void ReportSchedulerAndroid::StartWatchingUpdatesIfNeeded( base::Time last_upload, base::TimeDelta upload_interval) { @@ -37,6 +41,20 @@ // No-op because in-app auto-update is not supported on Android. } +bool ReportSchedulerAndroid::AreSecurityReportsEnabled() { + // Not supported. + return false; +} + +bool ReportSchedulerAndroid::UseCookiesInUploads() { + // Not supported. + return false; +} + +void ReportSchedulerAndroid::OnSecuritySignalsUploaded() { + // No-op because signals reporting is not supported on Android. +} + policy::DMToken ReportSchedulerAndroid::GetProfileDMToken() { std::optional<std::string> dm_token = reporting::GetUserDmToken(profile_); if (!dm_token || dm_token->empty())
diff --git a/chrome/browser/enterprise/reporting/report_scheduler_android.h b/chrome/browser/enterprise/reporting/report_scheduler_android.h index 204bdea2..eee2be1 100644 --- a/chrome/browser/enterprise/reporting/report_scheduler_android.h +++ b/chrome/browser/enterprise/reporting/report_scheduler_android.h
@@ -23,10 +23,14 @@ // ReportScheduler::Delegate implementation. PrefService* GetPrefService() override; + void OnInitializationCompleted() override; void StartWatchingUpdatesIfNeeded(base::Time last_upload, base::TimeDelta upload_interval) override; void StopWatchingUpdates() override; void OnBrowserVersionUploaded() override; + bool AreSecurityReportsEnabled() override; + bool UseCookiesInUploads() override; + void OnSecuritySignalsUploaded() override; policy::DMToken GetProfileDMToken() override; std::string GetProfileClientId() override;
diff --git a/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc b/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc index 4f1e791a..7679bc1 100644 --- a/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc +++ b/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc
@@ -18,6 +18,7 @@ #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" +#include "components/device_signals/core/common/signals_features.h" #include "components/enterprise/browser/reporting/report_scheduler.h" #include "components/policy/core/common/cloud/dm_token.h" #include "components/prefs/pref_service.h" @@ -54,6 +55,11 @@ if (profile) { #if BUILDFLAG(IS_CHROMEOS) NOTREACHED(); +#else + if (enterprise_signals::features::IsProfileSignalsReportingEnabled()) { + user_security_signals_service_ = + std::make_unique<UserSecuritySignalsService>(prefs_, this); + } #endif } } @@ -72,6 +78,12 @@ return prefs_; } +void ReportSchedulerDesktop::OnInitializationCompleted() { + if (user_security_signals_service_) { + user_security_signals_service_->Start(); + } +} + void ReportSchedulerDesktop::StartWatchingUpdatesIfNeeded( base::Time last_upload, base::TimeDelta upload_interval) { @@ -121,6 +133,28 @@ return reporting::GetUserClientId(profile_).value_or(std::string()); } +bool ReportSchedulerDesktop::AreSecurityReportsEnabled() { + return user_security_signals_service_ && + user_security_signals_service_->IsSecuritySignalsReportingEnabled(); +} + +bool ReportSchedulerDesktop::UseCookiesInUploads() { + return user_security_signals_service_ && + user_security_signals_service_->ShouldUseCookies(); +} + +void ReportSchedulerDesktop::OnSecuritySignalsUploaded() { + if (user_security_signals_service_) { + user_security_signals_service_->OnReportUploaded(); + } +} + +void ReportSchedulerDesktop::OnReportEventTriggered( + SecurityReportTrigger trigger) { + // TODO(crbug.com/402486791): Forward the trigger via + // `trigger_report_callback_`. +} + void ReportSchedulerDesktop::OnUpdate(const BuildState* build_state) { DCHECK(ShouldReportUpdates()); // A new version has been detected on the machine and a restart is now needed
diff --git a/chrome/browser/enterprise/reporting/report_scheduler_desktop.h b/chrome/browser/enterprise/reporting/report_scheduler_desktop.h index 3f6fc63b..88b0b16 100644 --- a/chrome/browser/enterprise/reporting/report_scheduler_desktop.h +++ b/chrome/browser/enterprise/reporting/report_scheduler_desktop.h
@@ -5,11 +5,13 @@ #ifndef CHROME_BROWSER_ENTERPRISE_REPORTING_REPORT_SCHEDULER_DESKTOP_H_ #define CHROME_BROWSER_ENTERPRISE_REPORTING_REPORT_SCHEDULER_DESKTOP_H_ -#include "components/enterprise/browser/reporting/report_scheduler.h" +#include <memory> #include "base/memory/raw_ptr.h" #include "chrome/browser/enterprise/reporting/extension_request/extension_request_observer_factory.h" #include "chrome/browser/upgrade_detector/build_state_observer.h" +#include "components/enterprise/browser/reporting/report_scheduler.h" +#include "components/enterprise/browser/reporting/user_security_signals_service.h" class Profile; @@ -17,6 +19,7 @@ // Desktop implementation of the ReportScheduler delegate. class ReportSchedulerDesktop : public ReportScheduler::Delegate, + public UserSecuritySignalsService::Delegate, public BuildStateObserver { public: ReportSchedulerDesktop(); @@ -29,6 +32,7 @@ // ReportScheduler::Delegate implementation. PrefService* GetPrefService() override; + void OnInitializationCompleted() override; void StartWatchingUpdatesIfNeeded(base::Time last_upload, base::TimeDelta upload_interval) override; void StopWatchingUpdates() override; @@ -37,12 +41,22 @@ policy::DMToken GetProfileDMToken() override; std::string GetProfileClientId() override; + bool AreSecurityReportsEnabled() override; + bool UseCookiesInUploads() override; + void OnSecuritySignalsUploaded() override; + + // UserSecuritySignalsService::Delegate implementation. + void OnReportEventTriggered(SecurityReportTrigger trigger) override; + // BuildStateObserver implementation. void OnUpdate(const BuildState* build_state) override; private: raw_ptr<Profile> profile_; raw_ptr<PrefService> prefs_; + + // Only set for Profile-level schedulers. + std::unique_ptr<UserSecuritySignalsService> user_security_signals_service_; }; } // namespace enterprise_reporting
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc index c5832d5..e5f855e 100644 --- a/chrome/browser/extensions/component_loader.cc +++ b/chrome/browser/extensions/component_loader.cc
@@ -182,8 +182,8 @@ ComponentLoader::ComponentExtensionInfo::~ComponentExtensionInfo() = default; // static -ComponentLoader* ComponentLoader::Get(Profile* profile) { - return ComponentLoaderFactory::GetForBrowserContext(profile); +ComponentLoader* ComponentLoader::Get(content::BrowserContext* context) { + return ComponentLoaderFactory::GetForBrowserContext(context); } ComponentLoader::ComponentLoader(Profile* profile)
diff --git a/chrome/browser/extensions/component_loader.h b/chrome/browser/extensions/component_loader.h index f614e6a8..e9d7926 100644 --- a/chrome/browser/extensions/component_loader.h +++ b/chrome/browser/extensions/component_loader.h
@@ -31,6 +31,10 @@ class Profile; +namespace content { +class BrowserContext; +} + namespace extensions { class Extension; @@ -39,7 +43,7 @@ // For registering, loading, and unloading component extensions. class ComponentLoader : public KeyedService { public: - static ComponentLoader* Get(Profile* profile); + static ComponentLoader* Get(content::BrowserContext* context); ComponentLoader(const ComponentLoader&) = delete; ComponentLoader& operator=(const ComponentLoader&) = delete;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 5e6831b..83126b9 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -751,11 +751,6 @@ "expiry_milestone": 145 }, { - "name": "autofill-enable-vcn-gray-out-for-merchant-opt-out", - "owners": ["hvs@google.com", "payments-autofill-team@google.com"], - "expiry_milestone": 135 - }, - { "name": "autofill-highlight-only-changed-value-in-preview-mode", "owners": [ "koerber@chromium.org", "mamir@chromium.org" ], "expiry_milestone": 120 @@ -4438,6 +4433,11 @@ "expiry_milestone": 138 }, { + "name": "enterprise-realtime-event-reporting-on-ios", + "owners": ["mxlg@google.com", "cbemobile-bling@google.com"], + "expiry_milestone": 139 + }, + { "name": "enterprise-reporting-ui", "owners": ["cros-reporting-team@google.com"], "expiry_milestone": 150
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index b28da794..e8c32ae 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -761,12 +761,6 @@ "card retrieval if a challenge is required, 3DS authentication is " "available for the card, and FIDO is not."; -const char kAutofillEnableVcnGrayOutForMerchantOptOutName[] = - "Enable virtual card suggestion graying out for opted-out merchants"; -const char kAutofillEnableVcnGrayOutForMerchantOptOutDescription[] = - "When enabled, Chrome will display grayed out virtual card suggestions on " - "merchant websites where the merchant has opted-out of virtual cards."; - const char kAutofillImprovedLabelsName[] = "Autofill suggestions with improved labels"; const char kAutofillImprovedLabelsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index c395843..b3fd17f 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -454,9 +454,6 @@ extern const char kAutofillEnableVcn3dsAuthenticationName[]; extern const char kAutofillEnableVcn3dsAuthenticationDescription[]; -extern const char kAutofillEnableVcnGrayOutForMerchantOptOutName[]; -extern const char kAutofillEnableVcnGrayOutForMerchantOptOutDescription[]; - extern const char kAutofillImprovedLabelsName[]; extern const char kAutofillImprovedLabelsDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 21a1376e..7e3aff6 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -843,7 +843,7 @@ BASE_FEATURE(kEdgeToEdgeBottomChin, "EdgeToEdgeBottomChin", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kEdgeToEdgeEverywhere, "EdgeToEdgeEverywhere", @@ -851,7 +851,7 @@ BASE_FEATURE(kEdgeToEdgeSafeAreaConstraint, "EdgeToEdgeSafeAreaConstraint", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kEdgeToEdgeWebOptIn, "EdgeToEdgeWebOptIn",
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 3e95fe66..341ca70 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
@@ -714,10 +714,7 @@ public static final CachedFlag sDrawKeyNativeEdgeToEdge = newCachedFlag(DRAW_KEY_NATIVE_EDGE_TO_EDGE, true); public static final CachedFlag sEdgeToEdgeBottomChin = - newCachedFlag( - EDGE_TO_EDGE_BOTTOM_CHIN, - /* defaultValue= */ false, - /* defaultValueInTests= */ true); + newCachedFlag(EDGE_TO_EDGE_BOTTOM_CHIN, /* defaultValue= */ true); public static final CachedFlag sEdgeToEdgeEverywhere = newCachedFlag( EDGE_TO_EDGE_EVERYWHERE, @@ -994,7 +991,7 @@ public static final MutableFlagWithSafeDefault sDynamicSafeAreaInsets = newMutableFlagWithSafeDefault(DYNAMIC_SAFE_AREA_INSETS, false); public static final MutableFlagWithSafeDefault sEdgeToEdgeSafeAreaConstraint = - newMutableFlagWithSafeDefault(EDGE_TO_EDGE_SAFE_AREA_CONSTRAINT, false); + newMutableFlagWithSafeDefault(EDGE_TO_EDGE_SAFE_AREA_CONSTRAINT, true); // Defaulted to true in native, but since it is being used as a kill switch set the default // value pre-native to false as it is safer if the feature needs to be killed via Finch config. public static final MutableFlagWithSafeDefault sEmptyTabListAnimationKillSwitch = @@ -1269,7 +1266,7 @@ */ public static final StringCachedFeatureParam sEdgeToEdgeBottomChinOemMinVersions = newStringCachedFeatureParam( - EDGE_TO_EDGE_BOTTOM_CHIN, "e2e_field_trial_oem_min_versions", ""); + EDGE_TO_EDGE_BOTTOM_CHIN, "e2e_field_trial_oem_min_versions", "34,34"); public static final StringCachedFeatureParam sEdgeToEdgeEverywhereOemMinVersions = newStringCachedFeatureParam( @@ -1281,7 +1278,8 @@ * #sEdgeToEdgeBottomChinOemMinVersions}. */ public static final StringCachedFeatureParam sEdgeToEdgeBottomChinOemList = - newStringCachedFeatureParam(EDGE_TO_EDGE_BOTTOM_CHIN, "e2e_field_trial_oem_list", ""); + newStringCachedFeatureParam( + EDGE_TO_EDGE_BOTTOM_CHIN, "e2e_field_trial_oem_list", "oppo,xiaomi"); public static final StringCachedFeatureParam sEdgeToEdgeEverywhereOemList = newStringCachedFeatureParam(EDGE_TO_EDGE_EVERYWHERE, "e2e_field_trial_oem_list", ""); @@ -1458,7 +1456,7 @@ public static final MutableBooleanParamWithSafeDefault sDisableBottomControlsStackerYOffsetDispatching = sBottomBrowserControlsRefactor.newBooleanParam( - "disable_bottom_controls_stacker_y_offset", true); + "disable_bottom_controls_stacker_y_offset", false); public static final MutableIntParamWithSafeDefault sTabSwitcherColorBlendAnimateDurationMs = sTabSwitcherColorBlendAnimate.newIntParam("animation_duration_ms", 240); public static final MutableIntParamWithSafeDefault sTabSwitcherColorBlendAnimateInterpolator =
diff --git a/chrome/browser/glic/fre/glic_fre_controller.cc b/chrome/browser/glic/fre/glic_fre_controller.cc index 9208a42..0c9cf8f 100644 --- a/chrome/browser/glic/fre/glic_fre_controller.cc +++ b/chrome/browser/glic/fre/glic_fre_controller.cc
@@ -79,7 +79,6 @@ if (!browser) { return false; } - source_browser_ = browser; // If there is a browser, the FRE can only be shown if no other modal is // currently being shown on the same tab. tabs::TabInterface* tab = browser->GetActiveTabInterface(); @@ -87,6 +86,8 @@ } void GlicFreController::ShowFreDialog(Browser* browser) { + CHECK(CanShowFreDialog(browser)); + source_browser_ = browser; show_start_time_ = base::TimeTicks::Now(); profile_->GetPrefs()->SetInteger( prefs::kGlicCompletedFre, @@ -170,12 +171,15 @@ chrome::GetChannel())); } + // Dismiss the FRE window and then show the Glic panel, but store source + // browser before it is cleared. + Browser* source_browser = source_browser_; DismissFre(); // Show a glic window attached to the invocation source browser. - if (source_browser_) { + if (source_browser) { GlicKeyedServiceFactory::GetGlicKeyedService(profile_)->ToggleUI( - source_browser_, /*prevent_close=*/true, mojom::InvocationSource::kFre); + source_browser, /*prevent_close=*/true, mojom::InvocationSource::kFre); } }
diff --git a/chrome/browser/glic/fre/glic_fre_controller_browsertest.cc b/chrome/browser/glic/fre/glic_fre_controller_browsertest.cc index f7689391..cfa225387 100644 --- a/chrome/browser/glic/fre/glic_fre_controller_browsertest.cc +++ b/chrome/browser/glic/fre/glic_fre_controller_browsertest.cc
@@ -23,6 +23,7 @@ class GlicFreControllerBrowserTest : public glic::test::InteractiveGlicTest { public: + GlicFreControllerBrowserTest() = default; ~GlicFreControllerBrowserTest() override = default; void SetUpOnMainThread() override { @@ -44,15 +45,29 @@ } void WaitForFreShow() { - ASSERT_TRUE(base::test::RunUntil( - [&]() { return glic_fre_controller()->IsShowingDialog(); })); + ASSERT_TRUE(base::test::RunUntil([&]() { + return glic_fre_controller()->IsShowingDialog(); + })) << "FRE dialog should have been shown"; + } + + void WaitForFreClose() { + ASSERT_TRUE(base::test::RunUntil([&]() { + return !glic_fre_controller()->IsShowingDialog(); + })) << "FRE dialog should have been closed"; + } + + void WaitForGlicPanelShow() { + ASSERT_TRUE(base::test::RunUntil([&]() { + return glic_test_environment().GetService()->IsWindowShowing(); + })) << "Glic panel should have been shown"; } void EnsureFreDoesNotShow() { auto end_time = base::TimeTicks::Now() + base::Milliseconds(500); ASSERT_TRUE(base::test::RunUntil( [&]() { return end_time < base::TimeTicks::Now(); })); - ASSERT_FALSE(glic_fre_controller()->IsShowingDialog()); + ASSERT_FALSE(glic_fre_controller()->IsShowingDialog()) + << "FRE dialog should not have been shown"; } }; @@ -228,5 +243,18 @@ 0, TabCloseTypes::CLOSE_USER_GESTURE); } +IN_PROC_BROWSER_TEST_F(GlicFreControllerBrowserTest, FreAcceptance) { + // Open the FRE dialog in a tab. + chrome::AddTabAt(browser(), GURL("about:blank"), 0, true); + browser()->tab_strip_model()->ActivateTabAt(0); + glic_fre_controller()->ShowFreDialog(browser()); + WaitForFreShow(); + + // Accept the FRE and confirm it closed and the glic panel opened. + glic_fre_controller()->AcceptFre(); + WaitForFreClose(); + WaitForGlicPanelShow(); +} + } // namespace } // namespace glic
diff --git a/chrome/browser/glic/fre/glic_fre_dialog_view.cc b/chrome/browser/glic/fre/glic_fre_dialog_view.cc index 10bfe95..d5f1220e 100644 --- a/chrome/browser/glic/fre/glic_fre_dialog_view.cc +++ b/chrome/browser/glic/fre/glic_fre_dialog_view.cc
@@ -28,7 +28,6 @@ SetShowCloseButton(false); SetButtons(static_cast<int>(ui::mojom::DialogButton::kNone)); SetModalType(ui::mojom::ModalType::kChild); - SetOwnedByWidget(false); SetOwnershipOfNewWidget( views::Widget::InitParams::Ownership::CLIENT_OWNS_WIDGET); // TODO(cuianthony): Share this constant in GlicWindowController to use with
diff --git a/chrome/browser/glic/host/glic_api_uitest.cc b/chrome/browser/glic/host/glic_api_uitest.cc index 9102cd4e10..2e79e17 100644 --- a/chrome/browser/glic/host/glic_api_uitest.cc +++ b/chrome/browser/glic/host/glic_api_uitest.cc
@@ -46,7 +46,8 @@ // This file runs the respective JS tests from // chrome/test/data/webui/glic/api_test.ts. -#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) +#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \ + defined(MEMORY_SANITIZER) #define SLOW_BINARY #endif @@ -190,24 +191,26 @@ } void WaitForGuest() { - ASSERT_TRUE(base::test::RunUntil([&]() { - return FindGlicGuestMainFrame() != nullptr; - })) << "Timed out waiting for the frame"; - auto end_time = base::TimeTicks::Now() + base::Seconds(5); + auto end_time = base::TimeTicks::Now() + base::Seconds(10); + content::RenderFrameHost* frame = nullptr; while (base::TimeTicks::Now() < end_time) { - content::RenderFrameHost* frame = FindGlicGuestMainFrame(); - ASSERT_TRUE(frame) << "Guest frame deleted"; - auto result = - content::EvalJs(frame, {"typeof runApiTest !== 'undefined'"}); - if (result.error.empty() && result.ExtractBool()) { - return; + // Note: Sometimes the previous guest frame is still around, but it won't + // have the runApiTest function. Loop until both conditions are met. + frame = FindGlicGuestMainFrame(); + if (frame) { + auto result = + content::EvalJs(frame, {"typeof runApiTest !== 'undefined'"}); + if (result.error.empty() && result.ExtractBool()) { + return; + } } base::RunLoop run_loop; base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask( FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(200)); run_loop.Run(); } - FAIL() << "Timed out waiting for guest frame"; + FAIL() << "Timed out waiting for guest frame. Has guest frame: " + << (frame != nullptr); } content::RenderFrameHost* FindGlicGuestMainFrame() { @@ -348,8 +351,7 @@ WaitForWebUiState(mojom::WebUiState::kReady); } -// TODO(harringtond): This is a flaky. -IN_PROC_BROWSER_TEST_F(GlicApiTest, DISABLED_testInitializeFailsWindowClosed) { +IN_PROC_BROWSER_TEST_F(GlicApiTest, testInitializeFailsWindowClosed) { // Immediately close the window to check behavior while window is closed. // Fail client initialization, should see error page. RunTestSequence( @@ -400,8 +402,7 @@ }); } -// TODO(harringtond): This is a flaky. -IN_PROC_BROWSER_TEST_F(GlicApiTest, DISABLED_testInitializeFailsAfterReload) { +IN_PROC_BROWSER_TEST_F(GlicApiTest, testInitializeFailsAfterReload) { RunTestSequence( OpenGlicWindow(GlicWindowMode::kDetached, GlicInstrumentMode::kNone)); WebUIStateListener listener(&window_controller()); @@ -417,9 +418,7 @@ listener.WaitForWebUiState(mojom::WebUiState::kError); } -// TODO(harringtond): This is a flaky. -IN_PROC_BROWSER_TEST_F(GlicApiTestWithFastTimeout, - DISABLED_testInitializeTimesOut) { +IN_PROC_BROWSER_TEST_F(GlicApiTestWithFastTimeout, testInitializeTimesOut) { #if defined(SLOW_BINARY) GTEST_SKIP() << "skip timeout test for slow binary"; #else
diff --git a/chrome/browser/glic/widget/glic_widget.cc b/chrome/browser/glic/widget/glic_widget.cc index 00ad6577..332c5d7 100644 --- a/chrome/browser/glic/widget/glic_widget.cc +++ b/chrome/browser/glic/widget/glic_widget.cc
@@ -26,6 +26,8 @@ return base::FeatureList::IsEnabled(features::kGlicUserResize); } +} // namespace + class GlicWidgetDelegate : public views::WidgetDelegate { public: GlicWidgetDelegate() { @@ -44,7 +46,6 @@ private: void Destroy() { delete this; } }; -} // namespace void* kGlicWidgetIdentifier = &kGlicWidgetIdentifier;
diff --git a/chrome/browser/glic/widget/glic_window_controller.cc b/chrome/browser/glic/widget/glic_window_controller.cc index 8401e37..627f6d8 100644 --- a/chrome/browser/glic/widget/glic_window_controller.cc +++ b/chrome/browser/glic/widget/glic_window_controller.cc
@@ -427,7 +427,9 @@ } // If floaty is focused or the source is the top button, close it // If floaty is unfocused and open, focus it - if (IsActive() || source == mojom::InvocationSource::kTopChromeButton) { + if (IsActive() || + (source == mojom::InvocationSource::kTopChromeButton && + !base::FeatureList::IsEnabled(features::kGlicZOrderChanges))) { maybe_close(); } else if (state_ == State::kOpen) { // TODO(crbug.com/404601783): Bring focus to the textbox.
diff --git a/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigManager.java b/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigManager.java index acbaf7e..59ee381 100644 --- a/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigManager.java +++ b/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigManager.java
@@ -5,8 +5,6 @@ package org.chromium.chrome.browser.magic_stack; import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.DEFAULT_BROWSER_PROMO; -import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.SINGLE_TAB; -import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.TAB_RESUMPTION; import android.content.Context; @@ -144,20 +142,13 @@ @ModuleType public List<Integer> getModuleListShownInSettings() { @ModuleType List<Integer> moduleListShownInSettings = new ArrayList<>(); - boolean isTabModuleAdded = false; boolean isEducationalTipModuleAdded = false; for (Entry<Integer, ModuleConfigChecker> entry : mModuleConfigCheckerMap.entrySet()) { ModuleConfigChecker configChecker = entry.getValue(); if (configChecker.isEligible()) { int moduleType = entry.getKey(); - if (moduleType == SINGLE_TAB || moduleType == TAB_RESUMPTION) { - // The SINGLE_TAB and TAB_RESUMPTION modules are controlled by the same - // preference. - if (isTabModuleAdded) continue; - - isTabModuleAdded = true; - } else if (HomeModulesUtils.belongsToEducationalTipModule(moduleType)) { + if (HomeModulesUtils.belongsToEducationalTipModule(moduleType)) { // All the educational tip modules are controlled by the same preference. if (isEducationalTipModuleAdded) continue; @@ -184,12 +175,6 @@ String getSettingsPreferenceKey(@ModuleType int moduleType) { assert 0 <= moduleType && moduleType < ModuleType.NUM_ENTRIES; - // SINGLE_TAB and TAB_RESUMPTION modules are controlled by the same preference key. - if (moduleType == ModuleType.SINGLE_TAB) { - return ChromePreferenceKeys.HOME_MODULES_MODULE_TYPE.createKey( - String.valueOf(ModuleType.TAB_RESUMPTION)); - } - // All the educational tip modules are controlled by the same preference key. if (HomeModulesUtils.belongsToEducationalTipModule(moduleType)) { return ChromePreferenceKeys.HOME_MODULES_MODULE_TYPE.createKey(
diff --git a/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesCoordinator.java b/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesCoordinator.java index 32e73dee..52aeca4 100644 --- a/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesCoordinator.java +++ b/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesCoordinator.java
@@ -284,15 +284,6 @@ if (!isEnabled) { removeModule(moduleType); - // The single tab module and the tab resumption modules are controlled by the same - // preference key. Once it is turned on or off, both modules will be enabled or - // disabled. - if (moduleType == ModuleType.SINGLE_TAB) { - removeModule(ModuleType.TAB_RESUMPTION); - } else if (moduleType == ModuleType.TAB_RESUMPTION) { - removeModule(ModuleType.SINGLE_TAB); - } - // All the educational tip modules are controlled by the same preference key. Once it is // turned on or off, all educational tip modules will be enabled or disabled. if (HomeModulesUtils.belongsToEducationalTipModule(moduleType)) {
diff --git a/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesMediator.java b/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesMediator.java index 17b960eff..387df3bb 100644 --- a/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesMediator.java +++ b/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesMediator.java
@@ -11,7 +11,6 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.segmentation_platform.client_util.HomeModulesRankingHelper; @@ -558,18 +557,12 @@ * enabled. */ void onModuleConfigChanged(@ModuleType int moduleType, boolean isEnabled) { - // The single tab module and the tab resumption modules are controlled by the same - // preference key. Once it is turned on or off, both modules will be enabled or disabled. - // The educational tip modules are also controlled by the same preference key. Once it is + // The educational tip modules are controlled by the same preference key. Once it is // turned on or off, all of the educational tip modules will be enabled or disabled. if (isEnabled) { // If the mEnabledModuleSet hasn't been initialized yet, skip here. if (mEnabledModuleSet != null) { - if (moduleType == ModuleType.SINGLE_TAB - || moduleType == ModuleType.TAB_RESUMPTION) { - mEnabledModuleSet.add(ModuleType.SINGLE_TAB); - mEnabledModuleSet.add(ModuleType.TAB_RESUMPTION); - } else if (HomeModulesUtils.belongsToEducationalTipModule(moduleType)) { + if (HomeModulesUtils.belongsToEducationalTipModule(moduleType)) { mEnabledModuleSet.addAll(HomeModulesUtils.getEducationalTipModuleList()); } else { mEnabledModuleSet.add(moduleType); @@ -578,11 +571,7 @@ } else { // If the mEnabledModuleSet hasn't been initialized yet, skip here. if (mEnabledModuleSet != null) { - if (moduleType == ModuleType.SINGLE_TAB - || moduleType == ModuleType.TAB_RESUMPTION) { - mEnabledModuleSet.remove(ModuleType.SINGLE_TAB); - mEnabledModuleSet.remove(ModuleType.TAB_RESUMPTION); - } else if (HomeModulesUtils.belongsToEducationalTipModule(moduleType)) { + if (HomeModulesUtils.belongsToEducationalTipModule(moduleType)) { mEnabledModuleSet.removeAll(HomeModulesUtils.getEducationalTipModuleList()); } else { mEnabledModuleSet.remove(moduleType); @@ -600,14 +589,12 @@ Set<Integer> getFilteredEnabledModuleSet() { ensureEnabledModuleSetCreated(); Set<Integer> set = new HashSet<>(mEnabledModuleSet); - assert !set.contains(ModuleType.DEPRECATED_EDUCATIONAL_TIP); + assert !set.contains(ModuleType.DEPRECATED_EDUCATIONAL_TIP) + && !set.contains(ModuleType.DEPRECATED_TAB_RESUMPTION); boolean isHomeSurface = mModuleDelegateHost.isHomeSurface(); - boolean addAll = ChromeFeatureList.sMagicStackAndroidShowAllModules.getValue(); - if (isHomeSurface && !addAll) { - set.remove(ModuleType.TAB_RESUMPTION); - } else if (!isHomeSurface) { + if (!isHomeSurface) { set.remove(ModuleType.SINGLE_TAB); }
diff --git a/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesMetricsUtils.java b/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesMetricsUtils.java index 92b5d429..7a79f6430 100644 --- a/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesMetricsUtils.java +++ b/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/HomeModulesMetricsUtils.java
@@ -7,13 +7,13 @@ import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.AUXILIARY_SEARCH; import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.DEFAULT_BROWSER_PROMO; import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.DEPRECATED_EDUCATIONAL_TIP; +import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.DEPRECATED_TAB_RESUMPTION; import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.PRICE_CHANGE; import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.QUICK_DELETE_PROMO; import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.SAFETY_HUB; import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.SINGLE_TAB; import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.TAB_GROUP_PROMO; import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.TAB_GROUP_SYNC_PROMO; -import static org.chromium.chrome.browser.magic_stack.ModuleDelegate.ModuleType.TAB_RESUMPTION; import androidx.annotation.VisibleForTesting; @@ -109,8 +109,6 @@ return "SingleTab"; case PRICE_CHANGE: return "PriceChange"; - case TAB_RESUMPTION: - return "TabResumption"; case SAFETY_HUB: return "SafetyHub"; case AUXILIARY_SEARCH: @@ -135,8 +133,6 @@ return SINGLE_TAB; case "PriceChange": return PRICE_CHANGE; - case "TabResumption": - return TAB_RESUMPTION; case "SafetyHub": return SAFETY_HUB; case "AuxiliarySearch": @@ -159,7 +155,8 @@ static HashSet<Integer> getAllActiveModulesForTesting() { HashSet<Integer> set = new HashSet<>(); for (@ModuleType int moduleType = 0; moduleType < ModuleType.NUM_ENTRIES; moduleType++) { - if (moduleType == DEPRECATED_EDUCATIONAL_TIP) { + if (moduleType == DEPRECATED_EDUCATIONAL_TIP + || moduleType == DEPRECATED_TAB_RESUMPTION) { continue; } set.add(moduleType);
diff --git a/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/ModuleDelegate.java b/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/ModuleDelegate.java index 9d42a197e..511c0885 100644 --- a/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/ModuleDelegate.java +++ b/chrome/browser/magic_stack/android/java/src/org/chromium/chrome/browser/magic_stack/ModuleDelegate.java
@@ -26,7 +26,7 @@ @IntDef({ ModuleType.SINGLE_TAB, ModuleType.PRICE_CHANGE, - ModuleType.TAB_RESUMPTION, + ModuleType.DEPRECATED_TAB_RESUMPTION, ModuleType.SAFETY_HUB, ModuleType.DEPRECATED_EDUCATIONAL_TIP, ModuleType.AUXILIARY_SEARCH, @@ -40,8 +40,7 @@ @interface ModuleType { int SINGLE_TAB = 0; int PRICE_CHANGE = 1; - // TODO(crbug.com/400479745): Rename to DEPRECATED_TAB_RESUMPTION and remote dead code. - int TAB_RESUMPTION = 2; + int DEPRECATED_TAB_RESUMPTION = 2; int SAFETY_HUB = 3; int DEPRECATED_EDUCATIONAL_TIP = 4; int AUXILIARY_SEARCH = 5;
diff --git a/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigManagerUnitTest.java b/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigManagerUnitTest.java index d9491ff..b1cbdee0 100644 --- a/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigManagerUnitTest.java +++ b/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigManagerUnitTest.java
@@ -161,44 +161,6 @@ } @Test - public void testGetTabResumptionListItemSingleTabShownFirst() { - // Verifies that the return list of getModuleListShownInSettings() contains and only - // SINGLE_TAB. - registerModuleConfigCheckerWithEligibility(ModuleType.SINGLE_TAB, true); - List<Integer> moduleList = mHomeModulesConfigManager.getModuleListShownInSettings(); - assertEquals(1, moduleList.size()); - assertEquals(ModuleType.SINGLE_TAB, (int) moduleList.get(0)); - - // Verifies that the return list of getModuleListShownInSettings contains only one of - // SINGLE_TAB and TAB_RESUMPTION. - registerModuleConfigCheckerWithEligibility(ModuleType.TAB_RESUMPTION, true); - moduleList = mHomeModulesConfigManager.getModuleListShownInSettings(); - assertEquals(1, moduleList.size()); - assertTrue( - moduleList.contains(ModuleType.SINGLE_TAB) - || moduleList.contains(ModuleType.TAB_RESUMPTION)); - } - - @Test - public void testGetTabResumptionListItemTabResumptionShownFirst() { - // Verifies that the return list of getModuleListShownInSettings() contains and only - // TAB_RESUMPTION. - registerModuleConfigCheckerWithEligibility(ModuleType.TAB_RESUMPTION, true); - List<Integer> moduleList = mHomeModulesConfigManager.getModuleListShownInSettings(); - assertEquals(1, moduleList.size()); - assertEquals(ModuleType.TAB_RESUMPTION, (int) moduleList.get(0)); - - // Verifies that the return list of getModuleListShownInSettings contains only one of - // SINGLE_TAB and TAB_RESUMPTION. - registerModuleConfigCheckerWithEligibility(ModuleType.SINGLE_TAB, true); - moduleList = mHomeModulesConfigManager.getModuleListShownInSettings(); - assertEquals(1, moduleList.size()); - assertTrue( - moduleList.contains(ModuleType.SINGLE_TAB) - || moduleList.contains(ModuleType.TAB_RESUMPTION)); - } - - @Test public void testGetEducationalTipListItemShown() { for (@ModuleType int tipModule : getEducationalTipModuleList()) { registerModuleConfigCheckerWithEligibility(tipModule, true); @@ -215,7 +177,7 @@ public void testGetMultipleListItemShown() { List<Integer> moduleTypeList = Arrays.asList( - ModuleType.TAB_RESUMPTION, + ModuleType.SINGLE_TAB, ModuleType.SAFETY_HUB, ModuleType.QUICK_DELETE_PROMO, ModuleType.PRICE_CHANGE); @@ -234,10 +196,7 @@ @Test public void testGetMultipleListItemShownSomeComplex() { List<Integer> eligibleTypeList = - Arrays.asList( - ModuleType.TAB_RESUMPTION, - ModuleType.SAFETY_HUB, - ModuleType.AUXILIARY_SEARCH); + Arrays.asList(ModuleType.SAFETY_HUB, ModuleType.AUXILIARY_SEARCH); List<Integer> notEligibleTypeList = Arrays.asList(ModuleType.SINGLE_TAB, ModuleType.PRICE_CHANGE); @@ -260,9 +219,9 @@ @Test public void testGetSettingsPreferenceKey() { - String tabResumptionPreferenceKey = + String singleTabPreferenceKey = ChromePreferenceKeys.HOME_MODULES_MODULE_TYPE.createKey( - String.valueOf(ModuleType.TAB_RESUMPTION)); + String.valueOf(ModuleType.SINGLE_TAB)); String defaultBrowserPromoPreferenceKey = ChromePreferenceKeys.HOME_MODULES_MODULE_TYPE.createKey( String.valueOf(ModuleType.DEFAULT_BROWSER_PROMO)); @@ -270,17 +229,12 @@ ChromePreferenceKeys.HOME_MODULES_MODULE_TYPE.createKey( String.valueOf(ModuleType.PRICE_CHANGE)); - assertFalse(TextUtils.equals(tabResumptionPreferenceKey, priceChangePreferenceKey)); + assertFalse(TextUtils.equals(singleTabPreferenceKey, priceChangePreferenceKey)); assertFalse(TextUtils.equals(defaultBrowserPromoPreferenceKey, priceChangePreferenceKey)); - // Verifies that the SINGLE_TAB and TAB_RESUMPTION modules are shared with the same - // preference key. assertEquals( - tabResumptionPreferenceKey, + singleTabPreferenceKey, mHomeModulesConfigManager.getSettingsPreferenceKey(ModuleType.SINGLE_TAB)); - assertEquals( - tabResumptionPreferenceKey, - mHomeModulesConfigManager.getSettingsPreferenceKey(ModuleType.TAB_RESUMPTION)); // Verifies that all the educational tip modules are shared with the same preference key. assertEquals(
diff --git a/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigSettingsUnitTest.java b/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigSettingsUnitTest.java index e829c199..f03f12a 100644 --- a/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigSettingsUnitTest.java +++ b/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesConfigSettingsUnitTest.java
@@ -63,9 +63,6 @@ public void testLaunchHomeModulesConfigSettings() { registerModuleConfigChecker(3); - String singleTabNotExistedPreferenceKey = - ChromePreferenceKeys.HOME_MODULES_MODULE_TYPE.createKey( - String.valueOf(ModuleType.SINGLE_TAB)); String priceChangePreferenceKey = ChromePreferenceKeys.HOME_MODULES_MODULE_TYPE.createKey( String.valueOf(ModuleType.PRICE_CHANGE)); @@ -82,10 +79,6 @@ fragmentManager.beginTransaction().replace(android.R.id.content, fragment).commit(); mActivityScenario.moveToState(State.STARTED); - ChromeSwitchPreference switchNotExisted = - fragment.findPreference(singleTabNotExistedPreferenceKey); - Assert.assertNull(switchNotExisted); - ChromeSwitchPreference switchExisted = fragment.findPreference(priceChangePreferenceKey); Assert.assertEquals( mActivity.getString(R.string.price_change_module_name), switchExisted.getTitle()); @@ -157,7 +150,8 @@ private void registerModuleConfigChecker(int size) { size = Math.min(size, ModuleType.NUM_ENTRIES); for (int i = 0; i < size; i++) { - if (i == ModuleType.DEPRECATED_EDUCATIONAL_TIP) { + if (i == ModuleType.DEPRECATED_EDUCATIONAL_TIP + || i == ModuleType.DEPRECATED_TAB_RESUMPTION) { continue; }
diff --git a/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesContextMenuManagerUnitTest.java b/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesContextMenuManagerUnitTest.java index 42aece0..f3f0b40 100644 --- a/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesContextMenuManagerUnitTest.java +++ b/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesContextMenuManagerUnitTest.java
@@ -52,7 +52,7 @@ private static final String EXPECTED_OPTION_1 = "Hide Chrome tips card"; private static final String EXPECTED_OPTION_2 = "Customize"; - private static final int MODULE_TYPE = ModuleType.TAB_RESUMPTION; + private static final int MODULE_TYPE = ModuleType.PRICE_CHANGE; @Mock private ModuleProvider mModuleProvider; @Mock private View mView; @Mock private ModuleDelegate mModuleDelegate;
diff --git a/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesCoordinatorUnitTest.java b/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesCoordinatorUnitTest.java index 99c3de8..cf66660 100644 --- a/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesCoordinatorUnitTest.java +++ b/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesCoordinatorUnitTest.java
@@ -479,7 +479,7 @@ verify(mHomeModulesRankingHelperJniMock) .getClassificationResult( any(), any(), any(), mClassificationResultCaptor.capture()); - String[] orderedLabels = {"SingleTab", "TabResumption"}; + String[] orderedLabels = {"SingleTab", "PriceChange"}; ClassificationResult result = new ClassificationResult( PredictionStatus.SUCCEEDED, orderedLabels, /* requestId= */ 0);
diff --git a/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesMediatorUnitTest.java b/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesMediatorUnitTest.java index 3d3fd386..8878ac1 100644 --- a/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesMediatorUnitTest.java +++ b/chrome/browser/magic_stack/android/junit/src/org/chromium/chrome/browser/magic_stack/HomeModulesMediatorUnitTest.java
@@ -90,13 +90,11 @@ mModuleProviders = new ModuleProvider[MODULE_TYPES]; OneshotSupplierImpl<Profile> profileSupplier = new OneshotSupplierImpl<>(); profileSupplier.set(mProfile); - for (int i = 0; i < MODULE_TYPES; i++) { - mModuleTypeList[i] = i; - mModuleProviderBuilderList[i] = Mockito.mock(ModuleProviderBuilder.class); - doReturn(true).when(mModuleProviderBuilderList[i]).build(eq(mModuleDelegate), any()); - mListItems[i] = new ListItem(mModuleTypeList[i], Mockito.mock(PropertyModel.class)); - mModuleProviders[i] = Mockito.mock(ModuleProvider.class); - } + + registerModule(0, ModuleType.SINGLE_TAB); + registerModule(1, ModuleType.PRICE_CHANGE); + registerModule(2, ModuleType.SAFETY_HUB); + mHomeModulesConfigManager = HomeModulesConfigManager.getInstance(); assertEquals(0, mHomeModulesConfigManager.getEnabledModuleSet().size()); mMediator = @@ -127,8 +125,8 @@ Map<Integer, Integer> moduleTypeToRankingIndexMap = mMediator.getModuleTypeToRankingIndexMapForTesting(); assertEquals(2, moduleTypeToRankingIndexMap.size()); - assertEquals(0, (int) moduleTypeToRankingIndexMap.get(2)); - assertEquals(1, (int) moduleTypeToRankingIndexMap.get(0)); + assertEquals(0, (int) moduleTypeToRankingIndexMap.get(mModuleTypeList[2])); + assertEquals(1, (int) moduleTypeToRankingIndexMap.get(mModuleTypeList[0])); } @Test @@ -240,7 +238,7 @@ // Calls onModuleBuilt() to add ModuleProviders to the map. for (int i = 0; i < 3; i++) { - mMediator.onModuleBuilt(i, mModuleProviders[i]); + mMediator.onModuleBuilt(mModuleTypeList[i], mModuleProviders[i]); } // The response of the second highest ranking module arrives first. @@ -287,7 +285,7 @@ // Calls onModuleBuilt() to add ModuleProviders to the map. for (int i = 0; i < 3; i++) { - mMediator.onModuleBuilt(i, mModuleProviders[i]); + mMediator.onModuleBuilt(mModuleTypeList[i], mModuleProviders[i]); } // Adds modules to the recyclerview and show. PropertyModel propertyModel0 = Mockito.mock(PropertyModel.class); @@ -478,7 +476,7 @@ mMediator.buildModulesAndShow(moduleList, mModuleDelegate, mOnHomeModulesChangedCallback); // Calls onModuleBuilt() to add ModuleProviders to the map. for (int i = 0; i < 3; i++) { - mMediator.onModuleBuilt(i, mModuleProviders[i]); + mMediator.onModuleBuilt(mModuleTypeList[i], mModuleProviders[i]); } Boolean[] moduleFetchResultsIndicator = mMediator.getModuleFetchResultsIndicatorForTesting(); @@ -583,7 +581,6 @@ Set.of( ModuleType.PRICE_CHANGE, ModuleType.SINGLE_TAB, - ModuleType.TAB_RESUMPTION, ModuleType.SAFETY_HUB, ModuleType.AUXILIARY_SEARCH, ModuleType.DEFAULT_BROWSER_PROMO, @@ -598,7 +595,6 @@ expectedModuleSet = Set.of( ModuleType.PRICE_CHANGE, - ModuleType.TAB_RESUMPTION, ModuleType.SAFETY_HUB, ModuleType.AUXILIARY_SEARCH, ModuleType.DEFAULT_BROWSER_PROMO, @@ -651,17 +647,17 @@ new ClassificationResult( org.chromium.components.segmentation_platform.prediction_status .PredictionStatus.SUCCEEDED, - new String[] {"TabResumption", "SingleTab", "PriceChange"}, + new String[] {"SafetyHub", "SingleTab", "PriceChange"}, /* requestId= */ 0); Set<Integer> filteredEnabledModuleSet = new HashSet<>(); filteredEnabledModuleSet.add(ModuleType.SINGLE_TAB); filteredEnabledModuleSet.add(ModuleType.PRICE_CHANGE); - filteredEnabledModuleSet.add(ModuleType.TAB_RESUMPTION); + filteredEnabledModuleSet.add(ModuleType.SAFETY_HUB); // Verifies that result of #filterEnabledModuleList() is used if the segmentation // service returns a valid result. List<Integer> expectedModuleList = - List.of(ModuleType.TAB_RESUMPTION, ModuleType.SINGLE_TAB, ModuleType.PRICE_CHANGE); + List.of(ModuleType.SAFETY_HUB, ModuleType.SINGLE_TAB, ModuleType.PRICE_CHANGE); assertEquals( expectedModuleList, mMediator.filterEnabledModuleList( @@ -669,7 +665,7 @@ // Verifies that the disabled module will be removed from the result of the segmentation // service. - filteredEnabledModuleSet.remove(ModuleType.TAB_RESUMPTION); + filteredEnabledModuleSet.remove(ModuleType.SAFETY_HUB); expectedModuleList = List.of(ModuleType.SINGLE_TAB, ModuleType.PRICE_CHANGE); assertEquals( expectedModuleList, @@ -705,4 +701,18 @@ INVALID_IMPRESSION_COUNT_BEFORE_INTERACTION, HomeModulesUtils.getImpressionCountBeforeInteraction(moduleType2)); } + + /** + * Helps to register a module. + * + * @param index The index of the module on the list. + * @param type The module type. + */ + private void registerModule(int index, @ModuleType int type) { + mModuleTypeList[index] = type; + mModuleProviderBuilderList[index] = Mockito.mock(ModuleProviderBuilder.class); + doReturn(true).when(mModuleProviderBuilderList[index]).build(eq(mModuleDelegate), any()); + mListItems[index] = new ListItem(mModuleTypeList[index], Mockito.mock(PropertyModel.class)); + mModuleProviders[index] = Mockito.mock(ModuleProvider.class); + } }
diff --git a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.cc b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.cc index 04af36a..5bfeadc 100644 --- a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.cc +++ b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.cc
@@ -278,6 +278,10 @@ void AutoPictureInPictureTabHelper::MaybeEnterAutoPictureInPicture() { if (!IsEligibleForAutoPictureInPicture( /*should_record_blocking_metrics=*/true)) { + if (content::MediaSession* media_session = + content::MediaSession::GetIfExists(web_contents())) { + media_session->ReportAutoPictureInPictureInfoChanged(); + } return; } auto_picture_in_picture_activation_time_ = @@ -560,6 +564,19 @@ return media::PictureInPictureEventsInfo::AutoPipReason::kUnknown; } +media::PictureInPictureEventsInfo::AutoPipInfo +AutoPictureInPictureTabHelper::GetAutoPipInfo() const { + return media::PictureInPictureEventsInfo::AutoPipInfo{ + .auto_pip_reason = GetAutoPipTriggerReason(), + .has_audio_focus = has_audio_focus_, + .is_playing = is_playing_, + .was_recently_audible = WasRecentlyAudible(), + .has_safe_url = has_safe_url_, + .meets_media_engagement_conditions = MeetsMediaEngagementConditions(), + .blocked_due_to_content_setting = blocked_due_to_content_setting_, + }; +} + media::PictureInPictureEventsInfo::AutoPipReason AutoPictureInPictureTabHelper::GetAutoPipTriggerReason() const { return auto_pip_trigger_reason_;
diff --git a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.h b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.h index d37e4624..90fc365 100644 --- a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.h +++ b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.h
@@ -159,6 +159,11 @@ media::PictureInPictureEventsInfo::AutoPipReason GetAutoPipTriggerReason() const; + // Returns information related to auto picture in picture. This information + // includes the reason for entering picture in picture automatically, if + // known, and various conditions that are used to allow/deny autopip requests. + media::PictureInPictureEventsInfo::AutoPipInfo GetAutoPipInfo() const; + private: explicit AutoPictureInPictureTabHelper(content::WebContents* web_contents); friend class content::WebContentsUserData<AutoPictureInPictureTabHelper>;
diff --git a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper_browsertest.cc b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper_browsertest.cc index c5776fe..0151e5a 100644 --- a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper_browsertest.cc +++ b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper_browsertest.cc
@@ -8,6 +8,7 @@ #include "base/files/file_util.h" #include "base/path_service.h" +#include "base/scoped_observation.h" #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_tick_clock.h" #include "build/build_config.h" @@ -194,6 +195,45 @@ std::optional<bool> was_recently_audible_; }; +// Helper class to wait for DevTools to receive auto picture in picture events +// information. +class AutoPipInfoDevToolsWaiter : public content::DevToolsInspectorLogWatcher:: + DevToolsInspectorLogWatcherObserver { + public: + explicit AutoPipInfoDevToolsWaiter( + content::DevToolsInspectorLogWatcher* log_watcher) { + auto_pip_dev_tools_waiter_observation_.Observe(log_watcher); + } + AutoPipInfoDevToolsWaiter(const AutoPipInfoDevToolsWaiter&) = delete; + AutoPipInfoDevToolsWaiter(AutoPipInfoDevToolsWaiter&&) = delete; + AutoPipInfoDevToolsWaiter& operator=(const AutoPipInfoDevToolsWaiter&) = + delete; + + void WaitUntilDone() { + if (auto_pip_event_info_set_) { + return; + } + run_loop_ = std::make_unique<base::RunLoop>(); + run_loop_->Run(); + } + + private: + void OnLastAutoPipEventInfoSet() override { + auto_pip_event_info_set_ = true; + if (run_loop_) { + run_loop_->Quit(); + } + auto_pip_dev_tools_waiter_observation_.Reset(); + } + + std::unique_ptr<base::RunLoop> run_loop_; + bool auto_pip_event_info_set_ = false; + base::ScopedObservation< + content::DevToolsInspectorLogWatcher, + content::DevToolsInspectorLogWatcher::DevToolsInspectorLogWatcherObserver> + auto_pip_dev_tools_waiter_observation_{this}; +}; + class AutoPictureInPictureTabHelperBrowserTest : public WebRtcTestBase { public: AutoPictureInPictureTabHelperBrowserTest() = default; @@ -679,8 +719,10 @@ media::PictureInPictureEventsInfo::AutoPipReason GetAutoPipReason( const content::WebContents& web_contents) { - return content::GetContentClientForTesting()->browser()->GetAutoPipReason( - web_contents); + return content::GetContentClientForTesting() + ->browser() + ->GetAutoPipInfo(web_contents) + .auto_pip_reason; } ukm::TestAutoSetUkmRecorder* ukm_recorder() { return ukm_recorder_.get(); } @@ -2571,3 +2613,40 @@ CloseBrowserSynchronously(browser()); } + +IN_PROC_BROWSER_TEST_F(AutoPictureInPictureWithVideoPlaybackBrowserTest, + AutoPipInfoRecordedInDevTools) { + LoadAutoDocumentPipPage(browser()); + auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + PlayVideo(web_contents); + WaitForAudioFocusGained(); + WaitForMediaSessionPlaying(web_contents); + SetExpectedHasHighEngagement(true); + WaitForWasRecentlyAudible(web_contents); + + { + // Start watching the DevTools logs and clear the latest media notification. + content::DevToolsInspectorLogWatcher log_watcher( + web_contents, content::DevToolsInspectorLogWatcher::Domain::Media); + log_watcher.ClearLastAutoPictureInPictureEventInfo(); + + // Generate media logs. + AutoPipInfoDevToolsWaiter pip_devtools_info_waiter(&log_watcher); + SwitchToNewTabAndBackAndExpectAutopip(/*should_video_pip=*/false, + /*should_document_pip=*/true); + pip_devtools_info_waiter.WaitUntilDone(); + + // Verify that the auto picture in picture information was recorded in the + // DevTools media logs. + log_watcher.FlushAndStopWatching(); + ASSERT_FALSE(log_watcher.last_auto_picture_in_picture_event_info().empty()); + const std::string expected_auto_pip_info = + "{\"auto_picture_in_picture_info\":\"{Reason: MediaPlayback, has audio " + "focus: true, is_playing: true, was recently audible: true, has safe " + "url: true, meets media engagement conditions: true, blocked due to " + "content setting: " + "false}\",\"event\":\"kAutoPictureInPictureInfoChanged\"}"; + EXPECT_EQ(expected_auto_pip_info, + log_watcher.last_auto_picture_in_picture_event_info()); + } +}
diff --git a/chrome/browser/picture_in_picture/auto_pip_setting_view.cc b/chrome/browser/picture_in_picture/auto_pip_setting_view.cc index 7b0d0c3..93674252 100644 --- a/chrome/browser/picture_in_picture/auto_pip_setting_view.cc +++ b/chrome/browser/picture_in_picture/auto_pip_setting_view.cc
@@ -62,6 +62,7 @@ views::BubbleBorder::Arrow arrow) : views::BubbleDialogDelegate(anchor_view, arrow), result_cb_(std::move(result_cb)) { + SetOwnedByWidget(true); DialogDelegate::SetButtons(static_cast<int>(ui::mojom::DialogButton::kNone)); CHECK(result_cb_); SetAnchorView(anchor_view);
diff --git a/chrome/browser/predictors/prefetch_manager.cc b/chrome/browser/predictors/prefetch_manager.cc index ae205370..4cf17004 100644 --- a/chrome/browser/predictors/prefetch_manager.cc +++ b/chrome/browser/predictors/prefetch_manager.cc
@@ -29,6 +29,7 @@ #include "net/base/load_flags.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "services/network/public/cpp/empty_url_loader_client.h" +#include "services/network/public/cpp/permissions_policy/permissions_policy.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/url_loader_factory_builder.h" #include "services/network/public/mojom/fetch_api.mojom.h" @@ -246,6 +247,12 @@ // conservative one (no-referrer) by default. request.referrer_policy = net::ReferrerPolicy::NO_REFERRER; + // The prefetch can happen before the permissions policy is known, so use a + // conservative, all-blocking permissions policy. + request.permissions_policy = + *network::PermissionsPolicy::CreateFromParsedPolicy( + {}, {}, url::Origin::Create(request.url)); + request.headers.SetHeader(blink::kPurposeHeaderName, blink::kSecPurposePrefetchHeaderValue); request.headers.SetHeader(blink::kSecPurposeHeaderName,
diff --git a/chrome/browser/predictors/prefetch_manager_unittest.cc b/chrome/browser/predictors/prefetch_manager_unittest.cc index fcbab47..ace14a9 100644 --- a/chrome/browser/predictors/prefetch_manager_unittest.cc +++ b/chrome/browser/predictors/prefetch_manager_unittest.cc
@@ -33,6 +33,7 @@ #include "net/base/network_isolation_key.h" #include "net/test/embedded_test_server/controllable_http_response.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "services/network/public/cpp/permissions_policy/permissions_policy.h" #include "services/network/public/mojom/fetch_api.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h" @@ -174,6 +175,9 @@ EXPECT_TRUE(request.load_flags & net::LOAD_PREFETCH); EXPECT_EQ(request.referrer_policy, net::ReferrerPolicy::NO_REFERRER); + EXPECT_EQ(request.permissions_policy, + *network::PermissionsPolicy::CreateFromParsedPolicy( + {}, {}, url::Origin::Create(request.url))); EXPECT_EQ(request.destination, network::mojom::RequestDestination::kScript); EXPECT_EQ( @@ -662,6 +666,9 @@ EXPECT_TRUE(request.load_flags & net::LOAD_PREFETCH); EXPECT_EQ(request.referrer_policy, net::ReferrerPolicy::NO_REFERRER); + EXPECT_EQ(request.permissions_policy, + *network::PermissionsPolicy::CreateFromParsedPolicy( + {}, {}, url::Origin::Create(request.url))); EXPECT_EQ(request.destination, network::mojom::RequestDestination::kFont); EXPECT_EQ(
diff --git a/chrome/browser/privacy_sandbox/notice/notice_model.cc b/chrome/browser/privacy_sandbox/notice/notice_model.cc index 92971fca..534023a 100644 --- a/chrome/browser/privacy_sandbox/notice/notice_model.cc +++ b/chrome/browser/privacy_sandbox/notice/notice_model.cc
@@ -104,37 +104,47 @@ return false; } -bool Notice::IsFulfillmentEvent(PrivacySandboxNoticeEvent event) { - const std::set<PrivacySandboxNoticeEvent>& enabled_set = - EnablementFulfillEvents(); - const std::set<PrivacySandboxNoticeEvent>& disabled_set = - DisablementFulfillEvents(); - if (enabled_set.find(event) != enabled_set.end()) { - return true; +std::optional<bool> Notice::EvaluateNoticeEvent( + PrivacySandboxNoticeEvent event) { + switch (event) { + // Fulfillment : Yes + case PrivacySandboxNoticeEvent::kAck: + case PrivacySandboxNoticeEvent::kSettings: + return true; + // Not Fulfillment + case PrivacySandboxNoticeEvent::kShown: + return std::nullopt; + // Unexpected. + default: + NOTREACHED(); } - if (disabled_set.find(event) != disabled_set.end()) { - return true; +} + +std::optional<bool> Consent::EvaluateNoticeEvent( + PrivacySandboxNoticeEvent event) { + switch (event) { + // Fulfillment : Yes + case PrivacySandboxNoticeEvent::kOptIn: + return true; + // Fulfillment : No + case PrivacySandboxNoticeEvent::kOptOut: + return false; + // Not Fulfillment + case PrivacySandboxNoticeEvent::kShown: + return std::nullopt; + // Unexpected. + default: + NOTREACHED(); } - return false; } void Notice::UpdateTargetApiResults(PrivacySandboxNoticeEvent event) { - if (!IsFulfillmentEvent(event)) { + std::optional<bool> result = EvaluateNoticeEvent(event); + if (!result.has_value()) { return; } - const std::set<PrivacySandboxNoticeEvent>& enabled_set = - EnablementFulfillEvents(); - const std::set<PrivacySandboxNoticeEvent>& disabled_set = - DisablementFulfillEvents(); for (NoticeApi* api : target_apis_) { - if (enabled_set.find(event) != enabled_set.end()) { - api->UpdateResult(true); - continue; - } - if (disabled_set.find(event) != disabled_set.end()) { - api->UpdateResult(false); - continue; - } + api->UpdateResult(*result); } } @@ -142,18 +152,6 @@ return NoticeType::kNotice; } -const std::set<PrivacySandboxNoticeEvent>& Notice::EnablementFulfillEvents() { - static base::NoDestructor<std::set<PrivacySandboxNoticeEvent>> enabled_set{ - {PrivacySandboxNoticeEvent::kAck, PrivacySandboxNoticeEvent::kSettings}}; - return *enabled_set; -} - -const std::set<PrivacySandboxNoticeEvent>& Notice::DisablementFulfillEvents() { - static base::NoDestructor<std::set<PrivacySandboxNoticeEvent>> disabled_set{ - {}}; - return *disabled_set; -} - // Consent class definitions. Consent::Consent(NoticeId notice_id) : Notice(notice_id) {} @@ -161,18 +159,6 @@ return NoticeType::kConsent; } -const std::set<PrivacySandboxNoticeEvent>& Consent::EnablementFulfillEvents() { - static base::NoDestructor<std::set<PrivacySandboxNoticeEvent>> enabled_set{ - {PrivacySandboxNoticeEvent::kOptIn}}; - return *enabled_set; -} - -const std::set<PrivacySandboxNoticeEvent>& Consent::DisablementFulfillEvents() { - static base::NoDestructor<std::set<PrivacySandboxNoticeEvent>> disabled_set{ - {PrivacySandboxNoticeEvent::kOptOut}}; - return *disabled_set; -} - // Notice catalog class definitions. NoticeCatalog::NoticeCatalog() = default; NoticeCatalog::~NoticeCatalog() = default;
diff --git a/chrome/browser/privacy_sandbox/notice/notice_model.h b/chrome/browser/privacy_sandbox/notice/notice_model.h index 6f587fa..042507e 100644 --- a/chrome/browser/privacy_sandbox/notice/notice_model.h +++ b/chrome/browser/privacy_sandbox/notice/notice_model.h
@@ -70,22 +70,22 @@ // performed on this notice. void UpdateTargetApiResults(notice::mojom::PrivacySandboxNoticeEvent event); - // Determines if an `event` is one of the FulfillEvents, both enabled or - // disable events are considered. - bool IsFulfillmentEvent(notice::mojom::PrivacySandboxNoticeEvent event); - // TODO(crbug.com/392612108) NoticeViews should also implement a function to // guard against a notice showing in certain conditions, even if it is the // only one that fulfills a certain Api. Example of this: Measurement Only // notice showing for the wrong group of users: Over 18 for example. private: - // TODO(crbug.com/392612108): Add a feature for every notice here, we will - // use the associated string/name for pref setting. - virtual const std::set<notice::mojom::PrivacySandboxNoticeEvent>& - EnablementFulfillEvents(); - virtual const std::set<notice::mojom::PrivacySandboxNoticeEvent>& - DisablementFulfillEvents(); + // Evaluates the outcome of a notice event. + // Return value semantics: + // - `has_value()` is true if the event is a fulfillment event. + // - `value()` is `true` for positive actions (Ack/OptIn) and `false` for + // negative (OptOut). + // - `std::nullopt` is returned for non-fulfillment events. + // Asserts (NOTREACHED) if the event is unexpected for the Notice. + virtual std::optional<bool> EvaluateNoticeEvent( + notice::mojom::PrivacySandboxNoticeEvent event); + NoticeId notice_id_; std::vector<raw_ptr<NoticeApi>> target_apis_; std::vector<raw_ptr<NoticeApi>> pre_req_apis_; @@ -98,10 +98,8 @@ NoticeType GetNoticeType() override; private: - const std::set<notice::mojom::PrivacySandboxNoticeEvent>& - EnablementFulfillEvents() override; - const std::set<notice::mojom::PrivacySandboxNoticeEvent>& - DisablementFulfillEvents() override; + std::optional<bool> EvaluateNoticeEvent( + notice::mojom::PrivacySandboxNoticeEvent event) override; }; class NoticeApi {
diff --git a/chrome/browser/privacy_sandbox/notice/notice_model_unittest.cc b/chrome/browser/privacy_sandbox/notice/notice_model_unittest.cc index e26ff57..8db4f98 100644 --- a/chrome/browser/privacy_sandbox/notice/notice_model_unittest.cc +++ b/chrome/browser/privacy_sandbox/notice/notice_model_unittest.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/privacy_sandbox/notice/notice_model.h" #include "base/test/mock_callback.h" -#include "chrome/browser/privacy_sandbox/notice/notice_features.h" #include "components/privacy_sandbox/privacy_sandbox_notice.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest-death-test.h" @@ -16,256 +15,399 @@ using privacy_sandbox::notice::mojom::PrivacySandboxNoticeEvent; using testing::_; using testing::Contains; -using testing::ValuesIn; +using testing::ElementsAre; +using testing::Eq; +using testing::IsEmpty; +using testing::Mock; +using testing::Return; +using testing::StrictMock; + +using enum privacy_sandbox::EligibilityLevel; +using enum privacy_sandbox::notice::mojom::PrivacySandboxNoticeEvent; +using enum privacy_sandbox::NoticeType; +using enum privacy_sandbox::SurfaceType; namespace privacy_sandbox { - -template <typename T> -std::unique_ptr<Notice> Make(NoticeId id) { - return std::make_unique<T>(id); -} namespace { -class NoticeTest : public testing::Test { - public: - NoticeTest() : catalog_(std::make_unique<NoticeCatalog>()) {} +BASE_FEATURE(kTestFeatureA, "TestFeatureA", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kTestFeatureB, "TestFeatureB", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kTestFeatureC, "TestFeatureC", base::FEATURE_DISABLED_BY_DEFAULT); - Notice* RegisterAndRetrieveNotice(PrivacySandboxNotice notice) { - return catalog_->RegisterAndRetrieveNewNotice( - &Make<Notice>, {notice, SurfaceType::kDesktopNewTab}); - } +// Test notice & Consent ID, with arbitrary NoticeType and SurfaceType. +constexpr NoticeId kTestNoticeId = {PrivacySandboxNotice::kThreeAdsApisNotice, + kDesktopNewTab}; - Notice* RegisterAndRetrieveConsent(PrivacySandboxNotice notice) { - return catalog_->RegisterAndRetrieveNewNotice( - &Make<Consent>, {notice, SurfaceType::kDesktopNewTab}); - } +constexpr NoticeId kTestConsentId = {PrivacySandboxNotice::kTopicsConsentNotice, + kClankBrApp}; - NoticeCatalog* notice_catalog() { return catalog_.get(); } +// Helper function to create Notice/Consent objects easily in tests +template <typename T> +std::unique_ptr<Notice> Make(NoticeId notice_id) { + return std::make_unique<T>(notice_id); +} - private: - std::unique_ptr<NoticeCatalog> catalog_; +//----------------------------------------------------------------------------- +// Notice / Consent Tests +//----------------------------------------------------------------------------- + +class PrivacySandboxNoticeModelTest : public testing::Test {}; + +TEST_F(PrivacySandboxNoticeModelTest, InitializeNotice) { + Notice notice(kTestNoticeId); + Consent consent(kTestConsentId); + EXPECT_EQ(notice.GetNoticeId(), kTestNoticeId); + EXPECT_EQ(notice.GetNoticeType(), kNotice); +} + +TEST_F(PrivacySandboxNoticeModelTest, InitializeConsent) { + Consent consent(kTestConsentId); + EXPECT_EQ(consent.GetNoticeId(), kTestConsentId); + EXPECT_EQ(consent.GetNoticeType(), kConsent); +} + +TEST_F(PrivacySandboxNoticeModelTest, SetAndGetFeature) { + Notice notice(kTestNoticeId); + EXPECT_EQ(notice.GetFeature(), nullptr); + notice.SetFeature(&kTestFeatureA); + EXPECT_EQ(notice.GetFeature(), &kTestFeatureA); +} + +TEST_F(PrivacySandboxNoticeModelTest, SetAndGetTargetApis) { + Notice notice(kTestNoticeId); + EXPECT_THAT(notice.GetTargetApis(), IsEmpty()); + + NoticeApi api1, api2; + notice.SetTargetApis({&api1, &api2}); + + EXPECT_THAT(notice.GetTargetApis(), ElementsAre(&api1, &api2)); + EXPECT_THAT(api1.GetLinkedNotices(), Contains(¬ice)); + EXPECT_THAT(api2.GetLinkedNotices(), Contains(¬ice)); +} + +TEST_F(PrivacySandboxNoticeModelTest, SetAndGetPreReqApis) { + Notice notice(kTestNoticeId); + EXPECT_THAT(notice.GetPreReqApis(), IsEmpty()); + + NoticeApi api1, api2; + notice.SetPreReqApis({&api1, &api2}); + + EXPECT_THAT(notice.GetPreReqApis(), ElementsAre(&api1, &api2)); +} + +TEST_F(PrivacySandboxNoticeModelTest, WasFulfilledInitialState) { + // TODO(crbug.com/392612108): Update this test when WasFulfilled is + // implemented. + Notice notice(kTestNoticeId); + Consent consent(kTestConsentId); + EXPECT_FALSE(notice.WasFulfilled()); + EXPECT_FALSE(consent.WasFulfilled()); +} + +struct NoticeTestParam { + std::unique_ptr<Notice> (*create)(NoticeId); + PrivacySandboxNoticeEvent event; + enum class Result { + kOutcomeTrue, + kOutcomeFalse, + kNotFulfillment, + kUnexpected, + }; + Result expected_result; }; -TEST_F(NoticeTest, NoticeIsFulfillmentEventCorrect) { - Notice* notice = - RegisterAndRetrieveNotice(PrivacySandboxNotice::kTopicsConsentNotice); - for (const auto& event : {PrivacySandboxNoticeEvent::kAck, - PrivacySandboxNoticeEvent::kSettings}) { - EXPECT_EQ(notice->IsFulfillmentEvent(event), true); +using enum NoticeTestParam::Result; + +class PrivacySandboxNoticeModelResultCallbackTest + : public PrivacySandboxNoticeModelTest, + public testing::WithParamInterface<NoticeTestParam> {}; + +TEST_P(PrivacySandboxNoticeModelResultCallbackTest, UpdateTargetApiResults) { + const auto& param = GetParam(); + + StrictMock<MockCallback<base::OnceCallback<void(bool)>>> callback_1, + callback_2; + NoticeApi target_1, target_2; + target_1.SetResultCallback(callback_1.Get()); + target_2.SetResultCallback(callback_2.Get()); + + auto notice = param.create(kTestNoticeId); + notice->SetTargetApis({&target_1, &target_2}); + + switch (param.expected_result) { + case kOutcomeTrue: + // Validate all result callbacks are called when a true fulfilment event. + EXPECT_CALL(callback_1, Run(Eq(true))).Times(1); + EXPECT_CALL(callback_2, Run(Eq(true))).Times(1); + notice->UpdateTargetApiResults(param.event); + break; + case kOutcomeFalse: + // Validate all result callbacks are called when a false fulfilment event. + EXPECT_CALL(callback_1, Run(Eq(false))).Times(1); + EXPECT_CALL(callback_2, Run(Eq(false))).Times(1); + notice->UpdateTargetApiResults(param.event); + break; + case kNotFulfillment: + // Some Events that aren't fulfilment events, will not call the Result + // callback (validated via the StrictMock). + notice->UpdateTargetApiResults(param.event); + break; + case kUnexpected: + // Certain Unexpected Events should trigger a crash depending on the + // Notice Type. + EXPECT_DEATH(notice->UpdateTargetApiResults(param.event), ""); + break; } - EXPECT_EQ(notice->IsFulfillmentEvent(PrivacySandboxNoticeEvent::kOptIn), - false); + Mock::VerifyAndClearExpectations(&callback_1); + Mock::VerifyAndClearExpectations(&callback_2); } -TEST_F(NoticeTest, ConsentIsFulfillmentEventCorrect) { - Notice* notice = - RegisterAndRetrieveConsent(PrivacySandboxNotice::kTopicsConsentNotice); - for (const auto& event : {PrivacySandboxNoticeEvent::kOptIn, - PrivacySandboxNoticeEvent::kOptOut}) { - EXPECT_EQ(notice->IsFulfillmentEvent(event), true); - } - EXPECT_EQ(notice->IsFulfillmentEvent(PrivacySandboxNoticeEvent::kAck), false); +std::vector<NoticeTestParam> notice_test_params = { + // Notice + {&Make<Notice>, kAck, kOutcomeTrue}, + {&Make<Notice>, kSettings, kOutcomeTrue}, + {&Make<Notice>, kShown, kNotFulfillment}, + {&Make<Notice>, kClosed, kUnexpected}, + {&Make<Notice>, kOptIn, kUnexpected}, + {&Make<Notice>, kOptOut, kUnexpected}, + // Consent + {&Make<Consent>, kOptIn, kOutcomeTrue}, + {&Make<Consent>, kOptOut, kOutcomeFalse}, + {&Make<Consent>, kShown, kNotFulfillment}, + {&Make<Consent>, kAck, kUnexpected}, + {&Make<Consent>, kSettings, kUnexpected}, + {&Make<Consent>, kClosed, kUnexpected}, +}; + +INSTANTIATE_TEST_SUITE_P(PrivacySandboxNoticeModelResultCallbackTest, + PrivacySandboxNoticeModelResultCallbackTest, + testing::ValuesIn(notice_test_params)); + +//----------------------------------------------------------------------------- +// NoticeApi Tests +//----------------------------------------------------------------------------- + +class PrivacySandboxNoticeApiTest : public testing::Test { + protected: + NoticeApi api_; + std::unique_ptr<Notice> notice_ = std::make_unique<Notice>(kTestNoticeId); + std::unique_ptr<Consent> consent_ = std::make_unique<Consent>(kTestConsentId); + StrictMock<MockCallback<base::RepeatingCallback<EligibilityLevel()>>> + mock_eligibility_callback_; + StrictMock<MockCallback<base::OnceCallback<void(bool)>>> + mock_result_callback_; +}; + +TEST_F(PrivacySandboxNoticeApiTest, InitialState) { + EXPECT_THAT(api_.GetLinkedNotices(), IsEmpty()); + EXPECT_EQ(api_.GetEligibilityLevel(), kNotEligible); + EXPECT_FALSE(api_.IsFulfilled()); } -TEST_F(NoticeTest, NoEligibilityCallbackReturnsNotEligible) { - NoticeApi* api = notice_catalog()->RegisterAndRetrieveNewApi(); - EXPECT_EQ(api->GetEligibilityLevel(), EligibilityLevel::kNotEligible); +TEST_F(PrivacySandboxNoticeApiTest, SetAndGetEligibilityCallback) { + api_.SetEligibilityCallback(mock_eligibility_callback_.Get()); + // Callback triggeerd via GetEligibilityLevel. + EXPECT_CALL(mock_eligibility_callback_, Run()) + .Times(1) + .WillOnce(Return(kEligibleNotice)); + EXPECT_EQ(api_.GetEligibilityLevel(), kEligibleNotice); + Mock::VerifyAndClearExpectations(&mock_result_callback_); + + // Callback triggeered via IsFulfilled. + EXPECT_CALL(mock_eligibility_callback_, Run()).Times(1); + api_.IsFulfilled(); + Mock::VerifyAndClearExpectations(&mock_result_callback_); } -TEST_F(NoticeTest, SetEligibilityCallbackReturnsNoticeEligibilitySuccessfully) { - NoticeApi* api = - notice_catalog()->RegisterAndRetrieveNewApi()->SetEligibilityCallback( - base::BindRepeating([]() -> EligibilityLevel { - return EligibilityLevel::kEligibleNotice; - })); - RegisterAndRetrieveNotice(PrivacySandboxNotice::kTopicsConsentNotice) - ->SetTargetApis({api}); - // TODO(crbug.com/392612108): Once WasFulfilled is implemented, change this - // value. - EXPECT_FALSE(api->IsFulfilled()); +TEST_F(PrivacySandboxNoticeApiTest, SetAndCallResultCallback) { + EXPECT_CALL(mock_result_callback_, Run(Eq(true))).Times(1); + api_.SetResultCallback(mock_result_callback_.Get()); + api_.UpdateResult(true); + Mock::VerifyAndClearExpectations(&mock_result_callback_); + + EXPECT_CALL(mock_result_callback_, Run(Eq(false))).Times(1); + api_.SetResultCallback(mock_result_callback_.Get()); + api_.UpdateResult(false); + Mock::VerifyAndClearExpectations(&mock_result_callback_); } -TEST_F(NoticeTest, - SetEligibilityCallbackReturnsConsentEligibilitySuccessfully) { - NoticeApi* api = - notice_catalog()->RegisterAndRetrieveNewApi()->SetEligibilityCallback( - base::BindRepeating([]() -> EligibilityLevel { - return EligibilityLevel::kEligibleConsent; - })); - RegisterAndRetrieveConsent(PrivacySandboxNotice::kTopicsConsentNotice) - ->SetTargetApis({api}); - // TODO(crbug.com/392612108): Once WasFulfilled is implemented, change this - // value. - EXPECT_FALSE(api->IsFulfilled()); +TEST_F(PrivacySandboxNoticeApiTest, UpdateResultWithoutCallback) { + api_.UpdateResult(true); + SUCCEED(); } -TEST_F(NoticeTest, ConsentEligibilityWithNoticeTypeReturnsNotFulfilled) { - NoticeApi* api = - notice_catalog()->RegisterAndRetrieveNewApi()->SetEligibilityCallback( - base::BindRepeating([]() -> EligibilityLevel { - return EligibilityLevel::kEligibleConsent; - })); - RegisterAndRetrieveNotice(PrivacySandboxNotice::kTopicsConsentNotice) - ->SetTargetApis({api}); - // TODO(crbug.com/392612108): Once WasFulfilled is implemented, change this - // value. - EXPECT_FALSE(api->IsFulfilled()); +TEST_F(PrivacySandboxNoticeApiTest, CanBeFulfilledByAndGetLinkedNotices) { + EXPECT_THAT(api_.GetLinkedNotices(), IsEmpty()); + api_.CanBeFulfilledBy(notice_.get()); + EXPECT_THAT(api_.GetLinkedNotices(), ElementsAre(notice_.get())); + api_.CanBeFulfilledBy(consent_.get()); + EXPECT_THAT(api_.GetLinkedNotices(), + ElementsAre(notice_.get(), consent_.get())); } -class ResultCallbackTest - : public NoticeTest, - public testing::WithParamInterface<PrivacySandboxNoticeEvent> {}; - -TEST_P(ResultCallbackTest, UpdateTargetApiResultsSuccess) { - MockCallback<base::OnceCallback<void(bool)>> result_callback; - NoticeApi* target = - notice_catalog()->RegisterAndRetrieveNewApi()->SetResultCallback( - result_callback.Get()); - MockCallback<base::OnceCallback<void(bool)>> result2_callback; - NoticeApi* target2 = - notice_catalog()->RegisterAndRetrieveNewApi()->SetResultCallback( - result2_callback.Get()); - Notice* notice = - RegisterAndRetrieveConsent(PrivacySandboxNotice::kTopicsConsentNotice) - ->SetTargetApis({target, target2}); - - // Set Expectations. - if (notice->IsFulfillmentEvent(GetParam())) { - EXPECT_CALL(result_callback, Run(_)).Times(1); - EXPECT_CALL(result2_callback, Run(_)).Times(1); - } else { - EXPECT_CALL(result_callback, Run(_)).Times(0); - EXPECT_CALL(result2_callback, Run(_)).Times(0); - } - notice->UpdateTargetApiResults(GetParam()); +TEST_F(PrivacySandboxNoticeApiTest, IsFulfilledNoLinkedNotices) { + EXPECT_CALL(mock_eligibility_callback_, Run()) + .WillOnce(Return(kEligibleNotice)); + api_.SetEligibilityCallback(mock_eligibility_callback_.Get()); + EXPECT_FALSE(api_.IsFulfilled()); } -INSTANTIATE_TEST_SUITE_P( - ResultCallbackTest, - ResultCallbackTest, - ValuesIn(std::vector<PrivacySandboxNoticeEvent>{ - PrivacySandboxNoticeEvent::kAck, PrivacySandboxNoticeEvent::kClosed, - PrivacySandboxNoticeEvent::kOptIn, PrivacySandboxNoticeEvent::kOptOut, - PrivacySandboxNoticeEvent::kSettings, - PrivacySandboxNoticeEvent::kShown})); - -class NoticeCatalogNoticeTest : public NoticeTest {}; - -TEST_F(NoticeCatalogNoticeTest, RegisterNewNoticeSuccessfully) { - NoticeApi* target_api = notice_catalog()->RegisterAndRetrieveNewApi(); - - NoticeApi* pre_req_api = notice_catalog()->RegisterAndRetrieveNewApi(); - - EXPECT_EQ(notice_catalog()->GetNoticeApis().size(), 2u); - Notice* notice = - notice_catalog() - ->RegisterAndRetrieveNewNotice( - &Make<Consent>, {PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kDesktopNewTab}) - ->SetFeature(&kTopicsConsentDesktopModalFeature) - ->SetTargetApis({target_api}) - ->SetPreReqApis({pre_req_api}); - - EXPECT_EQ(notice->GetNoticeType(), NoticeType::kConsent); - EXPECT_THAT(target_api->GetLinkedNotices(), Contains(notice)); - EXPECT_EQ(notice->GetNoticeId().first, - PrivacySandboxNotice::kTopicsConsentNotice); - EXPECT_EQ(notice->GetNoticeId().second, SurfaceType::kDesktopNewTab); - EXPECT_THAT(notice->GetTargetApis(), Contains(target_api)); - EXPECT_THAT(notice->GetPreReqApis(), Contains(pre_req_api)); - EXPECT_EQ(notice->GetFeature(), &kTopicsConsentDesktopModalFeature); +TEST_F(PrivacySandboxNoticeApiTest, IsFulfilledNotEligible) { + EXPECT_CALL(mock_eligibility_callback_, Run()).WillOnce(Return(kNotEligible)); + api_.SetEligibilityCallback(mock_eligibility_callback_.Get()); + api_.CanBeFulfilledBy(notice_.get()); + EXPECT_FALSE(api_.IsFulfilled()); } -TEST_F(NoticeCatalogNoticeTest, RegisterNewNoticeGroupSuccessfully) { - NoticeApi* target_api = notice_catalog()->RegisterAndRetrieveNewApi(); - - NoticeApi* pre_req_api = notice_catalog()->RegisterAndRetrieveNewApi(); - - notice_catalog()->RegisterNoticeGroup( - &Make<Consent>, - {{{PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kDesktopNewTab}, - &kTopicsConsentDesktopModalFeature}, - {{PrivacySandboxNotice::kTopicsConsentNotice, SurfaceType::kClankBrApp}, - &kTopicsConsentModalClankBrAppFeature}, - {{PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kClankCustomTab}, - &kTopicsConsentModalClankCCTFeature}}, - {target_api}); - - notice_catalog()->RegisterNoticeGroup( - &Make<Notice>, - {{{PrivacySandboxNotice::kProtectedAudienceMeasurementNotice, - SurfaceType::kDesktopNewTab}, - &kProtectedAudienceMeasurementNoticeModalFeature}, - {{PrivacySandboxNotice::kProtectedAudienceMeasurementNotice, - SurfaceType::kClankBrApp}, - &kProtectedAudienceMeasurementNoticeModalClankBrAppFeature}, - {{PrivacySandboxNotice::kProtectedAudienceMeasurementNotice, - SurfaceType::kClankCustomTab}, - &kProtectedAudienceMeasurementNoticeModalClankCCTFeature}}, - {target_api}, {pre_req_api}); - - const auto& notice_map = notice_catalog()->GetNoticeMap(); - EXPECT_THAT(notice_catalog()->GetNoticeApis().size(), 2u); - EXPECT_THAT(notice_map.size(), 6u); - - Notice* topics_desktop_notice = - notice_map - .find(std::make_pair(PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kDesktopNewTab)) - ->second.get(); - EXPECT_EQ(topics_desktop_notice->GetNoticeType(), NoticeType::kConsent); - - Notice* pa_desktop_notice = - notice_map - .find(std::make_pair( - PrivacySandboxNotice::kProtectedAudienceMeasurementNotice, - SurfaceType::kDesktopNewTab)) - ->second.get(); - EXPECT_EQ(pa_desktop_notice->GetNoticeType(), NoticeType::kNotice); +TEST_F(PrivacySandboxNoticeApiTest, + IsFulfilledEligibleNoticeWithUnfulfilledNotice) { + EXPECT_CALL(mock_eligibility_callback_, Run()) + .WillOnce(Return(kEligibleNotice)); + api_.SetEligibilityCallback(mock_eligibility_callback_.Get()); + api_.CanBeFulfilledBy(notice_.get()); + EXPECT_FALSE(api_.IsFulfilled()); } -TEST_F(NoticeCatalogNoticeTest, - VerifyFeatureSetCorrectlyDuringNoticeGroupRegistration) { - NoticeCatalog catalog; - NoticeApi* target_api = notice_catalog()->RegisterAndRetrieveNewApi(); +TEST_F(PrivacySandboxNoticeApiTest, + IsFulfilledEligibleConsentWithUnfulfilledConsent) { + EXPECT_CALL(mock_eligibility_callback_, Run()) + .WillOnce(Return(kEligibleConsent)); + api_.SetEligibilityCallback(mock_eligibility_callback_.Get()); + api_.CanBeFulfilledBy(consent_.get()); + EXPECT_FALSE(api_.IsFulfilled()); +} - notice_catalog()->RegisterNoticeGroup( - &Make<Consent>, - {{{PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kDesktopNewTab}, - &kTopicsConsentDesktopModalFeature}, - {{PrivacySandboxNotice::kTopicsConsentNotice, SurfaceType::kClankBrApp}, - &kTopicsConsentModalClankBrAppFeature}, - {{PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kClankCustomTab}, - &kTopicsConsentModalClankCCTFeature}}, - {target_api}); +TEST_F(PrivacySandboxNoticeApiTest, + IsFulfilledEligibleConsentWithOnlyNoticeLinked) { + EXPECT_CALL(mock_eligibility_callback_, Run()) + .WillOnce(Return(kEligibleConsent)); + api_.SetEligibilityCallback(mock_eligibility_callback_.Get()); + api_.CanBeFulfilledBy(notice_.get()); + EXPECT_FALSE(api_.IsFulfilled()); +} - const auto& notice_map = notice_catalog()->GetNoticeMap(); +TEST_F(PrivacySandboxNoticeApiTest, + IsFulfilledEligibleNoticeWithMixedNoticesUnfulfilled) { + EXPECT_CALL(mock_eligibility_callback_, Run()) + .WillOnce(Return(kEligibleNotice)); + api_.SetEligibilityCallback(mock_eligibility_callback_.Get()); + api_.CanBeFulfilledBy(consent_.get()); + api_.CanBeFulfilledBy(notice_.get()); + EXPECT_FALSE(api_.IsFulfilled()); +} - Notice* topics_desktop_notice = - notice_map - .find(std::make_pair(PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kDesktopNewTab)) - ->second.get(); - EXPECT_EQ(topics_desktop_notice->GetFeature(), - &kTopicsConsentDesktopModalFeature); - Notice* topics_brapp_notice = - notice_map - .find(std::make_pair(PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kClankBrApp)) - ->second.get(); - EXPECT_EQ(topics_brapp_notice->GetFeature(), - &kTopicsConsentModalClankBrAppFeature); - Notice* topics_cct_notice = - notice_map - .find(std::make_pair(PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kClankCustomTab)) - ->second.get(); - EXPECT_EQ(topics_cct_notice->GetFeature(), - &kTopicsConsentModalClankCCTFeature); +TEST_F(PrivacySandboxNoticeApiTest, + IsFulfilledEligibleConsentWithMixedNoticesUnfulfilled) { + EXPECT_CALL(mock_eligibility_callback_, Run()) + .WillOnce(Return(kEligibleConsent)); + api_.SetEligibilityCallback(mock_eligibility_callback_.Get()); + api_.CanBeFulfilledBy(notice_.get()); + api_.CanBeFulfilledBy(consent_.get()); + EXPECT_FALSE(api_.IsFulfilled()); +} + +//----------------------------------------------------------------------------- +// Catalog Tests +//----------------------------------------------------------------------------- + +class PrivacySandboxNoticeCatalogTest : public testing::Test { + protected: + NoticeCatalog catalog_; +}; + +TEST_F(PrivacySandboxNoticeCatalogTest, InitialState) { + EXPECT_THAT(catalog_.GetNoticeApis(), IsEmpty()); + EXPECT_THAT(catalog_.GetNoticeMap(), IsEmpty()); +} + +TEST_F(PrivacySandboxNoticeCatalogTest, RegisterAndRetrieveNewApi) { + NoticeApi* api1 = catalog_.RegisterAndRetrieveNewApi(); + EXPECT_NE(api1, nullptr); + EXPECT_EQ(catalog_.GetNoticeApis().size(), 1u); + EXPECT_EQ(catalog_.GetNoticeApis()[0].get(), api1); + + NoticeApi* api2 = catalog_.RegisterAndRetrieveNewApi(); + EXPECT_NE(api2, nullptr); + EXPECT_NE(api1, api2); + EXPECT_EQ(catalog_.GetNoticeApis().size(), 2u); + EXPECT_EQ(catalog_.GetNoticeApis()[1].get(), api2); +} + +TEST_F(PrivacySandboxNoticeCatalogTest, RegisterAndRetrieveNewNotice) { + NoticeApi* target_api = catalog_.RegisterAndRetrieveNewApi(); + NoticeApi* prereq_api = catalog_.RegisterAndRetrieveNewApi(); + + Notice* consent_notice = + catalog_.RegisterAndRetrieveNewNotice(&Make<Consent>, kTestConsentId); + + ASSERT_NE(consent_notice, nullptr); + EXPECT_EQ(consent_notice->GetNoticeId(), kTestConsentId); + EXPECT_EQ(consent_notice->GetNoticeType(), kConsent); + EXPECT_EQ(catalog_.GetNoticeMap().size(), 1u); + ASSERT_TRUE(catalog_.GetNoticeMap().contains(kTestConsentId)); + EXPECT_EQ(catalog_.GetNoticeMap().at(kTestConsentId).get(), consent_notice); + + consent_notice->SetFeature(&kTestFeatureA) + ->SetTargetApis({target_api}) + ->SetPreReqApis({prereq_api}); + + EXPECT_EQ(consent_notice->GetFeature(), &kTestFeatureA); + EXPECT_THAT(consent_notice->GetTargetApis(), ElementsAre(target_api)); + EXPECT_THAT(consent_notice->GetPreReqApis(), ElementsAre(prereq_api)); + EXPECT_THAT(target_api->GetLinkedNotices(), Contains(consent_notice)); +} + +TEST_F(PrivacySandboxNoticeCatalogTest, RegisterNoticeGroup) { + NoticeApi* target_api1 = catalog_.RegisterAndRetrieveNewApi(); + NoticeApi* target_api2 = catalog_.RegisterAndRetrieveNewApi(); + NoticeApi* prereq_api = catalog_.RegisterAndRetrieveNewApi(); + + const NoticeId consent_id_desktop = { + PrivacySandboxNotice::kTopicsConsentNotice, kDesktopNewTab}; + const NoticeId consent_id_clank = {PrivacySandboxNotice::kTopicsConsentNotice, + kClankBrApp}; + const NoticeId notice_id_desktop = { + PrivacySandboxNotice::kProtectedAudienceMeasurementNotice, + kDesktopNewTab}; + + catalog_.RegisterNoticeGroup(&Make<Consent>, + {{consent_id_desktop, &kTestFeatureA}, + {consent_id_clank, &kTestFeatureB}}, + {target_api1}); + + catalog_.RegisterNoticeGroup(&Make<Notice>, + {{notice_id_desktop, &kTestFeatureC}}, + {target_api1, target_api2}, {prereq_api}); + + EXPECT_EQ(catalog_.GetNoticeApis().size(), 3u); + EXPECT_EQ(catalog_.GetNoticeMap().size(), 3u); + + ASSERT_TRUE(catalog_.GetNoticeMap().contains(consent_id_desktop)); + Notice* consent_desktop = + catalog_.GetNoticeMap().at(consent_id_desktop).get(); + EXPECT_EQ(consent_desktop->GetNoticeType(), kConsent); + EXPECT_EQ(consent_desktop->GetFeature(), &kTestFeatureA); + EXPECT_THAT(consent_desktop->GetTargetApis(), ElementsAre(target_api1)); + EXPECT_THAT(consent_desktop->GetPreReqApis(), IsEmpty()); + EXPECT_THAT(target_api1->GetLinkedNotices(), Contains(consent_desktop)); + + ASSERT_TRUE(catalog_.GetNoticeMap().contains(consent_id_clank)); + Notice* consent_clank = catalog_.GetNoticeMap().at(consent_id_clank).get(); + EXPECT_EQ(consent_clank->GetNoticeType(), kConsent); + EXPECT_EQ(consent_clank->GetFeature(), &kTestFeatureB); + EXPECT_THAT(consent_clank->GetTargetApis(), ElementsAre(target_api1)); + EXPECT_THAT(consent_clank->GetPreReqApis(), IsEmpty()); + EXPECT_THAT(target_api1->GetLinkedNotices(), Contains(consent_clank)); + + ASSERT_TRUE(catalog_.GetNoticeMap().contains(notice_id_desktop)); + Notice* notice_desktop = catalog_.GetNoticeMap().at(notice_id_desktop).get(); + EXPECT_EQ(notice_desktop->GetNoticeType(), kNotice); + EXPECT_EQ(notice_desktop->GetFeature(), &kTestFeatureC); + EXPECT_THAT(notice_desktop->GetTargetApis(), + ElementsAre(target_api1, target_api2)); + EXPECT_THAT(notice_desktop->GetPreReqApis(), ElementsAre(prereq_api)); + EXPECT_THAT(target_api1->GetLinkedNotices(), Contains(notice_desktop)); + EXPECT_THAT(target_api2->GetLinkedNotices(), Contains(notice_desktop)); } } // namespace } // namespace privacy_sandbox
diff --git a/chrome/browser/privacy_sandbox/notice/notice_service_unittest.cc b/chrome/browser/privacy_sandbox/notice/notice_service_unittest.cc index e74ab1f..728474e 100644 --- a/chrome/browser/privacy_sandbox/notice/notice_service_unittest.cc +++ b/chrome/browser/privacy_sandbox/notice/notice_service_unittest.cc
@@ -16,13 +16,22 @@ namespace privacy_sandbox { namespace { -using privacy_sandbox::notice::mojom::PrivacySandboxNotice; -using privacy_sandbox::notice::mojom::PrivacySandboxNoticeEvent; +using testing::Combine; +using testing::Test; +using testing::Values; +using testing::WithParamInterface; -class NoticeServiceTest : public testing::Test, - public testing::WithParamInterface<NoticeId> { +using enum privacy_sandbox::notice::mojom::PrivacySandboxNotice; +using enum privacy_sandbox::SurfaceType; +using privacy_sandbox::notice::mojom::PrivacySandboxNotice; +using Event = privacy_sandbox::notice::mojom::PrivacySandboxNoticeEvent; + +class PrivacySandboxNoticeServiceTest + : public Test, + public WithParamInterface< + std::tuple<SurfaceType, std::pair<PrivacySandboxNotice, Event>>> { public: - NoticeServiceTest() { + PrivacySandboxNoticeServiceTest() { profile_ = IdentityTestEnvironmentProfileAdaptor:: CreateProfileForIdentityTestEnvironment(); notice_service_ = @@ -40,56 +49,36 @@ std::unique_ptr<PrivacySandboxNoticeService> notice_service_; }; -TEST_P(NoticeServiceTest, EventOccurredRegisteredInNoticeStorage) { - NoticeId notice_id = GetParam(); +TEST_P(PrivacySandboxNoticeServiceTest, + EventOccurredRegisteredInNoticeStorage) { + auto [surface, notice_id_event] = GetParam(); + auto [notice, event] = notice_id_event; - notice_service()->EventOccurred(notice_id, PrivacySandboxNoticeEvent::kShown); - notice_service()->EventOccurred(notice_id, PrivacySandboxNoticeEvent::kAck); + notice_service()->EventOccurred({notice, surface}, Event::kShown); + notice_service()->EventOccurred({notice, surface}, event); std::string_view notice_name = notice_service() ->GetCatalog() ->GetNoticeMap() - .find(notice_id) + .find({notice, surface}) ->second->GetFeature() ->name; // Pref auto actual = notice_service()->GetNoticeStorage()->ReadNoticeData( notice_service()->GetPrefService(), notice_name); EXPECT_EQ(actual->GetNoticeActionTakenForFirstShownFromEvents()->first, - PrivacySandboxNoticeEvent::kAck); + event); EXPECT_EQ(actual->GetNoticeEvents().size(), 2u); } INSTANTIATE_TEST_SUITE_P( - NoticeServiceTest, - NoticeServiceTest, - testing::Values( - std::make_pair(PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kDesktopNewTab), - std::make_pair(PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kClankBrApp), - std::make_pair(PrivacySandboxNotice::kTopicsConsentNotice, - SurfaceType::kClankCustomTab), - std::make_pair(PrivacySandboxNotice::kThreeAdsApisNotice, - SurfaceType::kDesktopNewTab), - std::make_pair(PrivacySandboxNotice::kThreeAdsApisNotice, - SurfaceType::kClankBrApp), - std::make_pair(PrivacySandboxNotice::kThreeAdsApisNotice, - SurfaceType::kClankCustomTab), - std::make_pair( - PrivacySandboxNotice::kProtectedAudienceMeasurementNotice, - SurfaceType::kDesktopNewTab), - std::make_pair( - PrivacySandboxNotice::kProtectedAudienceMeasurementNotice, - SurfaceType::kClankBrApp), - std::make_pair( - PrivacySandboxNotice::kProtectedAudienceMeasurementNotice, - SurfaceType::kClankCustomTab), - std::make_pair(PrivacySandboxNotice::kMeasurementNotice, - SurfaceType::kDesktopNewTab), - std::make_pair(PrivacySandboxNotice::kMeasurementNotice, - SurfaceType::kClankBrApp), - std::make_pair(PrivacySandboxNotice::kMeasurementNotice, - SurfaceType::kClankCustomTab))); + PrivacySandboxNoticeServiceTest, + PrivacySandboxNoticeServiceTest, + Combine(Values(kDesktopNewTab, kClankBrApp, kClankCustomTab), + Values(std::make_pair(kTopicsConsentNotice, Event::kOptIn), + std::make_pair(kThreeAdsApisNotice, Event::kAck), + std::make_pair(kProtectedAudienceMeasurementNotice, + Event::kAck), + std::make_pair(kMeasurementNotice, Event::kAck)))); } // namespace } // namespace privacy_sandbox
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc index 18cf47b..599e68149 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc
@@ -516,6 +516,12 @@ browsing_topics_service_(browsing_topics_service), first_party_sets_policy_service_(first_party_sets_service), privacy_sandbox_countries_(privacy_sandbox_countries) { + static constexpr int kFakeTaxonomyVersion = 1; + fake_current_topics_ = {{browsing_topics::Topic(1), kFakeTaxonomyVersion}, + {browsing_topics::Topic(2), kFakeTaxonomyVersion}}; + fake_blocked_topics_ = {{browsing_topics::Topic(3), kFakeTaxonomyVersion}, + {browsing_topics::Topic(4), kFakeTaxonomyVersion}}; + // Create notice storage notice_storage_ = std::make_unique<privacy_sandbox::PrivacySandboxNoticeStorage>();
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.h b/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.h index 9b0689a..0ee66c1f 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.h +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.h
@@ -359,13 +359,10 @@ #endif // Fake implementation for current and blocked topics. - static constexpr int kFakeTaxonomyVersion = 1; - std::set<privacy_sandbox::CanonicalTopic> fake_current_topics_ = { - {browsing_topics::Topic(1), kFakeTaxonomyVersion}, - {browsing_topics::Topic(2), kFakeTaxonomyVersion}}; - std::set<privacy_sandbox::CanonicalTopic> fake_blocked_topics_ = { - {browsing_topics::Topic(3), kFakeTaxonomyVersion}, - {browsing_topics::Topic(4), kFakeTaxonomyVersion}}; + // TODO(crbug.com/409048902): Moved initialization to constructor to prevent + // potential initialization order issues. + std::set<privacy_sandbox::CanonicalTopic> fake_current_topics_; + std::set<privacy_sandbox::CanonicalTopic> fake_blocked_topics_; // Record user action metrics based on the |action|. void RecordPromptActionMetrics(PrivacySandboxService::PromptAction action);
diff --git a/chrome/browser/resources/discards/BUILD.gn b/chrome/browser/resources/discards/BUILD.gn index 2544f8b..3a621952 100644 --- a/chrome/browser/resources/discards/BUILD.gn +++ b/chrome/browser/resources/discards/BUILD.gn
@@ -28,6 +28,7 @@ css_files = [ "database_tab.css", "discards_tab.css", + "graph_tab.css", ] mojo_files_deps = [
diff --git a/chrome/browser/resources/discards/graph_tab.css b/chrome/browser/resources/discards/graph_tab.css new file mode 100644 index 0000000..e9f1b6c0 --- /dev/null +++ b/chrome/browser/resources/discards/graph_tab.css
@@ -0,0 +1,89 @@ +/* Copyright 2025 The Chromium Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + +/* #css_wrapper_metadata_start + * #type=style-lit + * #import=chrome://resources/cr_elements/cr_shared_vars.css.js + * #css_wrapper_metadata_end */ + +.links line { + stroke: #999; + stroke-opacity: 0.6; + stroke-width: 1; +} + +.dashed-links line { + marker-start: url(#arrowToSource); + stroke: #999; + stroke-dasharray: 3; + stroke-opacity: 0.6; + stroke-width: 1; +} + +#arrowToSource { + fill: #999; + stroke: #999; +} + +.nodes circle { + stroke: #000; + stroke-width: 1.5px; +} + +.nodes circle.pinned { + stroke: red; +} + +.dead image { + display: none; +} + +.separator { + font: italic 13px sans-serif; + user-select: none; +} + +div.tooltip { + background: lightsteelblue; + border: 0; + border-radius: 8px; + padding: 2px; + position: absolute; + text-align: center; +} + +@media (prefers-color-scheme: dark) { + div.tooltip { + background: dimgray; + } + + .separator { + fill: var(--cr-secondary-text-color); + } + + .separators line { + stroke: var(--cr-secondary-text-color); + } +} + +tr { + font: 10px sans-serif; +} + +tr.heading > td { + font-weight: bold; + text-align: center; +} + +tr.value > td:nth-child(1) { + text-align: end; +} + +tr.value > td:nth-child(2) { + text-align: start; +} + +tr.value.collapsed { + display: none; +}
diff --git a/chrome/browser/resources/discards/graph_tab.html b/chrome/browser/resources/discards/graph_tab.html index 4e73c5f..51fdb3b 100644 --- a/chrome/browser/resources/discards/graph_tab.html +++ b/chrome/browser/resources/discards/graph_tab.html
@@ -1,88 +1,6 @@ -<style> - .links line { - stroke: #999; - stroke-opacity: 0.6; - stroke-width: 1; - } - .dashed-links line { - marker-start: url(#arrowToSource); - stroke: #999; - stroke-dasharray: 3; - stroke-opacity: 0.6; - stroke-width: 1; - } - - #arrowToSource { - fill: #999; - stroke: #999; - } - - .nodes circle { - stroke: #000; - stroke-width: 1.5px; - } - - .nodes circle.pinned { - stroke: red; - } - - .dead image { - display: none; - } - - .separator { - font: italic 13px sans-serif; - user-select: none; - } - - div.tooltip { - background: lightsteelblue; - border: 0; - border-radius: 8px; - padding: 2px; - position: absolute; - text-align: center; - } - - @media (prefers-color-scheme: dark) { - div.tooltip { - background: dimgray; - } - - .separator { - fill: var(--cr-secondary-text-color); - } - - .separators line { - stroke: var(--cr-secondary-text-color); - } - } - - tr { - font: 10px sans-serif; - } - - tr.heading > td { - font-weight: bold; - text-align: center; - } - - tr.value > td:nth-child(1) { - text-align: end; - } - - tr.value > td:nth-child(2) { - text-align: start; - } - - tr.value.collapsed { - display: none; - } - -</style> <div id="toolTips" width="100%" height="100%" - on-request-node-descriptions="onRequestNodeDescriptions_"> + @request-node-descriptions="${this.onRequestNodeDescriptions_}"> </div> <svg id="graphBody" width="100%" height="100%"> <defs>
diff --git a/chrome/browser/resources/discards/graph_tab.ts b/chrome/browser/resources/discards/graph_tab.ts index e104126..fa86cd8 100644 --- a/chrome/browser/resources/discards/graph_tab.ts +++ b/chrome/browser/resources/discards/graph_tab.ts
@@ -2,27 +2,32 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {Debouncer, PolymerElement, timeOut} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js'; import type {GraphChangeStreamInterface, GraphDumpRemote} from './discards.mojom-webui.js'; import {GraphChangeStreamReceiver, GraphDump} from './discards.mojom-webui.js'; import {Graph} from './graph.js'; -import {getTemplate} from './graph_tab.html.js'; +import {getCss} from './graph_tab.css.js'; +import {getHtml} from './graph_tab.html.js'; -interface GraphTabElement { +export interface GraphTabElement { $: { toolTips: HTMLElement, graphBody: SVGElement, }; } -class GraphTabElement extends PolymerElement { +export class GraphTabElement extends CrLitElement { static get is() { return 'graph-tab'; } - static get template() { - return getTemplate(); + static override get styles() { + return getCss(); + } + + override render() { + return getHtml.bind(this)(); } private client_: GraphChangeStreamReceiver; @@ -43,7 +48,6 @@ private graph_: Graph|null = null; private resizeObserver_: ResizeObserver|null = null; - private debouncer_: Debouncer|null = null; override connectedCallback() { super.connectedCallback(); @@ -51,12 +55,9 @@ this.graph_.initialize(); // Set up a resize listener to track the graph on resize. this.resizeObserver_ = new ResizeObserver(() => { - this.debouncer_ = - Debouncer.debounce(this.debouncer_, timeOut.after(20), () => { - if (this.graph_) { - this.graph_.onResize(); - } - }); + if (this.graph_) { + this.graph_.onResize(); + } }); this.resizeObserver_.observe(this.$.graphBody); this.graphDump_ = GraphDump.getRemote(); @@ -78,7 +79,7 @@ } // Handle request for node descriptions from the Graph. - private onRequestNodeDescriptions_(event: CustomEvent<bigint[]>) { + protected onRequestNodeDescriptions_(event: CustomEvent<bigint[]>) { // Forward the request through the mojoms and bounce the reply back. this.graphDump_!.requestNodeDescriptions(event.detail) .then(
diff --git a/chrome/browser/resources/settings/autofill_page/pay_over_time_issuer_list_entry.html b/chrome/browser/resources/settings/autofill_page/pay_over_time_issuer_list_entry.html index f990fd0..aa4537e 100644 --- a/chrome/browser/resources/settings/autofill_page/pay_over_time_issuer_list_entry.html +++ b/chrome/browser/resources/settings/autofill_page/pay_over_time_issuer_list_entry.html
@@ -39,9 +39,9 @@ <if expr="_google_chrome"> <picture id="paymentsIcon"> <source - srcset="chrome://theme/IDR_AUTOFILL_GOOGLE_PAY_DARK_SMALL" + srcset="[[getScaledSrcSet_('chrome://theme/IDR_AUTOFILL_GOOGLE_PAY_DARK_SMALL')]]" media="(prefers-color-scheme: dark)"> - <img alt="" src="chrome://theme/IDR_AUTOFILL_GOOGLE_PAY_SMALL"> + <img alt="" srcset="[[getScaledSrcSet_('chrome://theme/IDR_AUTOFILL_GOOGLE_PAY_SMALL')]]"> </picture> </if> <if expr="not _google_chrome">
diff --git a/chrome/browser/resources/settings/autofill_page/pay_over_time_issuer_list_entry.ts b/chrome/browser/resources/settings/autofill_page/pay_over_time_issuer_list_entry.ts index 030d668..215c5b06 100644 --- a/chrome/browser/resources/settings/autofill_page/pay_over_time_issuer_list_entry.ts +++ b/chrome/browser/resources/settings/autofill_page/pay_over_time_issuer_list_entry.ts
@@ -43,10 +43,17 @@ * `imageSrc`. */ private getIssuerImage_(imageSrc: string): string { - if (imageSrc.startsWith('chrome://theme')) { - return `${imageSrc} 1x, ${imageSrc}@2x 2x`; - } - return imageSrc; + return imageSrc.startsWith('chrome://theme') ? + this.getScaledSrcSet_(imageSrc) : + imageSrc; + } + + /** + * This function returns a string that can be used in a srcset to scale + * the provided `url` based on the user's screen resolution. + */ + private getScaledSrcSet_(url: string): string { + return `${url} 1x, ${url}@2x 2x`; } private onRemoteEditClick_() {
diff --git a/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc b/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc index b051223e..4e89beb4 100644 --- a/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc +++ b/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc
@@ -634,14 +634,10 @@ segmentation_platform::kPriceChangeFreshness, segmentation_platform::processing::ProcessedValue::FromFloat(-1)); input_context->metadata_args.emplace( - segmentation_platform::kTabResumptionForAndroidHomeFreshness, - segmentation_platform::processing::ProcessedValue::FromFloat(-1)); - input_context->metadata_args.emplace( segmentation_platform::kSafetyHubFreshness, segmentation_platform::processing::ProcessedValue::FromFloat(-1)); - std::vector<std::string> result = {kPriceChange, kSingleTab, - kTabResumptionForAndroidHome, kSafetyHub}; + std::vector<std::string> result = {kPriceChange, kSingleTab, kSafetyHub}; ExpectGetClassificationResult( segmentation_platform::kAndroidHomeModuleRankerKey, prediction_options, input_context,
diff --git a/chrome/browser/tab_ui/android/BUILD.gn b/chrome/browser/tab_ui/android/BUILD.gn index dd337e88..5a2b3c65 100644 --- a/chrome/browser/tab_ui/android/BUILD.gn +++ b/chrome/browser/tab_ui/android/BUILD.gn
@@ -15,6 +15,7 @@ "java/src/org/chromium/chrome/browser/tab_ui/TabContentManagerThumbnailProvider.java", "java/src/org/chromium/chrome/browser/tab_ui/TabGridIphDialogCoordinator.java", "java/src/org/chromium/chrome/browser/tab_ui/TabListFaviconProvider.java", + "java/src/org/chromium/chrome/browser/tab_ui/TabModelDotInfo.java", "java/src/org/chromium/chrome/browser/tab_ui/TabSwitcher.java", "java/src/org/chromium/chrome/browser/tab_ui/TabSwitcherCustomViewManager.java", "java/src/org/chromium/chrome/browser/tab_ui/TabSwitcherIphController.java",
diff --git a/chrome/browser/tab_ui/android/java/src/org/chromium/chrome/browser/tab_ui/TabModelDotInfo.java b/chrome/browser/tab_ui/android/java/src/org/chromium/chrome/browser/tab_ui/TabModelDotInfo.java new file mode 100644 index 0000000..0eccdf4 --- /dev/null +++ b/chrome/browser/tab_ui/android/java/src/org/chromium/chrome/browser/tab_ui/TabModelDotInfo.java
@@ -0,0 +1,24 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.tab_ui; + +/** + * Simple data class that holds information to show or not show a notification dot for the whole tab + * model. + */ +public class TabModelDotInfo { + public static final TabModelDotInfo HIDE = new TabModelDotInfo(false, ""); + + public final boolean showDot; + + // When showDot is true, this field will hold the title of one of the tab groups that + // warranted the dot to show. + public final String tabGroupTitle; + + public TabModelDotInfo(boolean showDot, String tabGroupTitle) { + this.showDot = showDot; + this.tabGroupTitle = tabGroupTitle; + } +}
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupTitleUtils.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupTitleUtils.java index cb29000..b635f580 100644 --- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupTitleUtils.java +++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupTitleUtils.java
@@ -57,7 +57,7 @@ * @return A non-null string that can be shown to users. */ public static String getDisplayableTitle( - Context context, TabGroupModelFilter tabGroupModelFilter, Token tabGroupId) { + Context context, TabGroupModelFilter tabGroupModelFilter, @Nullable Token tabGroupId) { int rootId = tabGroupModelFilter.getRootIdFromTabGroupId(tabGroupId); @Nullable String explicitTitle = rootId == Tab.INVALID_TAB_ID ? null : tabGroupModelFilter.getTabGroupTitle(rootId);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index e72eefc..cae64ac 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -3601,6 +3601,10 @@ if (use_dbus) { sources += [ + "views/frame/dbus_appmenu.cc", + "views/frame/dbus_appmenu.h", + "views/frame/dbus_appmenu_registrar.cc", + "views/frame/dbus_appmenu_registrar.h", "views/status_icons/concat_menu_model.cc", "views/status_icons/concat_menu_model.h", "views/status_icons/status_icon_linux_dbus.cc", @@ -3608,19 +3612,6 @@ ] deps += [ "//components/dbus" ] } - - # TODO(crbug.com/40193891): ozone_platform_x11 should not be leaked outside - # ozone. - if (use_dbus && ozone_platform_x11) { - sources += [ - "views/frame/dbus_appmenu.cc", - "views/frame/dbus_appmenu.h", - "views/frame/dbus_appmenu_registrar.cc", - "views/frame/dbus_appmenu_registrar.h", - ] - defines += [ "USE_DBUS_MENU" ] - deps += [ "//ui/gfx/x" ] - } } # Device signals sharing currently only supports win, mac, linux and
diff --git a/chrome/browser/ui/android/edge_to_edge/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeUtils.java b/chrome/browser/ui/android/edge_to_edge/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeUtils.java index c625c538..8aa75aa 100644 --- a/chrome/browser/ui/android/edge_to_edge/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeUtils.java +++ b/chrome/browser/ui/android/edge_to_edge/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeUtils.java
@@ -142,7 +142,7 @@ && ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( ChromeFeatureList.EDGE_TO_EDGE_SAFE_AREA_CONSTRAINT, PARAM_SAFE_AREA_CONSTRAINT_SCROLLABLE_WHEN_STACKING, - false); + true); } /**
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 3d8f3bb..fa63e00 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -4156,6 +4156,9 @@ other {Restore tab group of <ph name="TAB_COUNT_MANY">%1$s<ex>5</ex></ph> tabs, color <ph name="COLOR_NAME">%2$s<ex>Blue</ex></ph>, as a new background tab group.} } </message> + <message name="IDS_TAB_GROUP_UPDATE_IPH_TEXT" desc="Text to describe that a blue dot on the tab switcher means there's tab group share activity."> + <ph name="TAB_GROUP_TITLE">%s<ex>Vacation</ex></ph> tab group has new activity + </message> <message name="IDS_WEB_FEED_AWARENESS" desc="Educating the user about the web feed."> Explore content to follow </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_TAB_GROUP_UPDATE_IPH_TEXT.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_TAB_GROUP_UPDATE_IPH_TEXT.png.sha1 new file mode 100644 index 0000000..8f0f379 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_TAB_GROUP_UPDATE_IPH_TEXT.png.sha1
@@ -0,0 +1 @@ +6734193e47fff323d0916bc068eb66854ab6002b \ No newline at end of file
diff --git a/chrome/browser/ui/android/tab_model/tab_model.h b/chrome/browser/ui/android/tab_model/tab_model.h index 29793de1..d7ad5de 100644 --- a/chrome/browser/ui/android/tab_model/tab_model.h +++ b/chrome/browser/ui/android/tab_model/tab_model.h
@@ -39,8 +39,11 @@ // with Android's Tabs and Tab Model. class TabModel { public: + // LINT.IfChange(TabLaunchType) // Various ways tabs can be launched. // Values must be numbered from 0 and can't have gaps. + // This enum is used to back a histogram, entries should not be renumbered or + // reused. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.tab enum class TabLaunchType { // Opened from a link. Sets up a relationship between the newly created tab @@ -135,6 +138,7 @@ // Must be last. SIZE }; + // LINT.ThenChange(//tools/metrics/histograms/metadata/new_tab_page/enums.xml:TabLaunchType) // Various ways tabs can be selected. // Values must be numbered from 0 and can't have gaps.
diff --git a/chrome/browser/ui/android/toolbar/BUILD.gn b/chrome/browser/ui/android/toolbar/BUILD.gn index 9f2f44d7..2492992 100644 --- a/chrome/browser/ui/android/toolbar/BUILD.gn +++ b/chrome/browser/ui/android/toolbar/BUILD.gn
@@ -148,6 +148,7 @@ "//chrome/browser/settings:java", "//chrome/browser/signin/services/android:java", "//chrome/browser/tab:java", + "//chrome/browser/tab_ui/android:java", "//chrome/browser/tabmodel:java", "//chrome/browser/ui/android/appmenu:java", "//chrome/browser/ui/android/desktop_windowing:java", @@ -370,6 +371,7 @@ "java/src/org/chromium/chrome/browser/toolbar/top/PhoneCaptureStateTokenTest.java", "java/src/org/chromium/chrome/browser/toolbar/top/TabletCaptureStateTokenTest.java", "java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonCoordinatorTest.java", + "java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonUnitTest.java", "java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java", "java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTabletUnitTest.java", "java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarOverlayMediatorTest.java", @@ -397,6 +399,7 @@ "//chrome/browser/settings:java", "//chrome/browser/signin/services/android:java", "//chrome/browser/tab:java", + "//chrome/browser/tab_ui/android:java", "//chrome/browser/tabmodel:java", "//chrome/browser/ui/android/appmenu:java", "//chrome/browser/ui/android/desktop_windowing:java",
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java index b8ceccd..51f2dc5 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java
@@ -17,11 +17,18 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.theme.ThemeUtils; import org.chromium.chrome.browser.toolbar.R; import org.chromium.chrome.browser.toolbar.TabSwitcherDrawable; import org.chromium.chrome.browser.toolbar.TabSwitcherDrawable.TabSwitcherDrawableLocation; import org.chromium.chrome.browser.ui.theme.BrandedColorScheme; +import org.chromium.chrome.browser.user_education.IphCommand; +import org.chromium.chrome.browser.user_education.IphCommandBuilder; +import org.chromium.chrome.browser.user_education.UserEducationHelper; +import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightParams; +import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightShape; +import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.ui.listmenu.ListMenuButton; /** @@ -31,11 +38,13 @@ */ public class ToggleTabStackButton extends ListMenuButton implements TabSwitcherDrawable.Observer { private final Callback<Integer> mTabCountSupplierObserver = this::onUpdateTabCount; - private final Callback<Boolean> mNotificationDotObserver = this::onUpdateNotificationDot; + private final Callback<TabModelDotInfo> mNotificationDotObserver = + this::onUpdateNotificationDot; private TabSwitcherDrawable mTabSwitcherButtonDrawable; private ObservableSupplier<Integer> mTabCountSupplier; - private ObservableSupplier<Boolean> mNotificationDotSupplier; + private ObservableSupplier<TabModelDotInfo> mNotificationDotSupplier; private Supplier<Boolean> mIsIncognitoSupplier; + private @Nullable UserEducationHelper mUserEducationHelper; public ToggleTabStackButton(Context context, @Nullable AttributeSet attrs) { super(context, attrs); @@ -78,12 +87,14 @@ * @param tabCountSupplier A supplier used to observe the number of tabs in the current model. * @param notificationDotSupplier A supplier used to observe whether to show the notification * dot. - * @param incognitoSupplier A supplier used to check for incongito state. + * @param isIncognitoSupplier A supplier used to check for incongito state. + * @param userEducationHelper Used to show an IPH. */ void setSuppliers( ObservableSupplier<Integer> tabCountSupplier, - ObservableSupplier<Boolean> notificationDotSupplier, - Supplier<Boolean> isIncognitoSupplier) { + ObservableSupplier<TabModelDotInfo> notificationDotSupplier, + Supplier<Boolean> isIncognitoSupplier, + UserEducationHelper userEducationHelper) { assert mTabCountSupplier == null : "setSuppliers should only be called once."; mTabCountSupplier = tabCountSupplier; @@ -93,6 +104,7 @@ notificationDotSupplier.addObserver(mNotificationDotObserver); mIsIncognitoSupplier = isIncognitoSupplier; + mUserEducationHelper = userEducationHelper; } @Override @@ -164,8 +176,23 @@ mTabSwitcherButtonDrawable.updateForTabCount(tabCount, mIsIncognitoSupplier.get()); } - private void onUpdateNotificationDot(boolean showDot) { - mTabSwitcherButtonDrawable.setNotificationIconStatus(showDot); + private void onUpdateNotificationDot(TabModelDotInfo tabModelDotInfo) { + mTabSwitcherButtonDrawable.setNotificationIconStatus(tabModelDotInfo.showDot); + if (tabModelDotInfo.showDot && mUserEducationHelper != null) { + String tabGroupTitle = tabModelDotInfo.tabGroupTitle; + String contentString = + getResources().getString(R.string.tab_group_update_iph_text, tabGroupTitle); + IphCommand iphCommand = + new IphCommandBuilder( + getResources(), + FeatureConstants.TAB_GROUP_SHARE_UPDATE_FEATURE, + contentString, + contentString) + .setAnchorView(this) + .setHighlightParams(new HighlightParams(HighlightShape.CIRCLE)) + .build(); + mUserEducationHelper.requestShowIph(iphCommand); + } } /** Returns whether the button should show a notification icon. */
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonCoordinator.java index 1979f1a3..38c5463e 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonCoordinator.java
@@ -28,6 +28,7 @@ import org.chromium.chrome.browser.tab.CurrentTabObserver; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.toolbar.R; import org.chromium.chrome.browser.toolbar.TabSwitcherDrawable; @@ -125,13 +126,16 @@ OnLongClickListener onLongClickListener, ObservableSupplier<Integer> tabCountSupplier, @Nullable ObservableSupplier<Integer> archivedTabCountSupplier, - ObservableSupplier<Boolean> tabModelNotificationDotSupplier, + ObservableSupplier<TabModelDotInfo> tabModelNotificationDotSupplier, @NonNull Runnable archivedTabsIphShownCallback, @NonNull Runnable archivedTabsIphDismissedCallback) { mToggleTabStackButton.setOnClickListener(onClickListener); mToggleTabStackButton.setOnLongClickListener(onLongClickListener); mToggleTabStackButton.setSuppliers( - tabCountSupplier, tabModelNotificationDotSupplier, mIsIncognitoSupplier); + tabCountSupplier, + tabModelNotificationDotSupplier, + mIsIncognitoSupplier, + mUserEducationHelper); mArchivedTabCountSupplier = archivedTabCountSupplier; if (mArchivedTabCountSupplier != null) {
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonCoordinatorTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonCoordinatorTest.java index bb1e725..8981b28 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonCoordinatorTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonCoordinatorTest.java
@@ -29,12 +29,12 @@ import org.mockito.junit.MockitoRule; import org.robolectric.annotation.LooperMode; -import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.layouts.LayoutType; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.toolbar.R; @@ -46,7 +46,7 @@ import java.util.HashSet; import java.util.Set; -/** Unit tests for ToggleTabStackButtonCoordinator. */ +/** Unit tests for {@link ToggleTabStackButtonCoordinator}. */ @RunWith(BaseRobolectricTestRunner.class) @LooperMode(LooperMode.Mode.LEGACY) public class ToggleTabStackButtonCoordinatorTest { @@ -65,8 +65,8 @@ @Captor private ArgumentCaptor<IphCommand> mIphCommandCaptor; - private final ObservableSupplierImpl<Boolean> mNotificationDotSupplier = - new ObservableSupplierImpl<>(false); + private final ObservableSupplierImpl<TabModelDotInfo> mNotificationDotSupplier = + new ObservableSupplierImpl<>(TabModelDotInfo.HIDE); private final OneshotSupplierImpl<Boolean> mPromoShownOneshotSupplier = new OneshotSupplierImpl<>(); @@ -74,8 +74,6 @@ private boolean mOverviewOpen; private Set<LayoutStateProvider.LayoutStateObserver> mLayoutStateObserverSet; private OneshotSupplierImpl<LayoutStateProvider> mLayoutSateProviderOneshotSupplier; - private ObservableSupplier<Integer> mTabCountSupplier; - private ObservableSupplierImpl<Integer> mArchivedTabCountSupplier; private ToggleTabStackButtonCoordinator mCoordinator; private ObservableSupplierImpl<TabModelSelector> mTabModelSelectorSupplier; @@ -129,11 +127,12 @@ mLayoutSateProviderOneshotSupplier, new ObservableSupplierImpl<>(), mTabModelSelectorSupplier); + coordinator.initializeWithNative( mOnClickListener, mOnLongClickListener, - mTabCountSupplier, - mArchivedTabCountSupplier, + /* tabCountSupplier= */ null, + /* archivedTabCountSupplier= */ null, mNotificationDotSupplier, () -> {}, () -> {});
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonUnitTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonUnitTest.java new file mode 100644 index 0000000..703a3a8 --- /dev/null +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonUnitTest.java
@@ -0,0 +1,81 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.toolbar.top; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.verify; + +import android.app.Activity; + +import androidx.test.ext.junit.rules.ActivityScenarioRule; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.shadows.ShadowLooper; + +import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.base.supplier.Supplier; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.Features.EnableFeatures; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.tab_ui.TabModelDotInfo; +import org.chromium.chrome.browser.toolbar.R; +import org.chromium.chrome.browser.user_education.IphCommand; +import org.chromium.chrome.browser.user_education.UserEducationHelper; +import org.chromium.ui.base.TestActivity; + +/** Unit tests for {@link ToggleTabStackButton}. */ +@RunWith(BaseRobolectricTestRunner.class) +@EnableFeatures(ChromeFeatureList.DATA_SHARING) +public class ToggleTabStackButtonUnitTest { + + @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + + @Rule + public final ActivityScenarioRule<TestActivity> mActivityScenarioRule = + new ActivityScenarioRule<>(TestActivity.class); + + private final ObservableSupplierImpl<Integer> mTabCountSupplier = + new ObservableSupplierImpl<>(0); + private final ObservableSupplierImpl<TabModelDotInfo> mTabModelDotInfoSupplier = + new ObservableSupplierImpl<>(TabModelDotInfo.HIDE); + private final Supplier<Boolean> mIsIncognitoSupplier = () -> false; + + @Mock private UserEducationHelper mUserEducationHelper; + @Captor private ArgumentCaptor<IphCommand> mIphCommandCaptor; + + private Activity mActivity; + private ToggleTabStackButton mToggleTabStackButton; + + @Before + public void setUp() { + mActivityScenarioRule.getScenario().onActivity(activity -> mActivity = activity); + mActivity.setTheme(R.style.Theme_BrowserUI_DayNight); + mToggleTabStackButton = new ToggleTabStackButton(mActivity, null); + mToggleTabStackButton.onFinishInflate(); + } + + @Test + public void testTabModelDotInfoIph() { + mToggleTabStackButton.setSuppliers( + mTabCountSupplier, + mTabModelDotInfoSupplier, + mIsIncognitoSupplier, + mUserEducationHelper); + ShadowLooper.idleMainLooper(); + + String groupTitle = "Vacation"; + mTabModelDotInfoSupplier.set(new TabModelDotInfo(true, groupTitle)); + verify(mUserEducationHelper).requestShowIph(mIphCommandCaptor.capture()); + assertTrue(mIphCommandCaptor.getValue().contentString.contains(groupTitle)); + } +}
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index 448cf2d..9f4d105 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -81,7 +81,6 @@ import org.chromium.chrome.browser.user_education.UserEducationHelper; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.browser_ui.styles.SemanticColorUtils; -import org.chromium.components.browser_ui.util.KeyboardNavigationListener; import org.chromium.components.browser_ui.widget.animation.CancelAwareAnimatorListener; import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.components.feature_engagement.EventConstants; @@ -91,6 +90,7 @@ import org.chromium.ui.base.ViewUtils; import org.chromium.ui.interpolators.Interpolators; import org.chromium.ui.util.ColorUtils; +import org.chromium.ui.util.KeyboardNavigationListener; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.cc index 787c26a9..d6eef87ae 100644 --- a/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.cc +++ b/chrome/browser/ui/ash/shelf/app_service/app_service_shelf_context_menu.cc
@@ -247,7 +247,7 @@ const bool scaled = command_id == ash::CROSTINI_USE_LOW_DENSITY; registry_service->SetAppScaled(item().id.app_id, scaled); if (controller()->IsOpen(item().id)) { - crostini::ShowAppRestartDialog(display_id()); + crostini::AppRestartDialog::Show(display_id()); } return; }
diff --git a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc index 64d690a5..6f7c019 100644 --- a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc +++ b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc
@@ -34,7 +34,6 @@ #include "components/autofill/core/browser/metrics/payments/risk_data_metrics.h" #include "components/autofill/core/browser/payments/autofill_error_dialog_context.h" #include "components/autofill/core/browser/payments/autofill_offer_manager.h" -#include "components/autofill/core/browser/payments/bnpl_manager.h" #include "components/autofill/core/browser/payments/card_unmask_challenge_option.h" #include "components/autofill/core/browser/payments/credit_card_cvc_authenticator.h" #include "components/autofill/core/browser/payments/credit_card_otp_authenticator.h" @@ -931,14 +930,6 @@ return payments_mandatory_reauth_manager_.get(); } -payments::BnplManager* ChromePaymentsAutofillClient::GetPaymentsBnplManager() { - if (!bnpl_manager_) { - bnpl_manager_ = std::make_unique<payments::BnplManager>(&client_.get()); - } - - return bnpl_manager_.get(); -} - PaymentsDataManager& ChromePaymentsAutofillClient::GetPaymentsDataManager() { return client_->GetPersonalDataManager().payments_data_manager(); }
diff --git a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h index 5c141f6..af240b0 100644 --- a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h +++ b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h
@@ -71,7 +71,6 @@ namespace payments { struct BnplIssuerContext; -class BnplManager; class MandatoryReauthManager; class PaymentsWindowManager; class SelectBnplIssuerDialogControllerImpl; @@ -205,7 +204,6 @@ CreateCreditCardInternalAuthenticator(AutofillDriver* driver) override; payments::MandatoryReauthManager* GetOrCreatePaymentsMandatoryReauthManager() override; - payments::BnplManager* GetPaymentsBnplManager() override; PaymentsDataManager& GetPaymentsDataManager() final; void ShowCreditCardSaveAndFillDialog() override; void ShowSelectBnplIssuerDialog( @@ -327,8 +325,6 @@ std::unique_ptr<payments::MandatoryReauthManager> payments_mandatory_reauth_manager_; - std::unique_ptr<payments::BnplManager> bnpl_manager_; - std::unique_ptr<SaveAndFillDialogControllerImpl> save_and_fill_dialog_controller_;
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 81b14e0..899c109 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -1524,7 +1524,7 @@ command_updater_.UpdateCommandEnabled( IDC_GLIC_TOGGLE_PIN, glic::GlicEnabling::IsProfileEligible(profile())); command_updater_.UpdateCommandEnabled( - IDC_OPEN_GLIC, glic::GlicEnabling::IsProfileEligible(profile())); + IDC_OPEN_GLIC, glic::GlicEnabling::IsEnabledForProfile(profile())); command_updater_.UpdateCommandEnabled( IDC_GLIC_TOGGLE_FOCUS, glic::GlicEnabling::IsProfileEligible(profile())); #endif
diff --git a/chrome/browser/ui/browser_command_controller_browsertest.cc b/chrome/browser/ui/browser_command_controller_browsertest.cc index d936719..4eaa5c54 100644 --- a/chrome/browser/ui/browser_command_controller_browsertest.cc +++ b/chrome/browser/ui/browser_command_controller_browsertest.cc
@@ -663,6 +663,11 @@ BrowserCommandControllerBrowserTest::SetUp(); } + void SetUpCommandLine(base::CommandLine* command_line) override { + // Bypass glic eligibility check. + base::CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kGlicDev); + } + private: base::test::ScopedFeatureList scoped_feature_list_; }; @@ -730,9 +735,11 @@ IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTestGlic, ExecuteGlicThreeDotMenuItem) { // Bypass glic eligibility check. - base::CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kGlicDev); - // Bypass fre. PrefService* profile_prefs = browser()->profile()->GetPrefs(); + profile_prefs->SetInteger( + ::prefs::kGeminiSettings, + static_cast<int>(glic::prefs::SettingsPolicyState::kEnabled)); + // Bypass fre. profile_prefs->SetInteger(glic::prefs::kGlicCompletedFre, static_cast<int>(glic::prefs::FreStatus::kCompleted));
diff --git a/chrome/browser/ui/lens/lens_overlay_query_controller.cc b/chrome/browser/ui/lens/lens_overlay_query_controller.cc index 20f256d7..e2b57bc 100644 --- a/chrome/browser/ui/lens/lens_overlay_query_controller.cc +++ b/chrome/browser/ui/lens/lens_overlay_query_controller.cc
@@ -446,6 +446,7 @@ payload.mutable_stored_chunk_options()->set_read_stored_chunks(true); payload.mutable_stored_chunk_options()->set_total_stored_chunks( total_stored_chunks); + payload.set_compression_type(lens::CompressionType::ZSTD); return payload; }
diff --git a/chrome/browser/ui/lens/lens_overlay_query_controller_unittest.cc b/chrome/browser/ui/lens/lens_overlay_query_controller_unittest.cc index 2509518..fe0eb54 100644 --- a/chrome/browser/ui/lens/lens_overlay_query_controller_unittest.cc +++ b/chrome/browser/ui/lens/lens_overlay_query_controller_unittest.cc
@@ -3656,6 +3656,8 @@ .stored_chunk_options() .read_stored_chunks()); EXPECT_EQ(1, query_controller.num_upload_chunk_requests_sent()); + ASSERT_EQ(page_content_request.payload().compression_type(), + lens::CompressionType::ZSTD); // Check interaction request is correct. auto sent_interaction_request = query_controller.sent_interaction_request(); @@ -3801,6 +3803,8 @@ .stored_chunk_options() .read_stored_chunks()); EXPECT_EQ(1, query_controller.num_upload_chunk_requests_sent()); + ASSERT_EQ(page_content_request.payload().compression_type(), + lens::CompressionType::ZSTD); // Check interaction request is correct. auto sent_interaction_request = query_controller.sent_interaction_request();
diff --git a/chrome/browser/ui/views/autofill/edit_address_profile_view.cc b/chrome/browser/ui/views/autofill/edit_address_profile_view.cc index 4213a9b..a521335 100644 --- a/chrome/browser/ui/views/autofill/edit_address_profile_view.cc +++ b/chrome/browser/ui/views/autofill/edit_address_profile_view.cc
@@ -97,9 +97,8 @@ : controller_(controller) { DCHECK(controller); - // TODO(crbug.com/338254375): Remove the following two lines once this is the - // default state for widgets and the delegates. - SetOwnedByWidget(false); + // TODO(crbug.com/338254375): Remove the following line once this is the + // default state for widgets. SetOwnershipOfNewWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET); SetButtons(static_cast<int>(ui::mojom::DialogButton::kOk) |
diff --git a/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.cc b/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.cc index 96ff15e..ee7bf82 100644 --- a/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.cc +++ b/chrome/browser/ui/views/autofill/payments/autofill_progress_dialog_views.cc
@@ -127,9 +127,8 @@ : controller_(controller) { // Set the ownership of the delegate, not the View. The View is owned by the // Widget as a child view. - // TODO(crbug.com/338254375): Remove the following two lines once this is the - // default state for widgets and the delegates. - SetOwnedByWidget(false); + // TODO(crbug.com/338254375): Remove the following line once this is the + // default state for widgets. SetOwnershipOfNewWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET); SetButtons(static_cast<int>(ui::mojom::DialogButton::kCancel));
diff --git a/chrome/browser/ui/views/autofill/payments/bnpl_tos_dialog.cc b/chrome/browser/ui/views/autofill/payments/bnpl_tos_dialog.cc index b5c043b06..c6edddff 100644 --- a/chrome/browser/ui/views/autofill/payments/bnpl_tos_dialog.cc +++ b/chrome/browser/ui/views/autofill/payments/bnpl_tos_dialog.cc
@@ -32,9 +32,8 @@ : controller_(controller), link_opener_(link_opener) { // Set the ownership of the delegate, not the View. The View is owned by the // Widget as a child view. - // TODO(crbug.com/338254375): Remove the following two lines once this is the - // default state for widgets and the delegates. - SetOwnedByWidget(/*delete_self=*/false); + // TODO(crbug.com/338254375): Remove the following line once this is the + // default state for widgets. SetOwnershipOfNewWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET); SetAcceptCallbackWithClose( base::BindRepeating(&BnplTosDialog::OnAccepted, base::Unretained(this)));
diff --git a/chrome/browser/ui/views/autofill/payments/select_bnpl_issuer_dialog.cc b/chrome/browser/ui/views/autofill/payments/select_bnpl_issuer_dialog.cc index 9b9232e..f85bd74 100644 --- a/chrome/browser/ui/views/autofill/payments/select_bnpl_issuer_dialog.cc +++ b/chrome/browser/ui/views/autofill/payments/select_bnpl_issuer_dialog.cc
@@ -83,9 +83,8 @@ : controller_(controller), web_contents_(web_contents->GetWeakPtr()) { // Set the ownership of the delegate, not the View. The View is owned by the // Widget as a child view. - // TODO(crbug.com/338254375): Remove the following two lines once this is the - // default state for widgets and the delegates. - views::WidgetDelegate::SetOwnedByWidget(false); + // TODO(crbug.com/338254375): Remove the following line once this is the + // default state for widgets. SetOwnershipOfNewWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET); // TODO(crbug.com/363332740): Initialize the UI.
diff --git a/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_bubble_views.cc b/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_bubble_views.cc index 506804f..00c3ed6a 100644 --- a/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/payments/virtual_card_enroll_bubble_views.cc
@@ -187,26 +187,56 @@ views::BoxLayout::Orientation::kVertical); card_identifier_view->SetCrossAxisAlignment( views::BoxLayout::CrossAxisAlignment::kStart); - auto* card_name_4digits_view = card_identifier_view->AddChildView( - std::make_unique<views::BoxLayoutView>()); - card_name_4digits_view->SetOrientation( - views::BoxLayout::Orientation::kHorizontal); - card_name_4digits_view->SetBetweenChildSpacing( - provider->GetDistanceMetric(DISTANCE_RELATED_LABEL_HORIZONTAL_LIST)); - auto* card_name_label = - card_name_4digits_view->AddChildView(std::make_unique<views::Label>( - card.CardNameForAutofillDisplay(), - views::style::CONTEXT_DIALOG_BODY_TEXT, views::style::STYLE_PRIMARY)); - card_name_label->SetHorizontalAlignment( - gfx::HorizontalAlignment::ALIGN_TO_HEAD); - card_name_4digits_view->SetFlexForView(card_name_label, /*flex=*/1); - card_name_4digits_view->AddChildView(std::make_unique<views::Label>( - card.ObfuscatedNumberWithVisibleLastFourDigits(), - views::style::CONTEXT_DIALOG_BODY_TEXT, views::style::STYLE_PRIMARY)); - card_identifier_view->AddChildView(std::make_unique<views::Label>( - l10n_util::GetStringUTF16(IDS_AUTOFILL_VIRTUAL_CARD_ENTRY_PREFIX), - ChromeTextContext::CONTEXT_DIALOG_BODY_TEXT_SMALL, - views::style::STYLE_SECONDARY)); + if (base::FeatureList::IsEnabled( + features::kAutofillEnableNewFopDisplayDesktop)) { + std::optional<std::u16string> card_identifier = + card.CardIdentifierForAutofillDisplay(); + // Add the card identifier/nickname as the primary label, if it exists. + if (card_identifier.has_value()) { + card_identifier_view->AddChildView(std::make_unique<views::Label>( + *card_identifier, views::style::CONTEXT_DIALOG_BODY_TEXT, + views::style::STYLE_PRIMARY)); + } + views::style::TextStyle stype = card_identifier.has_value() + ? views::style::STYLE_SECONDARY + : views::style::STYLE_PRIMARY; + // Add the network and last 4 digits: on a second line if a card identifier + // exists, or as the primary label (and on the first line) otherwise. + auto* network_and_4digits_view = card_identifier_view->AddChildView( + std::make_unique<views::BoxLayoutView>()); + network_and_4digits_view->SetOrientation( + views::BoxLayout::Orientation::kHorizontal); + network_and_4digits_view->SetBetweenChildSpacing( + provider->GetDistanceMetric(DISTANCE_RELATED_LABEL_HORIZONTAL_LIST)); + network_and_4digits_view->AddChildView(std::make_unique<views::Label>( + card.NetworkAndLastFourDigits( + /*obfuscation_length=*/2), + views::style::CONTEXT_DIALOG_BODY_TEXT, stype)); + network_and_4digits_view->AddChildView(std::make_unique<views::Label>( + l10n_util::GetStringUTF16(IDS_AUTOFILL_VIRTUAL_CARD_ENTRY_PREFIX), + views::style::CONTEXT_DIALOG_BODY_TEXT, stype)); + } else { + auto* card_name_4digits_view = card_identifier_view->AddChildView( + std::make_unique<views::BoxLayoutView>()); + card_name_4digits_view->SetOrientation( + views::BoxLayout::Orientation::kHorizontal); + card_name_4digits_view->SetBetweenChildSpacing( + provider->GetDistanceMetric(DISTANCE_RELATED_LABEL_HORIZONTAL_LIST)); + auto* card_name_label = card_name_4digits_view->AddChildView( + std::make_unique<views::Label>(card.CardNameForAutofillDisplay(), + views::style::CONTEXT_DIALOG_BODY_TEXT, + views::style::STYLE_PRIMARY)); + card_name_label->SetHorizontalAlignment( + gfx::HorizontalAlignment::ALIGN_TO_HEAD); + card_name_4digits_view->SetFlexForView(card_name_label, /*flex=*/1); + card_name_4digits_view->AddChildView(std::make_unique<views::Label>( + card.ObfuscatedNumberWithVisibleLastFourDigits(), + views::style::CONTEXT_DIALOG_BODY_TEXT, views::style::STYLE_PRIMARY)); + card_identifier_view->AddChildView(std::make_unique<views::Label>( + l10n_util::GetStringUTF16(IDS_AUTOFILL_VIRTUAL_CARD_ENTRY_PREFIX), + ChromeTextContext::CONTEXT_DIALOG_BODY_TEXT_SMALL, + views::style::STYLE_SECONDARY)); + } AddChildView(CreateLegalMessageView()) ->SetID(DialogViewId::LEGAL_MESSAGE_VIEW);
diff --git a/chrome/browser/ui/views/borealis/borealis_disallowed_dialog.cc b/chrome/browser/ui/views/borealis/borealis_disallowed_dialog.cc index c728122..06e6bda 100644 --- a/chrome/browser/ui/views/borealis/borealis_disallowed_dialog.cc +++ b/chrome/browser/ui/views/borealis/borealis_disallowed_dialog.cc
@@ -41,8 +41,6 @@ namespace { -using AllowStatus = ::borealis::BorealisFeatures::AllowStatus; - using MaybeAction = std::optional<std::pair<std::u16string, base::OnceClosure>>; // Views uses tricks like this to ensure singleton-ness of dialogs. @@ -62,6 +60,88 @@ } }; +} // namespace + +class BorealisDisallowedDialog : public DialogDelegate { + public: + BorealisDisallowedDialog(std::unique_ptr<BehaviourProvider> behaviour, + int title_id) { + DCHECK(!g_instance_); + + SetTitle(IDS_BOREALIS_INSTALLER_APP_NAME); + set_internal_name("BorealisDisallowedDialog"); + MaybeAction second_action = behaviour->GetAction(); + if (second_action.has_value()) { + SetButtons(static_cast<int>(ui::mojom::DialogButton::kOk) | + static_cast<int>(ui::mojom::DialogButton::kCancel)); + SetButtonLabel(ui::mojom::DialogButton::kCancel, + l10n_util::GetStringUTF16(IDS_CLOSE)); + SetButtonLabel(ui::mojom::DialogButton::kOk, + std::move(second_action.value().first)); + SetAcceptCallback(std::move(second_action.value().second)); + } else { + SetButtons(static_cast<int>(ui::mojom::DialogButton::kOk)); + SetButtonLabel(ui::mojom::DialogButton::kOk, + l10n_util::GetStringUTF16(IDS_CLOSE)); + } + InitializeView(*behaviour, title_id); + SetModalType(ui::mojom::ModalType::kSystem); + SetOwnedByWidget(true); + SetShowCloseButton(false); + set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( + views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH)); + } + + ~BorealisDisallowedDialog() override { + DCHECK(g_instance_); + g_instance_ = nullptr; + } + + bool ShouldShowWindowTitle() const override { return false; } + + private: + void InitializeView(const BehaviourProvider& behaviour, int title_id) { + auto view = std::make_unique<views::View>(); + + views::LayoutProvider* provider = views::LayoutProvider::Get(); + view->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical, + provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG), + provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); + + views::Label* title_label = new views::Label( + l10n_util::GetStringUTF16(title_id), CONTEXT_IPH_BUBBLE_TITLE, + views::style::STYLE_EMPHASIZED); + title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + title_label->SetMultiLine(true); + view->AddChildViewRaw(title_label); + + views::Label* message_label = new views::Label(behaviour.GetMessage()); + message_label->SetMultiLine(true); + message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + view->AddChildViewRaw(message_label); + + for (const std::pair<std::u16string, GURL>& link : behaviour.GetLinks()) { + views::Link* link_label = + view->AddChildView(std::make_unique<views::Link>(link.first)); + link_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + link_label->SetCallback(base::BindRepeating( + [](GURL url) { + ash::NewWindowDelegate::GetPrimary()->OpenUrl( + url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction, + ash::NewWindowDelegate::Disposition::kNewForegroundTab); + }, + link.second)); + } + + SetContentsView(std::move(view)); + } +}; + +namespace { + +using AllowStatus = ::borealis::BorealisFeatures::AllowStatus; + class DisallowedHardware : public BehaviourProvider { public: std::u16string GetMessage() const override { @@ -143,82 +223,6 @@ } }; -class BorealisDisallowedDialog : public DialogDelegate { - public: - BorealisDisallowedDialog(std::unique_ptr<BehaviourProvider> behaviour, - int title_id) { - DCHECK(!g_instance_); - - SetTitle(IDS_BOREALIS_INSTALLER_APP_NAME); - set_internal_name("BorealisDisallowedDialog"); - MaybeAction second_action = behaviour->GetAction(); - if (second_action.has_value()) { - SetButtons(static_cast<int>(ui::mojom::DialogButton::kOk) | - static_cast<int>(ui::mojom::DialogButton::kCancel)); - SetButtonLabel(ui::mojom::DialogButton::kCancel, - l10n_util::GetStringUTF16(IDS_CLOSE)); - SetButtonLabel(ui::mojom::DialogButton::kOk, - std::move(second_action.value().first)); - SetAcceptCallback(std::move(second_action.value().second)); - } else { - SetButtons(static_cast<int>(ui::mojom::DialogButton::kOk)); - SetButtonLabel(ui::mojom::DialogButton::kOk, - l10n_util::GetStringUTF16(IDS_CLOSE)); - } - InitializeView(*behaviour, title_id); - SetModalType(ui::mojom::ModalType::kSystem); - SetOwnedByWidget(true); - SetShowCloseButton(false); - set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( - views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH)); - } - - ~BorealisDisallowedDialog() override { - DCHECK(g_instance_); - g_instance_ = nullptr; - } - - bool ShouldShowWindowTitle() const override { return false; } - - private: - void InitializeView(const BehaviourProvider& behaviour, int title_id) { - auto view = std::make_unique<views::View>(); - - views::LayoutProvider* provider = views::LayoutProvider::Get(); - view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, - provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG), - provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); - - views::Label* title_label = new views::Label( - l10n_util::GetStringUTF16(title_id), CONTEXT_IPH_BUBBLE_TITLE, - views::style::STYLE_EMPHASIZED); - title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - title_label->SetMultiLine(true); - view->AddChildViewRaw(title_label); - - views::Label* message_label = new views::Label(behaviour.GetMessage()); - message_label->SetMultiLine(true); - message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - view->AddChildViewRaw(message_label); - - for (const std::pair<std::u16string, GURL>& link : behaviour.GetLinks()) { - views::Link* link_label = - view->AddChildView(std::make_unique<views::Link>(link.first)); - link_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - link_label->SetCallback(base::BindRepeating( - [](GURL url) { - ash::NewWindowDelegate::GetPrimary()->OpenUrl( - url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction, - ash::NewWindowDelegate::Disposition::kNewForegroundTab); - }, - link.second)); - } - - SetContentsView(std::move(view)); - } -}; - std::unique_ptr<BehaviourProvider> StatusBehaviour(AllowStatus status) { switch (status) { case AllowStatus::kAllowed:
diff --git a/chrome/browser/ui/views/borealis/borealis_launch_error_dialog.cc b/chrome/browser/ui/views/borealis/borealis_launch_error_dialog.cc index be1b9da7..272708da 100644 --- a/chrome/browser/ui/views/borealis/borealis_launch_error_dialog.cc +++ b/chrome/browser/ui/views/borealis/borealis_launch_error_dialog.cc
@@ -40,6 +40,8 @@ // Views uses tricks like this to ensure singleton-ness of dialogs. static Widget* g_instance_ = nullptr; +} // namespace + class BorealisLaunchErrorDialog : public DialogDelegate { public: explicit BorealisLaunchErrorDialog(Profile* profile, @@ -215,7 +217,6 @@ FailureType failure_; raw_ptr<views::Checkbox> feedback_checkbox_ = nullptr; }; -} // namespace void ShowBorealisLaunchErrorView(Profile* profile, BorealisStartupResult error) {
diff --git a/chrome/browser/ui/views/crostini/crostini_app_restart_dialog.cc b/chrome/browser/ui/views/crostini/crostini_app_restart_dialog.cc index 45653a88..7df7047 100644 --- a/chrome/browser/ui/views/crostini/crostini_app_restart_dialog.cc +++ b/chrome/browser/ui/views/crostini/crostini_app_restart_dialog.cc
@@ -26,7 +26,29 @@ return screen->GetWindowAtScreenPoint(display.bounds().origin()); } -std::unique_ptr<views::View> MakeCrostiniAppRestartView() { +} // namespace + +// static +void AppRestartDialog::Show(int64_t display_id) { + ShowInternal(GetNativeWindowFromDisplayId(display_id)); +} + +// static +void AppRestartDialog::ShowForTesting(gfx::NativeWindow context) { + ShowInternal(context); +} + +// static +void AppRestartDialog::ShowInternal(gfx::NativeWindow context) { + auto contents = MakeCrostiniAppRestartView(); + auto delegate = MakeCrostiniAppRestartDelegate(std::move(contents)); + views::DialogDelegate::CreateDialogWidget(std::move(delegate), context, + nullptr) + ->Show(); +} + +// static +std::unique_ptr<views::View> AppRestartDialog::MakeCrostiniAppRestartView() { auto view = std::make_unique<views::View>(); views::LayoutProvider* provider = views::LayoutProvider::Get(); @@ -45,7 +67,9 @@ return view; } -std::unique_ptr<views::DialogDelegate> MakeCrostiniAppRestartDelegate( +// static +std::unique_ptr<views::DialogDelegate> +AppRestartDialog::MakeCrostiniAppRestartDelegate( std::unique_ptr<views::View> contents) { auto delegate = std::make_unique<views::DialogDelegate>(); delegate->set_internal_name("CrostiniAppRestart"); @@ -60,22 +84,4 @@ return delegate; } -void ShowInternal(gfx::NativeWindow context) { - auto contents = MakeCrostiniAppRestartView(); - auto delegate = MakeCrostiniAppRestartDelegate(std::move(contents)); - views::DialogDelegate::CreateDialogWidget(std::move(delegate), context, - nullptr) - ->Show(); -} - -} // namespace - -void ShowAppRestartDialog(int64_t display_id) { - ShowInternal(GetNativeWindowFromDisplayId(display_id)); -} - -void ShowAppRestartDialogForTesting(gfx::NativeWindow context) { - ShowInternal(context); -} - } // namespace crostini
diff --git a/chrome/browser/ui/views/crostini/crostini_app_restart_dialog.h b/chrome/browser/ui/views/crostini/crostini_app_restart_dialog.h index 85afa6d0..39e8d337 100644 --- a/chrome/browser/ui/views/crostini/crostini_app_restart_dialog.h +++ b/chrome/browser/ui/views/crostini/crostini_app_restart_dialog.h
@@ -5,12 +5,28 @@ #ifndef CHROME_BROWSER_UI_VIEWS_CROSTINI_CROSTINI_APP_RESTART_DIALOG_H_ #define CHROME_BROWSER_UI_VIEWS_CROSTINI_CROSTINI_APP_RESTART_DIALOG_H_ +#include <memory> + #include "ui/gfx/native_widget_types.h" +namespace views { +class DialogDelegate; +class View; +} // namespace views + namespace crostini { -void ShowAppRestartDialog(int64_t display_id); -void ShowAppRestartDialogForTesting(gfx::NativeWindow context); +class AppRestartDialog { + public: + static void Show(int64_t display_id); + static void ShowForTesting(gfx::NativeWindow context); + + private: + static void ShowInternal(gfx::NativeWindow context); + static std::unique_ptr<views::View> MakeCrostiniAppRestartView(); + static std::unique_ptr<views::DialogDelegate> MakeCrostiniAppRestartDelegate( + std::unique_ptr<views::View> contents); +}; } // namespace crostini
diff --git a/chrome/browser/ui/views/crostini/crostini_app_restart_dialog_unittest.cc b/chrome/browser/ui/views/crostini/crostini_app_restart_dialog_unittest.cc index 14057fa..7535d053 100644 --- a/chrome/browser/ui/views/crostini/crostini_app_restart_dialog_unittest.cc +++ b/chrome/browser/ui/views/crostini/crostini_app_restart_dialog_unittest.cc
@@ -20,7 +20,7 @@ views::test::WidgetTest::WidgetAutoclosePtr ShowDialog() { views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{}, "CrostiniAppRestart"); - crostini::ShowAppRestartDialogForTesting(GetContext()); + crostini::AppRestartDialog::ShowForTesting(GetContext()); return views::test::WidgetTest::WidgetAutoclosePtr( waiter.WaitIfNeededAndGet()); }
diff --git a/chrome/browser/ui/views/default_link_capturing_interactive_uitest.cc b/chrome/browser/ui/views/default_link_capturing_interactive_uitest.cc index 839cd01..a6813bf9 100644 --- a/chrome/browser/ui/views/default_link_capturing_interactive_uitest.cc +++ b/chrome/browser/ui/views/default_link_capturing_interactive_uitest.cc
@@ -12,6 +12,8 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/intent_picker_tab_helper.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/web_apps/web_app_link_capturing_test_utils.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" @@ -38,6 +40,27 @@ #include "ui/views/test/button_test_api.h" #include "ui/views/widget/any_widget_observer.h" +namespace { + +// Helper function to generate test names for IntentChipButton tests. +std::string GenerateIntentChipTestName( + const testing::TestParamInfo< + std::tuple<apps::test::LinkCapturingFeatureVersion, bool>>& + param_info) { + std::string test_name; + test_name.append(apps::test::ToString( + std::get<apps::test::LinkCapturingFeatureVersion>(param_info.param))); + test_name.append("_"); + if (std::get<bool>(param_info.param)) { + test_name.append("page_action_on"); + } else { + test_name.append("page_action_off"); + } + return test_name; +} + +} // namespace + #if BUILDFLAG(IS_MAC) #include "chrome/browser/apps/link_capturing/mac_intent_picker_helpers.h" #endif // BUILDFLAG(IS_MAC) @@ -48,11 +71,20 @@ class DefaultLinkCapturingInteractiveUiTest : public web_app::WebAppNavigationBrowserTest, public testing::WithParamInterface< - apps::test::LinkCapturingFeatureVersion> { + std::tuple<apps::test::LinkCapturingFeatureVersion, bool>> { public: DefaultLinkCapturingInteractiveUiTest() { - scoped_feature_list_.InitWithFeaturesAndParameters( - apps::test::GetFeaturesToEnableLinkCapturingUX(GetParam()), {}); + std::vector<base::test::FeatureRefAndParams> features_to_enable = + apps::test::GetFeaturesToEnableLinkCapturingUX( + std::get<apps::test::LinkCapturingFeatureVersion>(GetParam())); + + if (IsMigrationEnabled()) { + features_to_enable.push_back( + {::features::kPageActionsMigration, + {{::features::kPageActionsMigrationIntentPicker.name, "true"}}}); + } + + feature_list_.InitWithFeaturesAndParameters(features_to_enable, {}); } void SetUpOnMainThread() override { @@ -92,8 +124,10 @@ return {outer_app_id, inner_app_id}; } + bool IsMigrationEnabled() const { return std::get<bool>(GetParam()); } + private: - base::test::ScopedFeatureList scoped_feature_list_; + base::test::ScopedFeatureList feature_list_; }; IN_PROC_BROWSER_TEST_P(DefaultLinkCapturingInteractiveUiTest, @@ -176,7 +210,7 @@ // Verify that no icon was shown. EXPECT_TRUE(web_app::AwaitIntentPickerTabHelperIconUpdateComplete( browser()->tab_strip_model()->GetActiveWebContents())); - ASSERT_FALSE(web_app::GetIntentPickerIcon(browser())->GetVisible()); + ASSERT_FALSE(web_app::GetIntentPickerButton(browser())->GetVisible()); // Load a different page while simulating it having a native app. apps::OverrideMacAppForUrlForTesting(true, kFinderAppPath); @@ -185,11 +219,17 @@ // Verify app icon shows up in the intent picker. EXPECT_TRUE(web_app::AwaitIntentPickerTabHelperIconUpdateComplete( browser()->tab_strip_model()->GetActiveWebContents())); - IntentChipButton* intent_picker_icon = - web_app::GetIntentPickerIcon(browser()); + views::Button* intent_picker_icon = web_app::GetIntentPickerButton(browser()); ASSERT_NE(intent_picker_icon, nullptr); - ui::ImageModel app_icon = intent_picker_icon->GetAppIconForTesting(); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_NE(web_contents, nullptr); + + IntentPickerTabHelper* tab_helper = + IntentPickerTabHelper::FromWebContents(web_contents); + + ui::ImageModel app_icon = tab_helper->app_icon(); SkColor final_color = app_icon.GetImage().AsBitmap().getColor(8, 8); EXPECT_TRUE( @@ -200,6 +240,8 @@ INSTANTIATE_TEST_SUITE_P( All, DefaultLinkCapturingInteractiveUiTest, - testing::Values(apps::test::LinkCapturingFeatureVersion::kV2DefaultOff, - apps::test::LinkCapturingFeatureVersion::kV2DefaultOn), - apps::test::LinkCapturingVersionToString); + testing::Combine( + testing::Values(apps::test::LinkCapturingFeatureVersion::kV2DefaultOff, + apps::test::LinkCapturingFeatureVersion::kV2DefaultOn), + testing::Bool()), + GenerateIntentChipTestName);
diff --git a/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.cc b/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.cc index 37facc7..9946fad 100644 --- a/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.cc +++ b/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.cc
@@ -86,6 +86,7 @@ views::BubbleBorder::Arrow::NONE, views::BubbleBorder::DIALOG_SHADOW, /*autosize=*/true) { + SetOwnedByWidget(true); SetModalType(ui::mojom::ModalType::kChild); SetShowCloseButton(true);
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_contents_view_unittest.cc b/chrome/browser/ui/views/download/bubble/download_bubble_contents_view_unittest.cc index da2b8841..de860b3 100644 --- a/chrome/browser/ui/views/download/bubble/download_bubble_contents_view_unittest.cc +++ b/chrome/browser/ui/views/download/bubble/download_bubble_contents_view_unittest.cc
@@ -33,13 +33,13 @@ #include "ui/views/view.h" #include "ui/views/window/dialog_client_view.h" -namespace { - using ::testing::_; using ::testing::NiceMock; using ::testing::Return; using ::testing::ReturnRefOfCopy; +namespace { + class MockDownloadBubbleNavigationHandler : public DownloadBubbleNavigationHandler { public: @@ -90,6 +90,8 @@ return std::make_unique<MockDownloadCoreService>(); } +} // namespace + class DownloadBubbleContentsViewTest : public ChromeViewsTestBase, public ::testing::WithParamInterface<bool> { @@ -161,6 +163,7 @@ views::Widget::InitParams::TYPE_WINDOW); auto bubble_delegate = std::make_unique<views::BubbleDialogDelegate>( anchor_widget_->GetContentsView(), views::BubbleBorder::TOP_RIGHT); + bubble_delegate->SetOwnedByWidget(true); bubble_delegate_ = bubble_delegate.get(); navigation_handler_ = std::make_unique<MockDownloadBubbleNavigationHandler>(); @@ -432,5 +435,3 @@ OfflineItemUtils::GetContentIdForDownload(download_items_[0].get()), DownloadCommands::Command::DISCARD); } - -} // namespace
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc b/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc index 187b560..de24408c 100644 --- a/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc +++ b/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc
@@ -190,6 +190,7 @@ views::Widget::InitParams::TYPE_WINDOW); auto bubble_delegate = std::make_unique<views::BubbleDialogDelegate>( anchor_widget_->GetContentsView(), views::BubbleBorder::TOP_RIGHT); + bubble_delegate->SetOwnedByWidget(true); bubble_delegate_ = bubble_delegate.get(); bubble_navigator_ = std::make_unique<MockDownloadBubbleNavigationHandler>( *security_view_info_);
diff --git a/chrome/browser/ui/views/download/bubble/download_toolbar_ui_controller.cc b/chrome/browser/ui/views/download/bubble/download_toolbar_ui_controller.cc index f76d1b3..1f8e654 100644 --- a/chrome/browser/ui/views/download/bubble/download_toolbar_ui_controller.cc +++ b/chrome/browser/ui/views/download/bubble/download_toolbar_ui_controller.cc
@@ -920,6 +920,7 @@ button, views::BubbleBorder::TOP_RIGHT, views::BubbleBorder::DIALOG_SHADOW, /*autosize=*/true); + bubble_delegate->SetOwnedByWidget(true); bubble_delegate->SetTitle( l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_HEADER_LABEL)); bubble_delegate->SetShowTitle(false);
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc b/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc index af61b75..47a78a5 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc
@@ -72,6 +72,7 @@ auto bubble_delegate = std::make_unique<views::BubbleDialogDelegate>( anchor_view, views::BubbleBorder::TOP_RIGHT, views::BubbleBorder::DIALOG_SHADOW, /*autosize=*/true); + bubble_delegate->SetOwnedByWidget(true); bubble_delegate->set_margins(gfx::Insets(0)); bubble_delegate->set_fixed_width( views::LayoutProvider::Get()->GetDistanceMetric(
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc index 8988a1b..3c743a65 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
@@ -85,7 +85,6 @@ SetModalType(ui::mojom::ModalType::kChild); SetShowCloseButton(false); SetTitle(controller_->GetHeader()); - SetOwnedByWidget(false); RegisterDeleteDelegateCallback( RegisterDeleteCallbackPassKey(), base::BindOnce(
diff --git a/chrome/browser/ui/views/external_protocol_handler_ash.cc b/chrome/browser/ui/views/external_protocol_handler_ash.cc index ef5ba06..33b1e0f 100644 --- a/chrome/browser/ui/views/external_protocol_handler_ash.cc +++ b/chrome/browser/ui/views/external_protocol_handler_ash.cc
@@ -33,10 +33,6 @@ using content::WebContents; -namespace { - -const int kMessageWidth = 400; - // The external protocol dialog for Chrome OS shown when we have a URL with a // Tel scheme but there are no handlers. class ExternalProtocolNoHandlersTelSchemeDialog : public views::DialogDelegate { @@ -53,7 +49,7 @@ l10n_util::GetStringUTF16(IDS_EXTERNAL_PROTOCOL_CLOSE_BUTTON_TEXT)); message_box_view_ = new views::MessageBoxView(); - message_box_view_->SetMessageWidth(kMessageWidth); + message_box_view_->SetMessageWidth(400); views::DialogDelegate::CreateDialogWidget(this, nullptr, parent_window) ->Show(); @@ -121,8 +117,6 @@ } } -} // namespace - /////////////////////////////////////////////////////////////////////////////// // ExternalProtocolHandler
diff --git a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.cc b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.cc index 17293c8..a022574f 100644 --- a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.cc +++ b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.cc
@@ -36,13 +36,13 @@ namespace { -#if defined(USE_DBUS_MENU) -bool CreateGlobalMenuBar() { +#if BUILDFLAG(USE_DBUS) +bool ShouldCreateGlobalMenuBar() { return ui::OzonePlatform::GetInstance() - ->GetPlatformProperties() + ->GetPlatformRuntimeProperties() .supports_global_application_menus; } -#endif // defined(USE_DBUS_MENU) +#endif std::unordered_set<std::string>& SentStartupIds() { static base::NoDestructor<std::unordered_set<std::string>> sent_startup_ids; @@ -294,12 +294,12 @@ const views::Widget::InitParams& params) { DesktopWindowTreeHostLinux::Init(std::move(params)); -#if defined(USE_DBUS_MENU) - // We have now created our backing X11 window. We now need to (possibly) +#if BUILDFLAG(USE_DBUS) + // We have now created our backing window. We now need to (possibly) // alert the desktop environment that there's a menu bar attached to it. - if (CreateGlobalMenuBar()) { - dbus_appmenu_ = - std::make_unique<DbusAppmenu>(browser_view_, GetAcceleratedWidget()); + if (ShouldCreateGlobalMenuBar()) { + dbus_appmenu_ = std::make_unique<DbusAppmenu>( + browser_view_, platform_window(), GetAcceleratedWidget()); } #endif } @@ -311,7 +311,7 @@ } void BrowserDesktopWindowTreeHostLinux::CloseNow() { -#if defined(USE_DBUS_MENU) +#if BUILDFLAG(USE_DBUS) dbus_appmenu_.reset(); #endif DesktopWindowTreeHostLinux::CloseNow();
diff --git a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.h b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.h index 882f9d8..363e6e87 100644 --- a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.h +++ b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.h
@@ -7,12 +7,13 @@ #include "base/memory/raw_ptr.h" #include "build/build_config.h" +#include "build/config/linux/dbus/buildflags.h" #include "chrome/browser/ui/views/frame/browser_desktop_window_tree_host.h" #include "ui/base/mojom/window_show_state.mojom-forward.h" #include "ui/linux/device_scale_factor_observer.h" #include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h" // nogncheck -#if defined(USE_DBUS_MENU) +#if BUILDFLAG(USE_DBUS) #include "chrome/browser/ui/views/frame/dbus_appmenu.h" // nogncheck #endif @@ -104,7 +105,7 @@ raw_ptr<BrowserFrame> browser_frame_ = nullptr; raw_ptr<DesktopBrowserFrameAuraLinux> native_frame_ = nullptr; -#if defined(USE_DBUS_MENU) +#if BUILDFLAG(USE_DBUS) // Each browser frame maintains its own menu bar object because the lower // level dbus protocol associates a xid to a menu bar; we can't map multiple // xids to the same menu bar.
diff --git a/chrome/browser/ui/views/frame/dbus_appmenu.cc b/chrome/browser/ui/views/frame/dbus_appmenu.cc index 43bed5a..f007f82 100644 --- a/chrome/browser/ui/views/frame/dbus_appmenu.cc +++ b/chrome/browser/ui/views/frame/dbus_appmenu.cc
@@ -50,7 +50,6 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/menu_model.h" #include "ui/base/models/menu_separator_types.h" -#include "ui/events/keycodes/keyboard_code_conversion_x.h" #include "ui/gfx/text_elider.h" // A line in the static menu definitions. @@ -203,10 +202,13 @@ std::vector<raw_ptr<HistoryItem, VectorExperimental>> tabs; }; -DbusAppmenu::DbusAppmenu(BrowserView* browser_view, uint32_t browser_frame_id) +DbusAppmenu::DbusAppmenu(BrowserView* browser_view, + ui::PlatformWindow* platform_window, + uint32_t browser_frame_id) : browser_(browser_view->browser()), profile_(browser_->profile()), browser_view_(browser_view), + platform_window_(platform_window), browser_frame_id_(browser_frame_id), tab_restore_service_(nullptr), last_command_id_(kFirstUnreservedCommandId - 1) {
diff --git a/chrome/browser/ui/views/frame/dbus_appmenu.h b/chrome/browser/ui/views/frame/dbus_appmenu.h index 046f81d0..5a4f261 100644 --- a/chrome/browser/ui/views/frame/dbus_appmenu.h +++ b/chrome/browser/ui/views/frame/dbus_appmenu.h
@@ -29,6 +29,7 @@ namespace ui { class Accelerator; +class PlatformWindow; } class Browser; @@ -49,7 +50,9 @@ public sessions::TabRestoreServiceObserver, public ui::SimpleMenuModel::Delegate { public: - DbusAppmenu(BrowserView* browser_view, uint32_t browser_frame_id); + DbusAppmenu(BrowserView* browser_view, + ui::PlatformWindow* platform_window, + uint32_t browser_frame_id); DbusAppmenu(const DbusAppmenu&) = delete; DbusAppmenu& operator=(const DbusAppmenu&) = delete; @@ -62,6 +65,7 @@ std::string GetPath() const; uint32_t browser_frame_id() const { return browser_frame_id_; } + ui::PlatformWindow* platform_window() const { return platform_window_; } private: struct HistoryItem; @@ -144,6 +148,7 @@ const raw_ptr<Browser> browser_; raw_ptr<Profile> profile_; raw_ptr<BrowserView> browser_view_; + raw_ptr<ui::PlatformWindow> platform_window_; // XID of the browser's frame window that owns this menu. Deliberately stored // as plain int (and not as x11::Window) because it is never used for any // calls to the X server, but it is always used for building string paths and
diff --git a/chrome/browser/ui/views/frame/dbus_appmenu_registrar.cc b/chrome/browser/ui/views/frame/dbus_appmenu_registrar.cc index ec58351..7070a40 100644 --- a/chrome/browser/ui/views/frame/dbus_appmenu_registrar.cc +++ b/chrome/browser/ui/views/frame/dbus_appmenu_registrar.cc
@@ -16,6 +16,8 @@ #include "dbus/message.h" #include "dbus/object_path.h" #include "dbus/object_proxy.h" +#include "ui/platform_window/extensions/wayland_extension.h" +#include "ui/platform_window/extensions/x11_extension.h" namespace { @@ -42,13 +44,18 @@ void DbusAppmenuRegistrar::OnMenuBarDestroyed(DbusAppmenu* menu) { DCHECK(base::Contains(menus_, menu)); if (menus_[menu] == kRegistered) { - dbus::MethodCall method_call(kAppMenuRegistrarInterface, - "UnregisterWindow"); - dbus::MessageWriter writer(&method_call); - writer.AppendUint32(menu->browser_frame_id()); - registrar_proxy_->CallMethod(&method_call, - dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, - base::DoNothing()); + if (auto* toplevel_extension = + ui::GetWaylandToplevelExtension(*menu->platform_window())) { + toplevel_extension->UnsetAppmenu(); + } else if (ui::GetX11Extension(*menu->platform_window())) { + dbus::MethodCall method_call(kAppMenuRegistrarInterface, + "UnregisterWindow"); + dbus::MessageWriter writer(&method_call); + writer.AppendUint32(menu->browser_frame_id()); + registrar_proxy_->CallMethod(&method_call, + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::DoNothing()); + } } menus_.erase(menu); } @@ -77,12 +84,19 @@ DCHECK(base::Contains(menus_, menu)); DCHECK(menus_[menu] == kInitializeSucceeded || menus_[menu] == kRegistered); menus_[menu] = kRegistered; - dbus::MethodCall method_call(kAppMenuRegistrarInterface, "RegisterWindow"); - dbus::MessageWriter writer(&method_call); - writer.AppendUint32(menu->browser_frame_id()); - writer.AppendObjectPath(dbus::ObjectPath(menu->GetPath())); - registrar_proxy_->CallMethod( - &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::DoNothing()); + + if (auto* toplevel_extension = + ui::GetWaylandToplevelExtension(*menu->platform_window())) { + toplevel_extension->SetAppmenu(bus_->GetConnectionName(), menu->GetPath()); + } else if (ui::GetX11Extension(*menu->platform_window())) { + dbus::MethodCall method_call(kAppMenuRegistrarInterface, "RegisterWindow"); + dbus::MessageWriter writer(&method_call); + writer.AppendUint32(menu->browser_frame_id()); + writer.AppendObjectPath(dbus::ObjectPath(menu->GetPath())); + registrar_proxy_->CallMethod(&method_call, + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::DoNothing()); + } } void DbusAppmenuRegistrar::OnMenuInitialized(DbusAppmenu* menu, bool success) {
diff --git a/chrome/browser/ui/views/frame/multi_contents_resize_area.cc b/chrome/browser/ui/views/frame/multi_contents_resize_area.cc index 7800da6..123cde2b 100644 --- a/chrome/browser/ui/views/frame/multi_contents_resize_area.cc +++ b/chrome/browser/ui/views/frame/multi_contents_resize_area.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/views/frame/multi_contents_resize_area.h" -#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/views/frame/multi_contents_view.h" #include "chrome/grit/generated_resources.h" @@ -13,7 +12,6 @@ #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/color/color_provider.h" #include "ui/gfx/geometry/size.h" -#include "ui/gfx/paint_vector_icon.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/background.h" #include "ui/views/controls/focus_ring.h" @@ -21,9 +19,10 @@ #include "ui/views/layout/flex_layout.h" namespace { +const int kHandleCornerRadius = 2; const int kHandleHeight = 24; -const int kHandleWidth = 16; -const int kHandlePadding = 8; +const int kHandlePadding = 6; +const int kHandleWidth = 4; } // namespace DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(MultiContentsResizeHandle, @@ -37,8 +36,6 @@ SetCanProcessEventsWithinSubtree(false); SetFocusBehavior(FocusBehavior::ALWAYS); views::FocusRing::Install(this); - SetImage(ui::ImageModel::FromVectorIcon( - kDragHandleIcon, kColorSidePanelResizeAreaHandle, kHandleWidth)); GetViewAccessibility().SetRole(ax::mojom::Role::kSlider); GetViewAccessibility().SetName( l10n_util::GetStringUTF16(IDS_ACCNAME_SPLIT_TABS_RESIZE)); @@ -46,6 +43,30 @@ kMultiContentsResizeHandleElementId); } +void MultiContentsResizeHandle::UpdateVisibility(bool visible) { + if (visible) { + const SkColor resize_handle_color = + GetColorProvider()->GetColor(kColorSidePanelHoverResizeAreaHandle); + SetBackground(views::CreateRoundedRectBackground(resize_handle_color, + kHandleCornerRadius)); + } else { + SetBackground(nullptr); + } +} + +void MultiContentsResizeHandle::AddedToWidget() { + GetFocusManager()->AddFocusChangeListener(this); +} + +void MultiContentsResizeHandle::RemovedFromWidget() { + GetFocusManager()->RemoveFocusChangeListener(this); +} + +void MultiContentsResizeHandle::OnWillChangeFocus(views::View* before, + views::View* now) { + UpdateVisibility(now == this); +} + BEGIN_METADATA(MultiContentsResizeHandle) END_METADATA @@ -77,5 +98,13 @@ return false; } +void MultiContentsResizeArea::OnMouseMoved(const ui::MouseEvent& event) { + resize_handle_->UpdateVisibility(true); +} + +void MultiContentsResizeArea::OnMouseExited(const ui::MouseEvent& event) { + resize_handle_->UpdateVisibility(false); +} + BEGIN_METADATA(MultiContentsResizeArea) END_METADATA
diff --git a/chrome/browser/ui/views/frame/multi_contents_resize_area.h b/chrome/browser/ui/views/frame/multi_contents_resize_area.h index 8678777..a34d1f7 100644 --- a/chrome/browser/ui/views/frame/multi_contents_resize_area.h +++ b/chrome/browser/ui/views/frame/multi_contents_resize_area.h
@@ -6,20 +6,31 @@ #define CHROME_BROWSER_UI_VIEWS_FRAME_MULTI_CONTENTS_RESIZE_AREA_H_ #include "ui/base/interaction/element_identifier.h" -#include "ui/views/controls/image_view.h" #include "ui/views/controls/resize_area.h" +#include "ui/views/focus/focus_manager.h" +#include "ui/views/view.h" class MultiContentsView; // Keyboard-accessible drag handle icon intended to be drawn on top of a // MultiContentsResizeArea. -class MultiContentsResizeHandle : public views::ImageView { - METADATA_HEADER(MultiContentsResizeHandle, ImageView) +class MultiContentsResizeHandle : public views::View, + public views::FocusChangeListener { + METADATA_HEADER(MultiContentsResizeHandle, views::View) public: DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kMultiContentsResizeHandleElementId); MultiContentsResizeHandle(); + + void UpdateVisibility(bool visible); + + // views::View: + void AddedToWidget() override; + void RemovedFromWidget() override; + + // FocusChangeListener: + void OnWillChangeFocus(views::View* before, views::View* now) override; }; // ResizeArea meant to draw in between WebContents within a MultiContentsView, @@ -33,6 +44,8 @@ explicit MultiContentsResizeArea(MultiContentsView* multi_contents_view); bool OnKeyPressed(const ui::KeyEvent& event) override; + void OnMouseMoved(const ui::MouseEvent& event) override; + void OnMouseExited(const ui::MouseEvent& event) override; private: raw_ptr<MultiContentsView> multi_contents_view_;
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_coordinator.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_coordinator.cc index 0e200579..c74f5e2 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_coordinator.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_coordinator.cc
@@ -57,10 +57,18 @@ views::Widget* const widget = views::BubbleDialogDelegateView::CreateBubble(std::move(bubble_view)); + view_controller_->SetIsReloadingState(false); controller->Update(web_contents); widget->Show(); } +bool CookieControlsBubbleCoordinator::IsReloadingState() const { + if (!view_controller_) { + return false; + } + return view_controller_->IsReloadingState(); +} + CookieControlsBubbleViewImpl* CookieControlsBubbleCoordinator::GetBubble() const { return bubble_view_;
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_coordinator.h b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_coordinator.h index a74b4b79..bcb430af 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_coordinator.h +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_coordinator.h
@@ -33,6 +33,8 @@ virtual CookieControlsBubbleViewImpl* GetBubble() const; + bool IsReloadingState() const; + CookieControlsBubbleViewController* GetViewControllerForTesting(); void SetDisplayNameForTesting(const std::u16string& name);
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc index 757e86b..61c0968 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc
@@ -233,9 +233,13 @@ CookieBlocking3pcdStatus blocking_status, base::Time expiration, std::vector<content_settings::TrackingProtectionFeature> features) { + // Leave the UI unchanged during reloading; it will update after the page + // loads. + if (is_reloading_state_) { + return; + } protections_on_ = protections_on; blocking_status_ = blocking_status; - if (!controls_visible || features.empty()) { bubble_view_->CloseWidget(); return; @@ -356,6 +360,9 @@ base::RecordAction(base::UserMetricsAction( "CookieControls.Bubble.BlockThirdPartyCookies")); } + // We should only enter the reloading state in the Incognito ACT UI. + is_reloading_state_ = controller_->ShowActFeatures(); + controller_->SetUserChangedCookieBlockingForSite(true); // Set the toggle ON when protections are ON (cookies are blocked). controller_->OnCookieBlockingEnabledForSite(protections_on);
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h index 1c0d87f..a7548d4 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h
@@ -43,6 +43,12 @@ void SetSubjectUrlNameForTesting(const std::u16string& name); + void SetIsReloadingState(bool is_reloading_state) { + is_reloading_state_ = is_reloading_state; + } + + bool IsReloadingState() { return is_reloading_state_; } + private: friend class CookieControlsBubbleViewBrowserTest; @@ -87,6 +93,10 @@ // Whether protections are enabled for the given site. bool protections_on_ = true; + + // Whether the page is reloading in the background after UB is toggled. + bool is_reloading_state_ = false; + // The most recent status provided by the CookieControlsController, used to // determine the user's 3PCD status. CookieBlocking3pcdStatus blocking_status_ =
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc index 8982a10a..68c513b1 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc
@@ -200,7 +200,9 @@ protections_on_ = protections_on; blocking_status_ = blocking_status; should_highlight_ = should_highlight; - UpdateIcon(); + if (!bubble_coordinator_->IsReloadingState()) { + UpdateIcon(); + } } } @@ -261,6 +263,9 @@ // setting. if (ShouldBeVisible()) { GetViewAccessibility().SetDescription(u""); + if (base::FeatureList::IsEnabled(privacy_sandbox::kActUserBypassUx)) { + UpdateIcon(); + } // Animate the icon to provide a visual confirmation to the user that their // protection status on the site has changed. AnimateIn(GetLabelForStatus());
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc index 61f53cc..8ada0aa5 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc
@@ -29,6 +29,7 @@ #include "components/feature_engagement/public/feature_constants.h" #include "components/privacy_sandbox/privacy_sandbox_features.h" #include "components/privacy_sandbox/tracking_protection_prefs.h" +#include "components/privacy_sandbox/tracking_protection_settings.h" #include "components/profile_metrics/browser_profile_type.h" #include "components/site_engagement/content/site_engagement_service.h" #include "components/strings/grit/privacy_sandbox_strings.h" @@ -768,10 +769,56 @@ } std::vector<base::test::FeatureRef> DisabledFeatures() override { return {}; } + + privacy_sandbox::TrackingProtectionSettings* tracking_protection_settings() { + return TrackingProtectionSettingsFactory::GetForProfile( + browser()->profile()); + } + auto CheckTrackingProtectionFrozenContentBlockedState() { + return Steps( + CheckViewProperty(CookieControlsContentView::kToggleButton, + &views::ToggleButton::GetIsOn, false), + CheckViewProperty( + CookieControlsContentView::kTitle, &views::Label::GetText, + l10n_util::GetStringUTF16( + IDS_COOKIE_CONTROLS_BUBBLE_SITE_NOT_WORKING_TITLE)), + CheckViewProperty( + CookieControlsContentView::kDescription, &views::Label::GetText, + l10n_util::GetStringUTF16( + IDS_TRACKING_PROTECTION_BUBBLE_SITE_NOT_WORKING_DESCRIPTION)), + CheckViewProperty( + CookieControlsContentView::kThirdPartyCookiesLabel, + + &views::Label::GetText, + l10n_util::GetStringUTF16( + IDS_TRACKING_PROTECTION_BUBBLE_3PC_BLOCKED_SUBTITLE)), + CheckIcon(RichControlsContainerView::kIcon, + views::kEyeCrossedRefreshIcon)); + } + + auto CheckTrackingProtectionFrozenContentAllowedState() { + return Steps( + CheckViewProperty(CookieControlsContentView::kToggleButton, + &views::ToggleButton::GetIsOn, true), + CheckViewProperty( + CookieControlsContentView::kTitle, &views::Label::GetText, + l10n_util::GetStringUTF16( + IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_TITLE)), + CheckViewProperty( + CookieControlsContentView::kDescription, &views::Label::GetText, + l10n_util::GetStringUTF16( + IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_DESCRIPTION)), + CheckViewProperty( + CookieControlsContentView::kThirdPartyCookiesLabel, + &views::Label::GetText, + l10n_util::GetStringUTF16( + IDS_TRACKING_PROTECTION_BUBBLE_3PC_ALLOWED_SUBTITLE)), + CheckIcon(RichControlsContainerView::kIcon, views::kEyeRefreshIcon)); + } }; IN_PROC_BROWSER_TEST_F(CookieControlsInteractiveUiTrackingProtectionTest, - CreateAndRemoveExceptionIncognitoAct) { + CreateExceptionIncognitoAct) { BlockThirdPartyCookies(/*use_3pcd=*/true); EnableFpProtection(); auto* const incognito_browser = CreateIncognitoBrowser(browser()->profile()); @@ -786,6 +833,28 @@ /*with_act=*/true), PressButton(CookieControlsContentView::kToggleButton), EnsureNotPresent(CookieControlsBubbleView::kReloadingView), + CheckTrackingProtectionFrozenContentBlockedState()))); +} + +IN_PROC_BROWSER_TEST_F(CookieControlsInteractiveUiTrackingProtectionTest, + RemoveExceptionIncognitoAct) { + BlockThirdPartyCookies(/*use_3pcd=*/true); + EnableFpProtection(); + cookie_settings()->SetCookieSettingForUserBypass( + third_party_cookie_page_url()); + tracking_protection_settings()->AddTrackingProtectionException( + third_party_cookie_page_url()); + auto* const incognito_browser = CreateIncognitoBrowser(browser()->profile()); + RunTestSequence(InContext( + incognito_browser->window()->GetElementContext(), + Steps(InstrumentTab(kWebContentsElementId), + NavigateWebContents(kWebContentsElementId, + third_party_cookie_page_url()), + PressButton(kCookieControlsIconElementId), + InAnyContext(WaitForShow(CookieControlsBubbleView::kContentView)), CheckTrackingProtectionAllowedState(/*incognito=*/true, - /*with_act=*/true)))); + /*with_act=*/true), + PressButton(CookieControlsContentView::kToggleButton), + EnsureNotPresent(CookieControlsBubbleView::kReloadingView), + CheckTrackingProtectionFrozenContentAllowedState()))); }
diff --git a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc index b0010222..4cc5a6d2 100644 --- a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc +++ b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
@@ -126,10 +126,6 @@ exclusive_access_manager_(this) { SetHasWindowSizeControls(true); - // TODO(pbos): See if this can retain SetOwnedByWidget(true) and get deleted - // through WidgetDelegate::DeleteDelegate(). This requires confirming that - // delegate_->WindowClosed() is safe to call before this deletes. - SetOwnedByWidget(false); RegisterDeleteDelegateCallback( RegisterDeleteCallbackPassKey(), base::BindOnce(
diff --git a/chrome/browser/ui/views/passwords/credential_leak_dialog_view.cc b/chrome/browser/ui/views/passwords/credential_leak_dialog_view.cc index 3580001..ce355db8 100644 --- a/chrome/browser/ui/views/passwords/credential_leak_dialog_view.cc +++ b/chrome/browser/ui/views/passwords/credential_leak_dialog_view.cc
@@ -113,9 +113,8 @@ // Set the ownership of the delegate, not the View. The View is owned by the // Widget as a child view. - // TODO(crbug.com/338254375): Remove the following two lines once this is the - // default state for widgets and the delegates. - views::WidgetDelegate::SetOwnedByWidget(false); + // TODO(crbug.com/338254375): Remove the following line once this is the + // default state for widgets. SetOwnershipOfNewWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET); SetButtons(controller->ShouldShowCancelButton()
diff --git a/chrome/browser/ui/views/plus_addresses/plus_address_creation_dialog_delegate.cc b/chrome/browser/ui/views/plus_addresses/plus_address_creation_dialog_delegate.cc index bd9f63d..45c24974 100644 --- a/chrome/browser/ui/views/plus_addresses/plus_address_creation_dialog_delegate.cc +++ b/chrome/browser/ui/views/plus_addresses/plus_address_creation_dialog_delegate.cc
@@ -445,8 +445,6 @@ /*autosize=*/true), controller_(controller), web_contents_(web_contents) { - // This delegate is owned & deleted by the PlusAddressCreationController. - SetOwnedByWidget(false); RegisterDeleteDelegateCallback( RegisterDeleteCallbackPassKey(), base::BindOnce(
diff --git a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc index d60ac22d..9bddc5e 100644 --- a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc +++ b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
@@ -97,6 +97,8 @@ ADD_PROPERTY_METADATA(gfx::Rect, ClientRect) END_METADATA +} // namespace + class ScreenCaptureNotificationUIViews : public views::WidgetDelegateView, public views::ViewObserver { METADATA_HEADER(ScreenCaptureNotificationUIViews, views::WidgetDelegateView) @@ -139,34 +141,6 @@ raw_ptr<views::View> hide_link_ = nullptr; }; -// ScreenCaptureNotificationUI implementation using Views. -class ScreenCaptureNotificationUIImpl : public ScreenCaptureNotificationUI { - public: - ScreenCaptureNotificationUIImpl(const std::u16string& text, - content::WebContents* capturing_web_contents); - ScreenCaptureNotificationUIImpl(const ScreenCaptureNotificationUIImpl&) = - delete; - ScreenCaptureNotificationUIImpl& operator=( - const ScreenCaptureNotificationUIImpl&) = delete; - ~ScreenCaptureNotificationUIImpl() override = default; - - // ScreenCaptureNotificationUI override: - gfx::NativeViewId OnStarted( - base::OnceClosure stop_callback, - content::MediaStreamUI::SourceCallback source_callback, - const std::vector<content::DesktopMediaID>& media_ids) override; - - private: - // Helper to set window id to parent browser window id for task bar grouping. -#if BUILDFLAG(IS_WIN) - void SetWindowsAppId(views::Widget* widget); -#endif - - std::u16string text_; - base::WeakPtr<content::WebContents> capturing_web_contents_; - std::unique_ptr<views::Widget> widget_; -}; - ScreenCaptureNotificationUIViews::ScreenCaptureNotificationUIViews( const std::u16string& text, content::WebContents* capturing_web_contents, @@ -181,7 +155,6 @@ SetShowTitle(false); SetTitle(text); - SetOwnedByWidget(false); RegisterDeleteDelegateCallback( RegisterDeleteCallbackPassKey(), base::BindOnce(&ScreenCaptureNotificationUIViews::NotifyStopped, @@ -301,6 +274,36 @@ BEGIN_METADATA(ScreenCaptureNotificationUIViews) END_METADATA +namespace { + +// ScreenCaptureNotificationUI implementation using Views. +class ScreenCaptureNotificationUIImpl : public ScreenCaptureNotificationUI { + public: + ScreenCaptureNotificationUIImpl(const std::u16string& text, + content::WebContents* capturing_web_contents); + ScreenCaptureNotificationUIImpl(const ScreenCaptureNotificationUIImpl&) = + delete; + ScreenCaptureNotificationUIImpl& operator=( + const ScreenCaptureNotificationUIImpl&) = delete; + ~ScreenCaptureNotificationUIImpl() override = default; + + // ScreenCaptureNotificationUI override: + gfx::NativeViewId OnStarted( + base::OnceClosure stop_callback, + content::MediaStreamUI::SourceCallback source_callback, + const std::vector<content::DesktopMediaID>& media_ids) override; + + private: + // Helper to set window id to parent browser window id for task bar grouping. +#if BUILDFLAG(IS_WIN) + void SetWindowsAppId(views::Widget* widget); +#endif + + std::u16string text_; + base::WeakPtr<content::WebContents> capturing_web_contents_; + std::unique_ptr<views::Widget> widget_; +}; + ScreenCaptureNotificationUIImpl::ScreenCaptureNotificationUIImpl( const std::u16string& text, content::WebContents* capturing_web_contents)
diff --git a/chrome/browser/ui/views/tabs/dragging/drag_session_data.cc b/chrome/browser/ui/views/tabs/dragging/drag_session_data.cc index 427ec868d..324e07e 100644 --- a/chrome/browser/ui/views/tabs/dragging/drag_session_data.cc +++ b/chrome/browser/ui/views/tabs/dragging/drag_session_data.cc
@@ -14,7 +14,9 @@ #include "chrome/browser/ui/views/tabs/tab_slot_view.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" -TabDragData::TabDragData(TabDragContext* source_context, TabSlotView* view) { +TabDragData::TabDragData(TabDragContext* source_context, TabSlotView* view) + : source_model_index(source_context->GetIndexOf(view)), + view_type(view->GetTabSlotViewType()) { source_model_index = source_context->GetIndexOf(view); if (source_model_index.has_value()) { contents = source_context->GetTabStripModel()->GetWebContentsAt(
diff --git a/chrome/browser/ui/views/tabs/dragging/drag_session_data.h b/chrome/browser/ui/views/tabs/dragging/drag_session_data.h index d5de36d..d8f4015 100644 --- a/chrome/browser/ui/views/tabs/dragging/drag_session_data.h +++ b/chrome/browser/ui/views/tabs/dragging/drag_session_data.h
@@ -45,13 +45,15 @@ ~TabDragData(); TabDragData(TabDragData&&); - // The WebContents being dragged. - raw_ptr<content::WebContents> contents = nullptr; - // This is the index of the tab in `source_context_` when the drag // began. This is used to restore the previous state if the drag is aborted. // Nullopt if this is a group header. - std::optional<int> source_model_index = std::nullopt; + std::optional<int> source_model_index; + + TabSlotView::ViewType view_type; + + // The WebContents being dragged. + raw_ptr<content::WebContents> contents = nullptr; // If attached this is the view in `attached_context_`. raw_ptr<TabSlotView> attached_view = nullptr;
diff --git a/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.cc index 036da6f1..8fa2fb0 100644 --- a/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.cc
@@ -1680,23 +1680,40 @@ void TabDragController::RevertDrag() { CHECK(attached_context_); + CHECK(source_context_); // If we're dragging a saved tab group, suspend tracking during the revert. // Otherwise, the group will get emptied out as we revert all the tabs. MaybePauseTrackingSavedTabGroup(); - if (drag_data_.group_drag_data_.has_value()) { - RevertHeaderDrag(drag_data_.group_drag_data_.value().group); - } else { - for (size_t i = first_tab_index(); i < drag_data_.tab_drag_data_.size(); - ++i) { - if (drag_data_.tab_drag_data_[i].contents) { - // Contents is NULL if a tab was destroyed while the drag was under way. - RevertDragAt(i); - } + base::AutoReset<bool> is_mutating_setter(&is_mutating_, true); + base::AutoReset<bool> is_removing_last_tab_setter( + &is_removing_last_tab_for_revert_, true); + + if (attached_context_ != source_context_) { + for (TabDragData& tab_datum : drag_data_.tab_drag_data_) { + tab_datum.attached_view->set_detached(); + tab_datum.attached_view = nullptr; } } + // Revert each tab and group. N.B. we manually increment `i` because each + // group has multiple entries in `tab_drag_data_`. + for (size_t i = 0; i < drag_data_.tab_drag_data_.size();) { + const TabDragData tab_data = drag_data_.tab_drag_data_[i]; + if (tab_data.view_type == TabSlotView::ViewType::kTab) { + RevertTabAt(i); + i++; + } else { + RevertGroupAt(i); + // Skip all the tabs in the group too. + i += source_context_->GetTabStripModel() + ->group_model() + ->GetTabGroup(tab_data.tab_group_data->group_id) + ->tab_count() + + 1; + } + } MaybeResumeTrackingSavedTabGroup(); if (did_restore_window_) { @@ -1704,10 +1721,6 @@ } if (attached_context_ == source_context_) { source_context_->StoppedDragging(); - if (drag_data_.group_drag_data_.has_value()) { - source_context_->GetTabStripModel()->MoveTabGroup( - drag_data_.group_drag_data_.value().group); - } } else { attached_context_->DraggedTabsDetached(); } @@ -1729,9 +1742,7 @@ initial_selection_model_); } - if (source_context_) { - source_context_->GetWidget()->Activate(); - } + source_context_->GetWidget()->Activate(); } void TabDragController::ResetSelection(TabStripModel* model) { @@ -1800,40 +1811,52 @@ source_context_->GetTabStripModel()->SetSelectionFromModel(selection_model); } -void TabDragController::RevertHeaderDrag(tab_groups::TabGroupId group_id) { - CHECK_NE(current_state_, DragState::kNotStarted); - CHECK(source_context_); +void TabDragController::RevertGroupAt(size_t drag_index) { + const tab_groups::TabGroupId group_id = + drag_data_.tab_drag_data_[drag_index].tab_group_data->group_id; + const TabDragData first_tab_in_group = + drag_data_.tab_drag_data_[drag_index + 1]; + int target_index = first_tab_in_group.source_model_index.value(); + if (attached_context_ != source_context_) { + source_context_->GetTabStripModel()->InsertDetachedTabGroupAt( + attached_context_->GetTabStripModel()->DetachTabGroupForInsertion( + group_id), + target_index); + source_context_->GetTabStripModel() + ->group_model() + ->GetTabGroup(group_id) + ->SetVisualData(first_tab_in_group.tab_group_data->group_visual_data); + return; + } - const size_t first_tab_in_group_index = first_tab_index(); - CHECK(drag_data_.tab_drag_data_[first_tab_in_group_index].contents); + const int index = + attached_context_->GetTabStripModel()->GetIndexOfWebContents( + first_tab_in_group.contents); + CHECK_NE(index, TabStripModel::kNoTab); - if (attached_context_ && attached_context_ == source_context_) { - base::AutoReset<bool> setter(&is_mutating_, true); - attached_context_->GetTabStripModel()->MoveGroupTo( - group_id, drag_data_.tab_drag_data_[first_tab_in_group_index] - .source_model_index.value()); - } else { - const tab_groups::TabGroupVisualData og_visual_data = - drag_data_.source_view_drag_data() - ->tab_group_data.value() - .group_visual_data; - - source_context_->GetTabStripModel()->AddTabGroup( - drag_data_.group_drag_data_.value().group, og_visual_data); - - // Drop the group header ptr before it is destroyed during revert. - drag_data_.tab_drag_data_[0].attached_view = nullptr; - for (size_t i = first_tab_index(); i < drag_data_.tab_drag_data_.size(); - ++i) { - if (drag_data_.tab_drag_data_[i].contents) { - // Contents is NULL if a tab was destroyed while the drag was under way. - RevertDragAt(i); + if (target_index > index) { + for (size_t i = drag_index + 1; i < drag_data_.tab_drag_data_.size(); ++i) { + const TabDragData other_tab = drag_data_.tab_drag_data_[i]; + // Ignore group headers, they don't have model indices to skip over. + if (other_tab.view_type != TabSlotView::ViewType::kTab) { + continue; } + // Ignore other tabs in this group, they will get moved along with us + // so we won't skip over them. + if (other_tab.tab_group_data.has_value() && + other_tab.tab_group_data->group_id == group_id) { + continue; + } + + ++target_index; } } + + source_context_->GetTabStripModel()->MoveGroupTo( + first_tab_in_group.tab_group_data->group_id, target_index); } -void TabDragController::RevertDragAt(size_t drag_index) { +void TabDragController::RevertTabAt(size_t drag_index) { CHECK_NE(current_state_, DragState::kNotStarted); CHECK(attached_context_); CHECK(source_context_); @@ -1841,47 +1864,32 @@ // a group header. CHECK(drag_data_.tab_drag_data_[drag_index].contents); - base::AutoReset<bool> setter(&is_mutating_, true); - TabDragData* data = &(drag_data_.tab_drag_data_[drag_index]); - // The index we will try to insert the tab at. It may or may not end up at - // this index, if the source tabstrip has changed since the drag began. - int target_index = data->source_model_index.value(); + const TabDragData tab_data = drag_data_.tab_drag_data_[drag_index]; - std::optional<TabDragData::TabGroupData> drag_data = data->tab_group_data; - - // Create the group if not present in the group model. + // The tab can be reverted into its original group if it still exists. const std::optional<tab_groups::TabGroupId> existing_group = - drag_data.has_value() && + tab_data.tab_group_data.has_value() && source_context_->GetTabStripModel() ->group_model() - ->ContainsTabGroup(drag_data.value().group_id) - ? std::make_optional(drag_data.value().group_id) + ->ContainsTabGroup(tab_data.tab_group_data->group_id) + ? std::make_optional(tab_data.tab_group_data->group_id) : std::nullopt; - const int index = + const int from_index = attached_context_->GetTabStripModel()->GetIndexOfWebContents( - data->contents); + tab_data.contents); + CHECK_NE(from_index, TabStripModel::kNoTab); + int target_index = tab_data.source_model_index.value(); + if (attached_context_ != source_context_) { - std::unique_ptr<base::AutoReset<bool>> removing_last_tab_setter; - if (attached_context_->GetTabStripModel()->count() == 1) { - removing_last_tab_setter = std::make_unique<base::AutoReset<bool>>( - &is_removing_last_tab_for_revert_, true); - } // The Tab was inserted into another TabDragContext. We need to - // put it back into the original one. Marking the view as detached tells - // the TabStrip to not animate its closure, as it's actually being moved. - data->attached_view->set_detached(); - // Drop the ptr, as this view will be deleted as part of detaching. - data->attached_view = nullptr; + // put it back into the original one. std::unique_ptr<tabs::TabModel> detached_tab = - attached_context_->GetTabStripModel()->DetachTabAtForInsertion(index); - // No-longer removing the last tab, so reset state. - removing_last_tab_setter.reset(); - // TODO(beng): (Cleanup) seems like we should use Attach() for this - // somehow. + attached_context_->GetTabStripModel()->DetachTabAtForInsertion( + from_index); source_context_->GetTabStripModel()->InsertDetachedTabAt( target_index, std::move(detached_tab), - (data->pinned ? AddTabTypes::ADD_PINNED : 0), existing_group); + (tab_data.pinned ? AddTabTypes::ADD_PINNED : 0), existing_group); } else { // The Tab was moved within the TabDragContext where the drag // was initiated. Move it back to the starting location. @@ -1890,7 +1898,7 @@ // occupying indices between this tab and the target index. Those // unreverted tabs will later be reverted to the right of the target // index, so we skip those indices. - if (target_index > index) { + if (target_index > from_index) { for (size_t i = drag_index + 1; i < drag_data_.tab_drag_data_.size(); ++i) { if (drag_data_.tab_drag_data_[i].contents) { @@ -1898,8 +1906,9 @@ } } } + source_context_->GetTabStripModel()->MoveWebContentsAt( - index, target_index, false, existing_group); + from_index, target_index, false, existing_group); } }
diff --git a/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.h b/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.h index 4c22194..aafa670f 100644 --- a/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.h +++ b/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.h
@@ -399,12 +399,6 @@ // Reverts a cancelled drag operation. void RevertDrag(); - // Reverts the drag for all the tabs belonging to a group. - void RevertHeaderDrag(tab_groups::TabGroupId group_id); - - // Reverts the tab at `drag_index` in `drag_data_`. - void RevertDragAt(size_t drag_index); - // Selects the dragged tabs in `model`. Does nothing if there are no longer // any dragged contents (as happens when a WebContents is deleted out from // under us). @@ -413,6 +407,12 @@ // Restores `initial_selection_model_` to the `source_context_`. void RestoreInitialSelection(); + // Reverts the drag the group starting at `drag_index_`. + void RevertGroupAt(size_t drag_index); + + // Reverts the tab at `drag_index` in `drag_data_`. + void RevertTabAt(size_t drag_index); + // Finishes a successful drag operation. void CompleteDrag();
diff --git a/chrome/browser/ui/views/tabs/tab_strip_scroll_container_unittest.cc b/chrome/browser/ui/views/tabs/tab_strip_scroll_container_unittest.cc index 885e19be..9b2e3ec1 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_scroll_container_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_scroll_container_unittest.cc
@@ -59,6 +59,7 @@ params.bounds = gfx::Rect(0, 0, 400, 400); params.delegate = new views::BubbleDialogDelegate( tab_strip_, views::BubbleBorder::Arrow::LEFT_TOP); + params.delegate->SetOwnedByWidget(true); std::unique_ptr<views::Widget> widget_ = CreateTestWidget(std::move(params)); widget_->Show(); views::Widget::ReparentNativeView(widget_->GetNativeView(),
diff --git a/chrome/browser/ui/views/user_education/browser_user_education_service.cc b/chrome/browser/ui/views/user_education/browser_user_education_service.cc index 868edb32..49927f4 100644 --- a/chrome/browser/ui/views/user_education/browser_user_education_service.cc +++ b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
@@ -1544,7 +1544,7 @@ // Bubble step - Address bar TutorialDescription::BubbleStep(kOmniboxElementId) .SetBubbleBodyText(IDS_TUTORIAL_LENS_OVERLAY_CLICK_ADDRESS_BAR) - .SetBubbleArrow(HelpBubbleArrow::kTopRight), + .SetBubbleArrow(HelpBubbleArrow::kTopCenter), // Bubble step - Lens button TutorialDescription::BubbleStep(kLensOverlayPageActionIconElementId)
diff --git a/chrome/browser/ui/views/web_dialog_view_browsertest.cc b/chrome/browser/ui/views/web_dialog_view_browsertest.cc index 7407b621..e69af634 100644 --- a/chrome/browser/ui/views/web_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/web_dialog_view_browsertest.cc
@@ -66,6 +66,8 @@ base::RunLoop run_loop_; }; +} // namespace + class WebDialogBrowserTest : public InProcessBrowserTest { public: WebDialogBrowserTest() = default; @@ -123,8 +125,6 @@ } } -} // namespace - // Windows has some issues resizing windows. An off by one problem, and a // minimum size that seems too big. See http://crbug.com/52602. #if BUILDFLAG(IS_WIN)
diff --git a/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc b/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc index 38b0cd3e..c8feaa4 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc
@@ -46,9 +46,8 @@ model_(model), web_contents_hidden_(web_contents->GetVisibility() == content::Visibility::HIDDEN) { - // TODO(crbug.com/338254375): Remove the following two lines once this is the - // default state for widgets and the delegates. - SetOwnedByWidget(false); // Already owned-by-widget as the content view. + // TODO(crbug.com/338254375): Remove the following line once this is the + // default state for widgets. SetOwnershipOfNewWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET); SetShowTitle(false);
diff --git a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_unittest.cc b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_unittest.cc index b54f2af..bb42cfb 100644 --- a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_unittest.cc +++ b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_unittest.cc
@@ -32,16 +32,6 @@ using DismissReason = content::IdentityRequestDialogController::DismissReason; class FedCmAccountSelectionViewDesktopTest; -namespace { - -constexpr char kTopFrameEtldPlusOne[] = "top-frame-example.com"; -constexpr char kIdpEtldPlusOne[] = "idp-example.com"; -constexpr char kConfigUrl[] = "https://idp-example.com/fedcm.json"; -constexpr char kLoginUrl[] = "https://idp-example.com/login"; - -constexpr char kAccountId1[] = "account_id1"; -constexpr char kAccountId2[] = "account_id2"; - // Mock AccountSelectionViewBase which tracks state. class TestAccountSelectionView : public AccountSelectionViewBase, public views::WidgetDelegate { @@ -127,6 +117,16 @@ std::vector<std::string> account_ids_; }; +namespace { + +constexpr char kTopFrameEtldPlusOne[] = "top-frame-example.com"; +constexpr char kIdpEtldPlusOne[] = "idp-example.com"; +constexpr char kConfigUrl[] = "https://idp-example.com/fedcm.json"; +constexpr char kLoginUrl[] = "https://idp-example.com/login"; + +constexpr char kAccountId1[] = "account_id1"; +constexpr char kAccountId2[] = "account_id2"; + // Mock version of FedCmModalDialogView for injection during tests. class MockFedCmModalDialogView : public FedCmModalDialogView { public:
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc index f1fd5450..c355764e 100644 --- a/chrome/browser/ui/webui/settings/settings_ui.cc +++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -91,6 +91,7 @@ #include "chrome/grit/settings_resources_map.h" #include "components/account_manager_core/account_manager_facade.h" #include "components/autofill/content/browser/content_autofill_client.h" +#include "components/autofill/core/browser/data_manager/payments/payments_data_manager.h" #include "components/autofill/core/browser/payments/bnpl_manager.h" #include "components/autofill/core/browser/payments/payments_autofill_client.h" #include "components/commerce/core/commerce_feature_list.h" @@ -419,8 +420,8 @@ "shouldShowPayOverTimeSettings", autofill::ContentAutofillClient::FromWebContents(web_ui->GetWebContents()) ->GetPaymentsAutofillClient() - ->GetPaymentsBnplManager() - ->ShouldShowBnplSettings()); + ->GetPaymentsDataManager() + .ShouldShowBnplSettings()); AddSettingsPageUIHandler(std::make_unique<AboutHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<ResetSettingsHandler>(profile));
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index e70fb426..4ea756eee 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -1128,6 +1128,7 @@ if (is_chromeos) { sources += [ "commands/install_app_from_verified_manifest_command_browsertest.cc", + "isolated_web_apps/isolated_web_app_device_attributes_browsertest.cc", "isolated_web_apps/isolated_web_app_managed_configuration_api_browsertest.cc", "isolated_web_apps/policy/isolated_web_app_cache_browsertest.cc", "isolated_web_apps/policy/isolated_web_app_policy_manager_ash_browsertest.cc", @@ -1200,6 +1201,7 @@ "//chrome/browser/ash/system_web_apps/test_support:test_support_ui", "//chrome/browser/ui/ash/login", "//chrome/browser/web_applications/ash/migrations:browser_tests", + "//chromeos/ash/components/system:system", ] }
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_device_attributes_browsertest.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_device_attributes_browsertest.cc new file mode 100644 index 0000000..024e198 --- /dev/null +++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_device_attributes_browsertest.cc
@@ -0,0 +1,219 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <tuple> + +#include "chrome/browser/ash/login/test/device_state_mixin.h" +#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" +#include "chrome/browser/ash/policy/core/device_policy_cros_test_helper.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h" +#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_server_mixin.h" +#include "chrome/browser/web_applications/isolated_web_apps/test/isolated_web_app_builder.h" +#include "chrome/browser/web_applications/isolated_web_apps/test/policy_test_utils.h" +#include "chrome/browser/web_applications/test/web_app_test_observers.h" +#include "chrome/browser/web_applications/web_app_install_info.h" +#include "chrome/common/pref_names.h" +#include "chromeos/ash/components/dbus/session_manager/session_manager_client.h" +#include "chromeos/ash/components/system/fake_statistics_provider.h" +#include "components/account_id/account_id.h" +#include "components/prefs/pref_service.h" +#include "components/user_manager/scoped_user_manager.h" +#include "components/web_package/test_support/signed_web_bundles/key_pair.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features_generated.h" + +namespace web_app { +namespace { + +using ::testing::Eq; +using ::testing::HasSubstr; + +constexpr std::array<const char*, 5> kDeviceAttributeNames = { + "AnnotatedAssetId", "AnnotatedLocation", "DirectoryId", "Hostname", + "SerialNumber"}; + +content::EvalJsResult CallDeviceAttributesApi( + const content::ToRenderFrameHost& frame, + const std::string& attribute_name) { + return content::EvalJs( + frame, base::ReplaceStringPlaceholders("navigator.managed.get$1()", + {attribute_name}, nullptr)); +} + +constexpr char kDeviceAnnotatedAssetId[] = "iwa_test_asset_id"; +constexpr char kDeviceAnnotatedLocation[] = "iwa_test_location"; +constexpr char kDeviceDirectoryApiId[] = "iwa_test_directory_id"; +constexpr char kDeviceHostname[] = "iwa_test_hostname"; +constexpr char kDeviceSerialNumber[] = "iwa_test_serial_number"; + +constexpr std::array<const char*, 5> kExpectedDeviceAttributeValues = { + kDeviceAnnotatedAssetId, kDeviceAnnotatedLocation, kDeviceDirectoryApiId, + kDeviceHostname, kDeviceSerialNumber}; + +const AccountId kManagedUserAccountId = + AccountId::FromUserEmail("example@example.com"); + +constexpr char kPermissionsPolicyError[] = + "Permissions-Policy: device-attributes are disabled."; + +constexpr char kAdminPolicyError[] = + "The current origin cannot use this web API because it is not allowed by " + "the DeviceAttributesAllowedForOrigins policy."; + +} // namespace + +class IsolatedWebAppDeviceAttributesBrowserTest + : public IsolatedWebAppBrowserTestHarness, + public ::testing::WithParamInterface<std::tuple<bool, bool, bool>> { + public: + IsolatedWebAppDeviceAttributesBrowserTest() { + fake_statistics_provider_.SetVpdStatus( + ash::system::StatisticsProvider::VpdStatus::kValid); + if (IsFeatureFlagEnabled()) { + features_.InitAndEnableFeature( + blink::features::kDeviceAttributesPermissionPolicy); + } else { + features_.InitAndDisableFeature( + blink::features::kDeviceAttributesPermissionPolicy); + } + } + void SetUpInProcessBrowserTestFixture() override { + if (!ash::SessionManagerClient::Get()) { + ash::SessionManagerClient::InitializeFakeInMemory(); + } + IsolatedWebAppBrowserTestHarness::SetUpInProcessBrowserTestFixture(); + } + + protected: + bool IsFeatureFlagEnabled() { return std::get<0>(GetParam()); } + bool IsPermissionsPolicyGranted() { return std::get<1>(GetParam()); } + bool IsAdminPolicyAllowed() { return std::get<2>(GetParam()); } + + void AllowDeviceAttributesForOrigin(const std::string& origin) { + profile()->GetPrefs()->SetList(prefs::kDeviceAttributesAllowedForOrigins, + base::Value::List().Append(origin)); + } + + void SetUpOnMainThread() override { + IsolatedWebAppBrowserTestHarness::SetUpOnMainThread(); + ash::system::StatisticsProvider::SetTestProvider( + &fake_statistics_provider_); + SetDevicePolicies(); + } + + std::unique_ptr<user_manager::ScopedUserManager> GetLoggedInAffiliatedUser() { + auto fake_user_manager = std::make_unique<ash::FakeChromeUserManager>(); + fake_user_manager->AddUserWithAffiliation(kManagedUserAccountId, true); + fake_user_manager->LoginUser(kManagedUserAccountId); + return std::make_unique<user_manager::ScopedUserManager>( + std::move(fake_user_manager)); + } + + IsolatedWebAppUrlInfo InstallApp( + bool device_attributes_permissions_policy_enabled) { + auto web_bundle_id = web_package::test::GetDefaultEd25519WebBundleId(); + auto iwa_url_info = + web_app::IsolatedWebAppUrlInfo::CreateFromSignedWebBundleId( + web_bundle_id); + + web_app::WebAppTestInstallObserver observer(profile()); + observer.BeginListening({iwa_url_info.app_id()}); + + auto manifest_builder = ManifestBuilder(); + if (device_attributes_permissions_policy_enabled) { + manifest_builder.AddPermissionsPolicy( + network::mojom::PermissionsPolicyFeature::kDeviceAttributes, true, + {}); + } + isolated_web_app_update_server_mixin_.AddBundle( + IsolatedWebAppBuilder(manifest_builder) + .BuildBundle(web_bundle_id, + {web_package::test::GetDefaultEd25519KeyPair()})); + web_app::test::AddForceInstalledIwaToPolicy( + profile()->GetPrefs(), + isolated_web_app_update_server_mixin_.CreateForceInstallPolicyEntry( + web_bundle_id)); + + EXPECT_EQ(iwa_url_info.app_id(), observer.Wait()); + return iwa_url_info; + } + + private: + void SetDevicePolicies() { + device_policy().policy_data().set_annotated_asset_id( + kDeviceAnnotatedAssetId); + device_policy().policy_data().set_annotated_location( + kDeviceAnnotatedLocation); + device_policy().policy_data().set_directory_api_id(kDeviceDirectoryApiId); + device_policy() + .payload() + .mutable_network_hostname() + ->set_device_hostname_template(kDeviceHostname); + policy_helper_.RefreshDevicePolicy(); + + fake_statistics_provider_.SetMachineStatistic(ash::system::kSerialNumberKey, + kDeviceSerialNumber); + } + policy::DevicePolicyBuilder& device_policy() { + return *(policy_helper_.device_policy()); + } + + ash::DeviceStateMixin device_state_{ + &mixin_host_, + ash::DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED}; + ash::system::ScopedFakeStatisticsProvider fake_statistics_provider_; + base::test::ScopedFeatureList features_; + policy::DevicePolicyCrosTestHelper policy_helper_; + web_app::IsolatedWebAppUpdateServerMixin + isolated_web_app_update_server_mixin_{&mixin_host_}; +}; + +IN_PROC_BROWSER_TEST_P(IsolatedWebAppDeviceAttributesBrowserTest, + ObtainingDeviceAttributes) { + IsolatedWebAppUrlInfo url_info = InstallApp(IsPermissionsPolicyGranted()); + if (IsAdminPolicyAllowed()) { + AllowDeviceAttributesForOrigin(url_info.origin().Serialize()); + } + std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_ = + GetLoggedInAffiliatedUser(); + content::RenderFrameHost* app_frame = OpenApp(url_info.app_id()); + ASSERT_NE(app_frame, nullptr); + ASSERT_EQ(kDeviceAttributeNames.size(), + kExpectedDeviceAttributeValues.size()); + bool device_attributes_should_work = IsFeatureFlagEnabled() + ? IsPermissionsPolicyGranted() + : IsAdminPolicyAllowed(); + for (size_t i = 0; i < kDeviceAttributeNames.size(); ++i) { + if (device_attributes_should_work) { + EXPECT_EQ(kExpectedDeviceAttributeValues[i], + CallDeviceAttributesApi(app_frame, kDeviceAttributeNames[i])); + } else { + EXPECT_THAT( + CallDeviceAttributesApi(app_frame, kDeviceAttributeNames[i]).error, + HasSubstr(IsFeatureFlagEnabled() ? kPermissionsPolicyError + : kAdminPolicyError)); + } + } +} + +INSTANTIATE_TEST_SUITE_P( + All, + IsolatedWebAppDeviceAttributesBrowserTest, + ::testing::Combine(::testing::Bool(), // feature flag + ::testing::Bool(), // permissions policy + ::testing::Bool() // admin policy + ), + [](const ::testing::TestParamInfo<std::tuple<bool, bool, bool>>& info) { + // Generate a descriptive name for each test case. + return base::StringPrintf( + "FeatureFlag%s_PermissionsPolicy%s_AdminPolicy%s", + std::get<0>(info.param) ? "Enabled" : "Disabled", + std::get<1>(info.param) ? "Granted" : "Denied", + std::get<2>(info.param) ? "Allowed" : "Denied"); + }); +} // namespace web_app
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index 3a54e55..e80b0bd 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1744027037-926670ded2fb33e529ab1d3426230000fb365854-b1f3fd44213da2ace27fa16878446d0197e54f0f.profdata +chrome-android32-main-1744048751-cdd6f0152f5419d88b8abc9a19346fc8ec2d6970-4c01c407f87e60a9c0d41f6372df70364a780128.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 4b5afe62..5c5083e 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1744037444-563ed695d1fdc36369f6e9bf28588bc50408fda5-fa7e352f809f702de6de6495c42dd2294a3d3979.profdata +chrome-android64-main-1744052807-caabcc0ff5bfedfc3cff1d3f5c895df2f2764e5b-d8fa5193bebed721a11659ea3d585daffb055115.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index bd26b8d..c4481f0 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1744027037-3d21438a38621460416bee845916c1efa82126a2-b1f3fd44213da2ace27fa16878446d0197e54f0f.profdata +chrome-linux-main-1744048751-a2f2a3f5d6f3867ca7c38f1474a0f80fd330650f-4c01c407f87e60a9c0d41f6372df70364a780128.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 611b811e..a90439f 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1744041557-557bde7c5c224ba3f4529f1d4594033afeee4912-bc16abbc25d71745fc414c65df8046bd87aa2197.profdata +chrome-mac-arm-main-1744055965-91ffa3508ce63c9e79b0b8ee0e9dccfc1b63d6e9-f4e9a3c7f4b43b0229b0f4fd2607d581467f22b1.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 1d8df4a..c500f75 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1744027037-9b7b56a223482bf3e5e0b4c9e1fe797c824e38cb-b1f3fd44213da2ace27fa16878446d0197e54f0f.profdata +chrome-mac-main-1744048751-effec5453030ec23c37b47cefcea87f61155b712-4c01c407f87e60a9c0d41f6372df70364a780128.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index 5e31328..34b2dbd0 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1744027037-b129fdcd57930d9331ed5093c1d951ab99be60d7-b1f3fd44213da2ace27fa16878446d0197e54f0f.profdata +chrome-win-arm64-main-1744048751-891667e5bebfe740306e51207ebb4d374f026ff1-4c01c407f87e60a9c0d41f6372df70364a780128.profdata
diff --git a/chrome/release_scripts b/chrome/release_scripts index ebacc43..b0e8d98 160000 --- a/chrome/release_scripts +++ b/chrome/release_scripts
@@ -1 +1 @@ -Subproject commit ebacc4377d49ec15f4d19e061d5d9ed344cffc1e +Subproject commit b0e8d98f5141c3b50870406a7cf1e090806b2f8e
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index f040b43..d3394cb6 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2946,7 +2946,6 @@ "../browser/content_index/content_index_browsertest.cc", "../browser/content_language/content_language_browsertest.cc", "../browser/contextual_cueing/contextual_cueing_service_browsertest.cc", - "../browser/contextual_cueing/zero_state_suggestions_page_data_browsertest.cc", "../browser/crash_recovery_browsertest.cc", "../browser/custom_handlers/protocol_handler_registry_browsertest.cc", "../browser/data_saver/data_saver_browsertest.cc", @@ -3566,6 +3565,7 @@ if (enable_glic) { sources += [ + "../browser/contextual_cueing/zero_state_suggestions_page_data_browsertest.cc", "../browser/ui/views/tabs/glic_button_browsertest.cc", "../browser/ui/webui/settings/glic_handler_browsertest.cc", ]
diff --git a/chrome/test/base/web_ui_mocha_browser_test.cc b/chrome/test/base/web_ui_mocha_browser_test.cc index 5d30dc3..42299b4e 100644 --- a/chrome/test/base/web_ui_mocha_browser_test.cc +++ b/chrome/test/base/web_ui_mocha_browser_test.cc
@@ -243,7 +243,33 @@ // Report individual JS test results if reporting is enabled. if (sub_test_reporter_) { + // ResultDB limits test identifiers to 512 bytes. However, GTest code isn't + // privy to the exact schema used (for that, see TestResultsTracker:: + // SaveSummaryAsJSON). Here, it is simply assumed that test name length can + // be estimated as a sum of the lengths of the GTest fixture name, GTest + // test name, and Mocha JS test name, plus a few extra bytes for delimiters. + // Retrieve GTest fixture name and GTest test name to build an estimate. + const testing::TestInfo* info = + testing::UnitTest::GetInstance()->current_test_info(); + CHECK(info); + for (const auto& sub_test_result : sub_test_results) { + // Estimate the final test identifier length. Allocate 3 bytes for + // delimiters. + size_t estimate = strlen(info->name()) + strlen(info->test_suite_name()) + + sub_test_result.name.size() + 3ul; + + if (estimate > 512ul) { + testing::Message msg; + msg << "Test name too long. Test identifier size estimate is " + << estimate << ". ResultDB limits test identifiers to 512 bytes. " + << "Please reduce total test name length by at least " + << (estimate - 512ul) << " bytes. name=\"" << info->name() + << "\", test_suite_name=\"" << info->test_suite_name() + << "\", js_test_name=\"" << sub_test_result.name << "\""; + return testing::AssertionFailure(msg); + } + sub_test_reporter_->Report(sub_test_result.name, sub_test_result.duration, sub_test_result.failure_reason); } @@ -278,8 +304,12 @@ RunTest(file, trigger, /*skip_test_loader=*/true); } -void WebUIMochaBrowserTest::DisableSubTestResultReporting() { - sub_test_reporter_.reset(); +void WebUIMochaBrowserTest::SetSubTestResultReportingEnabled(bool enabled) { + if (enabled) { + sub_test_reporter_ = std::make_unique<SubTestReporter>(); + } else { + sub_test_reporter_.reset(); + } } testing::AssertionResult WebUIMochaBrowserTest::SimulateTestLoader(
diff --git a/chrome/test/base/web_ui_mocha_browser_test.h b/chrome/test/base/web_ui_mocha_browser_test.h index 88a7474..68d839b 100644 --- a/chrome/test/base/web_ui_mocha_browser_test.h +++ b/chrome/test/base/web_ui_mocha_browser_test.h
@@ -47,14 +47,6 @@ std::optional<std::string_view> failure_message) const; }; -// Production implementation of SubTestReporter interface. -class SubTestReporterImpl : public SubTestReporter { - public: - void Report(std::string_view name, - testing::TimeInMillis elapsed_time, - std::optional<std::string_view> failure_message) const override; -}; - namespace webui { // Convert all non-alphanumeric characters to underscore in-place. Assumes @@ -110,10 +102,10 @@ const std::string& trigger, const bool& skip_test_loader); - // Tests may optionally call this before calling RunTest to opt out of - // SubTestResult reporting. This is useful for GTests that run intentionally - // failing JS tests. - void DisableSubTestResultReporting(); + // Tests may optionally call this before calling RunTest to opt into or out + // of SubTestResult reporting. This is useful for GTests that run + // intentionally failing JS tests. + void SetSubTestResultReportingEnabled(bool enabled); // Hook for subclasses that need to perform additional setup steps that // involve the WebContents, before the Mocha test runs.
diff --git a/chrome/test/base/web_ui_mocha_browser_test_browsertest.cc b/chrome/test/base/web_ui_mocha_browser_test_browsertest.cc index 9a4ad98..70568e16 100644 --- a/chrome/test/base/web_ui_mocha_browser_test_browsertest.cc +++ b/chrome/test/base/web_ui_mocha_browser_test_browsertest.cc
@@ -109,7 +109,7 @@ s_test_ = this; // Some of these tests contain intentionally failing JS tests. // These should not be reported individually. - DisableSubTestResultReporting(); + SetSubTestResultReportingEnabled(false); } protected: @@ -165,11 +165,21 @@ EXPECT_FATAL_FAILURE(RunTestStatic("does_not_exist.js", "mocha.run();"), ""); } +// Test that when the test name is too long, the test fails. +IN_PROC_BROWSER_TEST_F(WebUIMochaSuccessFailureTest, TestWithLongNameFails) { + // SubTestResult reporting must be enabled to reach the code that fails the + // test with a long test name. Though it is enabled, it should stop short of + // reporting any failing SubTestResults. + SetSubTestResultReportingEnabled(true); + + EXPECT_FATAL_FAILURE( + RunTestStatic("js/long_test_name_test_suite_self_test.js", + "mocha.run();"), + "Test name too long"); +} + // Test that when the underlying Mocha test fails, the C++ test also fails. IN_PROC_BROWSER_TEST_F(WebUIMochaSuccessFailureTest, TestFailureFails) { - // This JS test is expected to fail, so it should not be reported. - DisableSubTestResultReporting(); - EXPECT_FATAL_FAILURE( RunTestStatic("js/test_suite_self_test.js", "mocha.fgrep('TestSuiteSelfTest Failure').run();"), @@ -221,6 +231,20 @@ "chrome://webui-test/does_not_exist.js"); } +// Test that when the test name is too long, the test fails. +IN_PROC_BROWSER_TEST_F(WebUIMochaSuccessFailureWithoutTestLoaderTest, + TestWithLongNameFails) { + // SubTestResult reporting must be enabled to reach the code that fails the + // test with a long test name. Though it is enabled, it should stop short of + // reporting any failing SubTestResults. + SetSubTestResultReportingEnabled(true); + + EXPECT_FATAL_FAILURE( + RunTestStatic("js/long_test_name_test_suite_self_test.js", + "mocha.run();"), + "Test name too long"); +} + // Test that when the underlying Mocha test fails, the C++ test also fails. IN_PROC_BROWSER_TEST_F(WebUIMochaSuccessFailureWithoutTestLoaderTest, TestFailureFails) {
diff --git a/chrome/test/data/webui/js/BUILD.gn b/chrome/test/data/webui/js/BUILD.gn index 0605281..72e64771 100644 --- a/chrome/test/data/webui/js/BUILD.gn +++ b/chrome/test/data/webui/js/BUILD.gn
@@ -20,6 +20,7 @@ "static_types_test.ts", "store_test.ts", "test_suite_self_test.ts", + "long_test_name_test_suite_self_test.ts", "util_test.ts", ] ts_definitions = [
diff --git a/chrome/test/data/webui/js/long_test_name_test_suite_self_test.ts b/chrome/test/data/webui/js/long_test_name_test_suite_self_test.ts new file mode 100644 index 0000000..75dca0b --- /dev/null +++ b/chrome/test/data/webui/js/long_test_name_test_suite_self_test.ts
@@ -0,0 +1,17 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assertTrue} from 'chrome://webui-test/chai_assert.js'; + +const MAX_LIMIT = 512; + +const testName = 'a'.repeat(MAX_LIMIT + 1); + +// Test suite used to test the WebUIMochaBrowserTest C++ class itself. See +// chrome/test/base/web_ui_mocha_browser_test_browsertest.cc for usages. +suite('LongTestNameTestSuiteSelfTest', function() { + test(testName, function() { + assertTrue(true); + }); +});
diff --git a/chrome/test/interaction/interactive_browser_test_interactive_uitest.cc b/chrome/test/interaction/interactive_browser_test_interactive_uitest.cc index 49d058e..3da3ce3 100644 --- a/chrome/test/interaction/interactive_browser_test_interactive_uitest.cc +++ b/chrome/test/interaction/interactive_browser_test_interactive_uitest.cc
@@ -693,6 +693,8 @@ BEGIN_METADATA(HoverDetectionView) END_METADATA +} // namespace + class HoverDetectionBubbleView : public views::FlexLayoutView, public views::BubbleDialogDelegate { METADATA_HEADER(HoverDetectionBubbleView, views::FlexLayoutView) @@ -700,6 +702,8 @@ public: explicit HoverDetectionBubbleView(views::View* anchor_view) : BubbleDialogDelegate(anchor_view, views::BubbleBorder::TOP_RIGHT) { + SetOwnedByWidget(true); + auto* view = AddChildView(std::make_unique<HoverDetectionView>()); view->SetProperty(views::kElementIdentifierKey, kHoverView1Id); views_.push_back(view); @@ -728,8 +732,6 @@ BEGIN_METADATA(HoverDetectionBubbleView) END_METADATA -} // namespace - class InteractiveBrowserTestHoverUiTest : public InteractiveBrowserTestUiTest { public: InteractiveBrowserTestHoverUiTest() = default;
diff --git a/chrome/updater/update_usage_stats_task.h b/chrome/updater/update_usage_stats_task.h index a739561e..bc40092 100644 --- a/chrome/updater/update_usage_stats_task.h +++ b/chrome/updater/update_usage_stats_task.h
@@ -6,6 +6,7 @@ #define CHROME_UPDATER_UPDATE_USAGE_STATS_TASK_H_ #include <memory> +#include <optional> #include <string> #include <vector> @@ -39,19 +40,38 @@ // have usage stats enabled. This information is stored in the registry on // Windows, and in a crashpad database found in the `ApplicationSupport` // directory on MacOS. - virtual bool AnyAppEnablesUsageStats() = 0; + virtual bool AnyAppEnablesUsageStats() const = 0; + + // Returns true if the updater is allowed to send detailed event logs to an + // external endpoint. Logging is allowed only if the following conditions are + // all met: + // 1) The updater manages an app (an `event_logging_permission_provider`) + // responsible for granting the updater permission to send remote + // logging events. + // 2) The `event_logging_permission_provider` app has usage stats enabled. + // 3) The updater manages no other apps. That is, the apps managed by the + // updater are a subset of {Updater, Enterprise Companion App, + // event_logging_permission_provider}. + virtual bool RemoteEventLoggingAllowed() const = 0; static std::unique_ptr<UsageStatsProvider> Create(UpdaterScope scope); private: friend class UpdateUsageStatsTaskTest; + // Creates a UsageStatsProvider that checks apps in the specified locations + // (install directories on MacOS and registry paths on Windows), as well as + // uses the specified app as an event logging permission provider. The app is + // identified via an appid on Windows and as the name of the application + // directory on MacOS. #if BUILDFLAG(IS_WIN) static std::unique_ptr<UsageStatsProvider> Create( HKEY hive, + std::optional<std::wstring> event_logging_permission_provider, std::vector<std::wstring> registry_paths); #elif BUILDFLAG(IS_MAC) static std::unique_ptr<UsageStatsProvider> Create( + std::optional<std::string> event_logging_permission_provider, std::vector<base::FilePath> app_directories); #endif };
diff --git a/chrome/updater/update_usage_stats_task_linux.cc b/chrome/updater/update_usage_stats_task_linux.cc index e498500..18686c31 100644 --- a/chrome/updater/update_usage_stats_task_linux.cc +++ b/chrome/updater/update_usage_stats_task_linux.cc
@@ -21,7 +21,8 @@ UsageStatsProviderImpl() = default; // TODO(crbug.com/40821596): Implement. - bool AnyAppEnablesUsageStats() override { return false; } + bool AnyAppEnablesUsageStats() const override { return false; } + bool RemoteEventLoggingAllowed() const override { return false; } }; std::unique_ptr<UsageStatsProvider> UsageStatsProvider::Create(
diff --git a/chrome/updater/update_usage_stats_task_mac.mm b/chrome/updater/update_usage_stats_task_mac.mm index cd260ef5..3e9eea3d 100644 --- a/chrome/updater/update_usage_stats_task_mac.mm +++ b/chrome/updater/update_usage_stats_task_mac.mm
@@ -14,6 +14,7 @@ #include "base/files/file_enumerator.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "chrome/enterprise_companion/installer_paths.h" #include "chrome/updater/updater_branding.h" #include "chrome/updater/updater_scope.h" #include "chrome/updater/util/mac_util.h" @@ -45,12 +46,15 @@ class UsageStatsProviderImpl : public UsageStatsProvider { public: explicit UsageStatsProviderImpl( + std::optional<std::string> event_logging_permission_provider, std::vector<base::FilePath> install_directories) - : install_directories_(std::move(install_directories)) {} + : event_logging_permission_provider_( + std::move(event_logging_permission_provider)), + install_directories_(std::move(install_directories)) {} // Returns true if any app directory under the associated // `install_directories` has usage stats enabled. - bool AnyAppEnablesUsageStats() override { + bool AnyAppEnablesUsageStats() const override { return std::ranges::any_of( GetAppDirectories(), [](const base::FilePath& app_dir) { return app_dir.BaseName().value() != PRODUCT_FULLNAME_STRING && @@ -58,7 +62,7 @@ }); } - std::vector<base::FilePath> GetAppDirectories() { + std::vector<base::FilePath> GetAppDirectories() const { std::vector<base::FilePath> all_apps; for (const base::FilePath& install_dir : install_directories_) { base::FileEnumerator(install_dir, @@ -71,7 +75,34 @@ return all_apps; } + bool RemoteEventLoggingAllowed() const override { + if (!event_logging_permission_provider_) { + return false; + } + + if (std::ranges::any_of( + GetAppDirectories(), [this](const base::FilePath& app_dir) { + std::string name = app_dir.BaseName().value(); + std::optional<base::FilePath> enterprise_companion_app_path = + enterprise_companion::GetInstallDirectory(); + return name != PRODUCT_FULLNAME_STRING && + name != event_logging_permission_provider_ && + (!enterprise_companion_app_path || + name != + enterprise_companion_app_path->BaseName().value()); + })) { + return false; + } + + return std::ranges::any_of( + install_directories_, [this](const base::FilePath& install_dir) { + return AppAllowsUsageStats( + install_dir.Append(*event_logging_permission_provider_)); + }); + } + private: + std::optional<std::string> event_logging_permission_provider_; std::vector<base::FilePath> install_directories_; }; @@ -81,12 +112,14 @@ std::unique_ptr<UsageStatsProvider> UsageStatsProvider::Create( UpdaterScope scope) { return UsageStatsProvider::Create( - GetApplicationSupportDirectoriesForUsers(scope)); + std::nullopt, GetApplicationSupportDirectoriesForUsers(scope)); } std::unique_ptr<UsageStatsProvider> UsageStatsProvider::Create( + std::optional<std::string> event_logging_permission_provider, std::vector<base::FilePath> install_directories) { return std::make_unique<UsageStatsProviderImpl>( + std::move(event_logging_permission_provider), std::move(install_directories)); }
diff --git a/chrome/updater/update_usage_stats_task_unittest.cc b/chrome/updater/update_usage_stats_task_unittest.cc index 6ff7a23d..1d9e44e 100644 --- a/chrome/updater/update_usage_stats_task_unittest.cc +++ b/chrome/updater/update_usage_stats_task_unittest.cc
@@ -30,12 +30,14 @@ #if BUILDFLAG(IS_MAC) #include "base/files/scoped_temp_dir.h" +#include "chrome/enterprise_companion/installer_paths.h" #include "chrome/updater/util/mac_util.h" #elif BUILDFLAG(IS_WIN) #include "base/strings/sys_string_conversions.h" #include "base/test/test_reg_util_win.h" #include "base/win/registry.h" #include "base/win/windows_types.h" +#include "chrome/enterprise_companion/global_constants.h" #include "chrome/updater/util/win_util.h" #include "chrome/updater/win/win_constants.h" #endif @@ -43,8 +45,28 @@ namespace updater { class UpdateUsageStatsTaskTest : public testing::Test { - protected: + protected: + std::string fake_permission_provider_ = "UsageStatsTestPermissionProvider"; #if BUILDFLAG(IS_MAC) + base::ScopedTempDir fake_user_directory_; + base::ScopedTempDir fake_system_directory_; + + std::unique_ptr<UsageStatsProvider> + UsageStatsProviderWithNullPermissionProvider() { + return UsageStatsProvider::Create(std::nullopt, InstallDirectories()); + } + + void SetUpdaterUsageStats(bool enabled, UpdaterScope scope) { + SetAppUsageStats(PRODUCT_FULLNAME_STRING, enabled, scope); + } + + void SetCECAUsageStats(bool enabled, UpdaterScope scope) { + std::optional<base::FilePath> ceca_path = + enterprise_companion::GetInstallDirectory(); + ASSERT_TRUE(ceca_path); + SetAppUsageStats(ceca_path->BaseName().value(), enabled, scope); + } + void SetAppUsageStats(const std::string& app_id, bool enabled, UpdaterScope scope) { @@ -63,15 +85,25 @@ void SetUp() override { ASSERT_TRUE(fake_user_directory_.CreateUniqueTempDir()); ASSERT_TRUE(fake_system_directory_.CreateUniqueTempDir()); - std::vector<base::FilePath> install_directories( - {fake_user_directory_.GetPath()}); - if (IsSystemInstall(scope_)) { - install_directories.push_back(fake_system_directory_.GetPath()); - } - usage_stats_provider_ = UsageStatsProvider::Create(install_directories); + usage_stats_provider_ = UsageStatsProvider::Create( + fake_permission_provider_, InstallDirectories()); } #elif BUILDFLAG(IS_WIN) + + std::unique_ptr<UsageStatsProvider> + UsageStatsProviderWithNullPermissionProvider() { + return UsageStatsProvider::Create(hive_, std::nullopt, + InstallRegistryPaths()); + } + + void SetUpdaterUsageStats(bool enabled, UpdaterScope scope) { + SetAppUsageStats(kUpdaterAppId, enabled, scope); + } + + void SetCECAUsageStats(bool enabled, UpdaterScope scope) { + SetAppUsageStats(enterprise_companion::kCompanionAppId, enabled, scope); + } void SetAppUsageStats(const std::string& app_id, bool enabled, UpdaterScope scope) { @@ -91,11 +123,9 @@ ERROR_SUCCESS); ASSERT_EQ(key.Create(hive_, system_key_path_.c_str(), Wow6432(KEY_WRITE)), ERROR_SUCCESS); - std::vector<std::wstring> key_paths({user_key_path_}); - if (IsSystemInstall(scope_)) { - key_paths.push_back(system_key_path_); - } - usage_stats_provider_ = UsageStatsProvider::Create(hive_, key_paths); + usage_stats_provider_ = UsageStatsProvider::Create( + hive_, base::UTF8ToWide(fake_permission_provider_), + InstallRegistryPaths()); } void TearDown() override { @@ -113,9 +143,23 @@ private: #if BUILDFLAG(IS_MAC) - base::ScopedTempDir fake_user_directory_; - base::ScopedTempDir fake_system_directory_; + std::vector<base::FilePath> InstallDirectories() { + std::vector<base::FilePath> install_directories( + {fake_user_directory_.GetPath()}); + if (IsSystemInstall(scope_)) { + install_directories.push_back(fake_system_directory_.GetPath()); + } + return install_directories; + } #elif BUILDFLAG(IS_WIN) + + std::vector<std::wstring> InstallRegistryPaths() { + std::vector<std::wstring> key_paths({user_key_path_}); + if (IsSystemInstall(scope_)) { + key_paths.push_back(system_key_path_); + } + return key_paths; + } HKEY hive_ = UpdaterScopeToHKeyRoot(GetUpdaterScopeForTesting()); std::wstring user_key_path_ = base::StrCat({UPDATER_KEY, L"UsageStatsProviderTestUserKey\\"}); @@ -126,7 +170,10 @@ #if BUILDFLAG(IS_LINUX) TEST_F(UpdateUsageStatsTaskTest, LinuxAlwaysFalse) { - ASSERT_FALSE(UsageStatsProvider::Create(scope_)->AnyAppEnablesUsageStats()); + std::unique_ptr<UsageStatsProvider> usage_stats_provider = + UsageStatsProvider::Create(scope_); + ASSERT_FALSE(usage_stats_provider->AnyAppEnablesUsageStats()); + ASSERT_FALSE(usage_stats_provider->RemoteEventLoggingAllowed()); } #else @@ -148,7 +195,7 @@ TEST_F(UpdateUsageStatsTaskTest, UserInstallIgnoresSystem) { if (IsSystemInstall(scope_)) { - return; + GTEST_SKIP() << "Not applicable to system-scoped installs"; } SetAppUsageStats("app1", false, UpdaterScope::kUser); SetAppUsageStats("app1", true, UpdaterScope::kSystem); @@ -157,13 +204,76 @@ TEST_F(UpdateUsageStatsTaskTest, SystemInstallLooksAtUser) { if (!IsSystemInstall(scope_)) { - return; + GTEST_SKIP() << "Not applicable to user-scoped installs"; } SetAppUsageStats("app1", true, UpdaterScope::kUser); SetAppUsageStats("app1", false, UpdaterScope::kSystem); ASSERT_TRUE(usage_stats_provider_->AnyAppEnablesUsageStats()); } +TEST_F(UpdateUsageStatsTaskTest, NullPermissionProviderReturnsFalse) { + ASSERT_FALSE(UsageStatsProviderWithNullPermissionProvider() + ->RemoteEventLoggingAllowed()); +} + +TEST_F(UpdateUsageStatsTaskTest, NullPermissionProviderIgnoresAppPermissions) { + SetAppUsageStats("app1", true, scope_); + SetAppUsageStats("app2", false, scope_); + SetAppUsageStats(fake_permission_provider_, true, scope_); + ASSERT_FALSE(UsageStatsProviderWithNullPermissionProvider() + ->RemoteEventLoggingAllowed()); +} + +TEST_F(UpdateUsageStatsTaskTest, PermissionProviderAllowsRemoteLogging) { + SetAppUsageStats(fake_permission_provider_, true, scope_); + ASSERT_TRUE(usage_stats_provider_->RemoteEventLoggingAllowed()); +} + +TEST_F(UpdateUsageStatsTaskTest, + PermissionProviderAllowsRemoteLoggingWithCECAAndUpdater) { + SetUpdaterUsageStats(true, scope_); + SetCECAUsageStats(true, scope_); + SetAppUsageStats(fake_permission_provider_, true, scope_); + ASSERT_TRUE(usage_stats_provider_->RemoteEventLoggingAllowed()); +} + +TEST_F(UpdateUsageStatsTaskTest, UsageStatsProviderChecksPermissionProvider) { + SetUpdaterUsageStats(true, scope_); + SetCECAUsageStats(true, scope_); + SetAppUsageStats(fake_permission_provider_, false, scope_); + ASSERT_FALSE(usage_stats_provider_->RemoteEventLoggingAllowed()); +} + +TEST_F(UpdateUsageStatsTaskTest, + PermissionProviderDisallowsRemoteLoggingWithOtherAppDisabled) { + SetUpdaterUsageStats(true, scope_); + SetCECAUsageStats(true, scope_); + SetAppUsageStats(fake_permission_provider_, true, scope_); + SetAppUsageStats("unsupported_app", false, scope_); + ASSERT_FALSE(usage_stats_provider_->RemoteEventLoggingAllowed()); +} + +TEST_F(UpdateUsageStatsTaskTest, + PermissionProviderDisallowsRemoteLoggingWithOtherAppEnabled) { + SetUpdaterUsageStats(true, scope_); + SetCECAUsageStats(true, scope_); + SetAppUsageStats(fake_permission_provider_, true, scope_); + SetAppUsageStats("unsupported_app", true, scope_); + ASSERT_FALSE(usage_stats_provider_->RemoteEventLoggingAllowed()); +} + +TEST_F(UpdateUsageStatsTaskTest, + SystemPermissionProviderAllowsRemoteLoggingWithUserAppEnabled) { + if (!IsSystemInstall(scope_)) { + GTEST_SKIP() << "Not applicable to user-scoped installs"; + } + SetUpdaterUsageStats(true, scope_); + SetCECAUsageStats(true, scope_); + SetAppUsageStats(fake_permission_provider_, true, UpdaterScope::kUser); + SetAppUsageStats(fake_permission_provider_, false, UpdaterScope::kSystem); + ASSERT_TRUE(usage_stats_provider_->RemoteEventLoggingAllowed()); +} + #endif } // namespace updater
diff --git a/chrome/updater/update_usage_stats_task_win.cc b/chrome/updater/update_usage_stats_task_win.cc index 205a925..aa2f89e 100644 --- a/chrome/updater/update_usage_stats_task_win.cc +++ b/chrome/updater/update_usage_stats_task_win.cc
@@ -6,6 +6,7 @@ #include <algorithm> #include <memory> +#include <optional> #include <string> #include <vector> @@ -23,10 +24,16 @@ class UsageStatsProviderImpl : public UsageStatsProvider { public: - UsageStatsProviderImpl(HKEY hive, std::vector<std::wstring> key_paths) - : hive_(hive), key_paths_(std::move(key_paths)) {} + UsageStatsProviderImpl( + HKEY hive, + std::optional<std::wstring> event_logging_permission_provider, + std::vector<std::wstring> key_paths) + : hive_(hive), + event_logging_permission_provider_( + std::move(event_logging_permission_provider)), + key_paths_(std::move(key_paths)) {} - bool AnyAppEnablesUsageStats() override { + bool AnyAppEnablesUsageStats() const override { bool allowed = std::ranges::any_of( GetInstalledAppIds(), [this](const std::wstring& app_id) { if (!IsUpdaterOrCompanionApp(base::WideToUTF8(app_id)) && @@ -44,7 +51,7 @@ } private: - std::vector<std::wstring> GetInstalledAppIds() { + std::vector<std::wstring> GetInstalledAppIds() const { std::vector<std::wstring> app_ids; for (const std::wstring& path : key_paths_) { for (base::win::RegistryKeyIterator it(hive_, path.c_str(), @@ -56,7 +63,7 @@ return app_ids; } - bool AppAllowsUsageStats(const std::wstring& app_id) { + bool AppAllowsUsageStats(const std::wstring& app_id) const { return std::ranges::any_of( key_paths_, [this, app_id](std::wstring key_path) { DWORD usagestats = 0; @@ -68,17 +75,32 @@ }); } + bool RemoteEventLoggingAllowed() const override { + if (!event_logging_permission_provider_) { + return false; + } + + bool manages_additional_apps = std::ranges::any_of( + GetInstalledAppIds(), [this](const std::wstring& app_id) { + return !IsUpdaterOrCompanionApp(base::WideToUTF8(app_id)) && + (app_id != *event_logging_permission_provider_); + }); + + return !manages_additional_apps && + AppAllowsUsageStats(*event_logging_permission_provider_); + } + HKEY hive_; + std::optional<std::wstring> event_logging_permission_provider_; std::vector<std::wstring> key_paths_; }; -// Returns a usage stats provider that checks for apps under the // CLIENT_STATE_MEDIUM_KEY and CLIENT_STATE_KEY registry keys. The updater // stores installation and usage stat information in these keys. std::unique_ptr<UsageStatsProvider> UsageStatsProvider::Create( UpdaterScope scope) { return UsageStatsProvider::Create( - UpdaterScopeToHKeyRoot(scope), + UpdaterScopeToHKeyRoot(scope), std::nullopt, IsSystemInstall(scope) ? std::vector<std::wstring>( {CLIENT_STATE_KEY, CLIENT_STATE_MEDIUM_KEY}) : std::vector<std::wstring>({CLIENT_STATE_KEY})); @@ -88,8 +110,10 @@ // given registry keys. std::unique_ptr<UsageStatsProvider> UsageStatsProvider::Create( HKEY hive, + std::optional<std::wstring> event_logging_permission_provider, std::vector<std::wstring> key_paths) { - return std::make_unique<UsageStatsProviderImpl>(hive, std::move(key_paths)); + return std::make_unique<UsageStatsProviderImpl>( + hive, std::move(event_logging_permission_provider), std::move(key_paths)); } } // namespace updater
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java index 631cbe67..8690d5d 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
@@ -385,6 +385,7 @@ } @Override + @SuppressWarnings("GestureBackNavigation") public void onBackPressed() { WebContents webContents = CastWebContentsIntentUtils.getWebContents(getIntent()); if (webContents == null) {
diff --git a/chromeos/ash/components/boca/babelorca/babel_orca_consumer.cc b/chromeos/ash/components/boca/babelorca/babel_orca_consumer.cc index 44e4ee6..ce66742 100644 --- a/chromeos/ash/components/boca/babelorca/babel_orca_consumer.cc +++ b/chromeos/ash/components/boca/babelorca/babel_orca_consumer.cc
@@ -267,7 +267,8 @@ } join_group_authed_client_.reset(); auto oauth_token_fetcher = std::make_unique<OAuthTokenFetcher>( - identity_manager_, boca::kSchoolToolsAuthScope); + identity_manager_, boca::kSchoolToolsAuthScope, + /*uma_name=*/"SchoolTools"); join_group_token_manager_ = std::make_unique<TokenManagerImpl>(std::move(oauth_token_fetcher)); join_group_authed_client_ = std::make_unique<TachyonAuthedClientImpl>(
diff --git a/chromeos/ash/components/boca/babelorca/babel_orca_producer.cc b/chromeos/ash/components/boca/babelorca/babel_orca_producer.cc index 7b6f6b5..c522438 100644 --- a/chromeos/ash/components/boca/babelorca/babel_orca_producer.cc +++ b/chromeos/ash/components/boca/babelorca/babel_orca_producer.cc
@@ -11,6 +11,7 @@ #include "base/functional/bind.h" #include "base/logging.h" #include "base/memory/scoped_refptr.h" +#include "base/metrics/histogram_functions.h" #include "base/sequence_checker.h" #include "base/time/time.h" #include "chromeos/ash/components/boca/babelorca/babel_orca_caption_translator.h" @@ -29,6 +30,12 @@ #include "services/network/public/cpp/shared_url_loader_factory.h" namespace ash::babelorca { +namespace { + +constexpr char kSendingStoppedReasonUma[] = + "Ash.Boca.Babelorca.SendingStoppedReason"; + +} // namespace // static std::unique_ptr<BabelOrcaController> BabelOrcaProducer::Create( @@ -75,6 +82,10 @@ void BabelOrcaProducer::OnSessionEnded() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (in_session_ && session_captions_enabled_) { + base::UmaHistogramEnumeration(kSendingStoppedReasonUma, + SendingStoppedReason::kSessionEnded); + } in_session_ = false; session_captions_enabled_ = false; rate_limited_sender_.reset(); @@ -87,6 +98,11 @@ bool session_captions_enabled, bool translations_enabled) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (in_session_ && session_captions_enabled_ && !session_captions_enabled) { + base::UmaHistogramEnumeration( + kSendingStoppedReasonUma, + SendingStoppedReason::kSessionCaptionTurnedOff); + } if (!in_session_) { LOG(ERROR) << "Session caption config event called out of session."; return; @@ -207,6 +223,9 @@ void BabelOrcaProducer::OnSendFailed() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // TODO(crbug.com/373692250): report error. + base::UmaHistogramEnumeration( + kSendingStoppedReasonUma, + SendingStoppedReason::kTachyonSendMessagesError); LOG(ERROR) << "Transcript send permanently failed"; session_captions_enabled_ = false; rate_limited_sender_.reset();
diff --git a/chromeos/ash/components/boca/babelorca/babel_orca_producer.h b/chromeos/ash/components/boca/babelorca/babel_orca_producer.h index 9368a5a3..a495aec 100644 --- a/chromeos/ash/components/boca/babelorca/babel_orca_producer.h +++ b/chromeos/ash/components/boca/babelorca/babel_orca_producer.h
@@ -37,6 +37,18 @@ // Class to control captions handling behavior in producer mode. class BabelOrcaProducer : public BabelOrcaController { public: + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. Public for testing. + // + // LINT.IfChange(SendingStoppedReason) + enum class SendingStoppedReason { + kSessionEnded = 0, + kSessionCaptionTurnedOff = 1, + kTachyonSendMessagesError = 2, + kMaxValue = kTachyonSendMessagesError, + }; + // LINT.ThenChange(//tools/metrics/histograms/metadata/ash/enums.xml:BabelOrcaSendingStoppedReason) + static std::unique_ptr<BabelOrcaController> Create( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, std::unique_ptr<BabelOrcaSpeechRecognizer> speech_recognizer,
diff --git a/chromeos/ash/components/boca/babelorca/babel_orca_producer_unittest.cc b/chromeos/ash/components/boca/babelorca/babel_orca_producer_unittest.cc index 06bf82c..08fb182 100644 --- a/chromeos/ash/components/boca/babelorca/babel_orca_producer_unittest.cc +++ b/chromeos/ash/components/boca/babelorca/babel_orca_producer_unittest.cc
@@ -15,6 +15,7 @@ #include "base/functional/callback_helpers.h" #include "base/memory/weak_ptr.h" #include "base/test/bind.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "base/time/time.h" #include "chromeos/ash/components/boca/babelorca/babel_orca_speech_recognizer.h" @@ -46,6 +47,8 @@ namespace { const std::string kLanguage = "en-US"; +constexpr char kSendingStoppedReasonUma[] = + "Ash.Boca.Babelorca.SendingStoppedReason"; class MockSpeechRecognizer : public BabelOrcaSpeechRecognizer { public: @@ -112,6 +115,7 @@ base::WeakPtr<FakeBabelOrcaTranslationDispatcher> translation_dispatcher_; std::unique_ptr<BabelOrcaCaptionTranslator> translator_; TestingPrefServiceSimple pref_service_; + base::HistogramTester uma_recorder_; }; TEST_F(BabelOrcaProducerTest, EnableLocalCaptionsOutOfSession) { @@ -232,6 +236,11 @@ producer.OnSessionCaptionConfigUpdated(/*session_captions_enabled=*/false, /*translations_enabled=*/false); EXPECT_FALSE(caption_controller_delegate_ptr->IsCaptionBubbleAlive()); + EXPECT_EQ( + uma_recorder_.GetBucketCount( + kSendingStoppedReasonUma, + BabelOrcaProducer::SendingStoppedReason::kSessionCaptionTurnedOff), + 1); } TEST_F(BabelOrcaProducerTest, EnableLocalCaptionsThenSessionCaptionsInSession) { @@ -410,6 +419,10 @@ .Times(2); EXPECT_CALL(*speech_recognizer_ptr, Stop).Times(2); producer.OnSessionEnded(); + EXPECT_EQ(uma_recorder_.GetBucketCount( + kSendingStoppedReasonUma, + BabelOrcaProducer::SendingStoppedReason::kSessionEnded), + 1); } TEST_F(BabelOrcaProducerTest, SessionEndLocalCaptionsEnabled) {
diff --git a/chromeos/ash/components/boca/babelorca/oauth_token_fetcher.cc b/chromeos/ash/components/boca/babelorca/oauth_token_fetcher.cc index 5056ef5..72c9003 100644 --- a/chromeos/ash/components/boca/babelorca/oauth_token_fetcher.cc +++ b/chromeos/ash/components/boca/babelorca/oauth_token_fetcher.cc
@@ -16,6 +16,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/memory/raw_ptr.h" +#include "base/metrics/histogram_functions.h" #include "base/sequence_checker.h" #include "base/time/time.h" #include "chromeos/ash/components/boca/babelorca/token_data_wrapper.h" @@ -38,8 +39,9 @@ } // namespace OAuthTokenFetcher::OAuthTokenFetcher(signin::IdentityManager* identity_manager, - const std::string& scope) - : identity_manager_(identity_manager), scope_(scope) {} + const std::string& scope, + const std::string& uma_name) + : identity_manager_(identity_manager), scope_(scope), uma_name_(uma_name) {} OAuthTokenFetcher::~OAuthTokenFetcher() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -76,9 +78,14 @@ GoogleServiceAuthError error, signin::AccessTokenInfo access_token_info) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - static constexpr int kMaxRetries = 2; - static constexpr base::TimeDelta kRetryInitialBackoff = - base::Milliseconds(500); + constexpr int kMaxRetries = 2; + constexpr base::TimeDelta kRetryInitialBackoff = base::Milliseconds(500); + constexpr char kErrorUmaPathTemplate[] = + "Ash.Boca.Babelorca.$1.OAuthFetchError"; + base::UmaHistogramEnumeration( + base::ReplaceStringPlaceholders(kErrorUmaPathTemplate, {uma_name_}, + /*=offsets*/ nullptr), + error.state(), GoogleServiceAuthError::NUM_STATES); if (retry_num < kMaxRetries && IsOAuthTokenFetchRetryableError(error.state())) { retry_timer_.Start(FROM_HERE, (retry_num + 1) * kRetryInitialBackoff,
diff --git a/chromeos/ash/components/boca/babelorca/oauth_token_fetcher.h b/chromeos/ash/components/boca/babelorca/oauth_token_fetcher.h index 606a5a4..25238a7 100644 --- a/chromeos/ash/components/boca/babelorca/oauth_token_fetcher.h +++ b/chromeos/ash/components/boca/babelorca/oauth_token_fetcher.h
@@ -29,7 +29,8 @@ public: explicit OAuthTokenFetcher( signin::IdentityManager* identity_manager, - const std::string& scope = GaiaConstants::kTachyonOAuthScope); + const std::string& scope = GaiaConstants::kTachyonOAuthScope, + const std::string& uma_name = "Tachyon"); OAuthTokenFetcher(const OAuthTokenFetcher&) = delete; OAuthTokenFetcher& operator=(const OAuthTokenFetcher&) = delete; @@ -50,6 +51,7 @@ SEQUENCE_CHECKER(sequence_checker_); raw_ptr<signin::IdentityManager> identity_manager_; const std::string scope_; + const std::string uma_name_; std::unique_ptr<signin::AccessTokenFetcher> access_token_fetcher_ GUARDED_BY_CONTEXT(sequence_checker_); base::OneShotTimer retry_timer_;
diff --git a/chromeos/ash/components/boca/babelorca/oauth_token_fetcher_unittest.cc b/chromeos/ash/components/boca/babelorca/oauth_token_fetcher_unittest.cc index add73fa3..7f87449 100644 --- a/chromeos/ash/components/boca/babelorca/oauth_token_fetcher_unittest.cc +++ b/chromeos/ash/components/boca/babelorca/oauth_token_fetcher_unittest.cc
@@ -6,6 +6,7 @@ #include <optional> +#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "base/test/test_future.h" #include "base/time/time.h" @@ -27,6 +28,8 @@ base::Time::FromDeltaSinceWindowsEpoch(base::Days(50000)); constexpr char kIdToken[] = "id-test-token"; constexpr base::TimeDelta kRetryInitialBackoff = base::Milliseconds(500); +constexpr char kErrorUmaPathTemplate[] = + "Ash.Boca.Babelorca.Tachyon.OAuthFetchError"; class OAuthTokenFetcherTest : public testing::Test { protected: @@ -41,6 +44,7 @@ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; signin::IdentityTestEnvironment identity_test_env_; AccountInfo account_info_; + base::HistogramTester uma_recorder_; }; TEST_F(OAuthTokenFetcherTest, SuccessfulOAuthTokenFetch) { @@ -57,6 +61,9 @@ ASSERT_TRUE(token_data.has_value()); EXPECT_THAT(token_data->token, testing::StrEq(kOAuthToken)); EXPECT_EQ(token_data->expiration_time, kExpirationTime); + EXPECT_EQ(uma_recorder_.GetBucketCount(kErrorUmaPathTemplate, + GoogleServiceAuthError::NONE), + 1); } TEST_F(OAuthTokenFetcherTest, FailedOAuthTokenFetch) { @@ -70,6 +77,9 @@ auto token_data = fetch_future.Get(); EXPECT_FALSE(token_data.has_value()); + EXPECT_EQ(uma_recorder_.GetBucketCount(kErrorUmaPathTemplate, + GoogleServiceAuthError::SERVICE_ERROR), + 1); } TEST_F(OAuthTokenFetcherTest, OverlappingTokenFetchShouldFail) { @@ -173,6 +183,14 @@ GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE)); EXPECT_FALSE(fetch_future.Get().has_value()); + EXPECT_EQ( + uma_recorder_.GetBucketCount(kErrorUmaPathTemplate, + GoogleServiceAuthError::SERVICE_UNAVAILABLE), + 2); + EXPECT_EQ( + uma_recorder_.GetBucketCount(kErrorUmaPathTemplate, + GoogleServiceAuthError::CONNECTION_FAILED), + 1); } } // namespace
diff --git a/chromeos/ash/components/boca/babelorca/transcript_sender_impl.h b/chromeos/ash/components/boca/babelorca/transcript_sender_impl.h index 9bb4a3d7..4df3f771 100644 --- a/chromeos/ash/components/boca/babelorca/transcript_sender_impl.h +++ b/chromeos/ash/components/boca/babelorca/transcript_sender_impl.h
@@ -35,7 +35,7 @@ public: struct Options { size_t max_allowed_char = 200; - size_t max_errors_num = 2; + size_t max_errors_num = 5; }; TranscriptSenderImpl(TachyonAuthedClient* authed_client,
diff --git a/chromeos/ash/components/boca/boca_session_manager.cc b/chromeos/ash/components/boca/boca_session_manager.cc index db3137a3..a026e42 100644 --- a/chromeos/ash/components/boca/boca_session_manager.cc +++ b/chromeos/ash/components/boca/boca_session_manager.cc
@@ -305,6 +305,10 @@ } } +bool BocaSessionManager::disabled_on_non_managed_network() { + return disabled_on_non_managed_network_; +} + void BocaSessionManager::SetSessionCaptionInitializer( SessionCaptionInitializer session_caption_initializer) { session_caption_initializer_ = session_caption_initializer;
diff --git a/chromeos/ash/components/boca/boca_session_manager.h b/chromeos/ash/components/boca/boca_session_manager.h index ad3d0d18..3c2de618 100644 --- a/chromeos/ash/components/boca/boca_session_manager.h +++ b/chromeos/ash/components/boca/boca_session_manager.h
@@ -188,6 +188,8 @@ // Triggered by SWA delegate to notify app reload events. virtual void NotifyAppReload(); + virtual bool disabled_on_non_managed_network(); + void SetSessionCaptionInitializer( SessionCaptionInitializer session_caption_initializer); void RemoveSessionCaptionInitializer();
diff --git a/chromeos/ash/components/boca/on_task/on_task_session_manager.cc b/chromeos/ash/components/boca/on_task/on_task_session_manager.cc index 0649921..6815adf0 100644 --- a/chromeos/ash/components/boca/on_task/on_task_session_manager.cc +++ b/chromeos/ash/components/boca/on_task/on_task_session_manager.cc
@@ -91,6 +91,9 @@ if (const SessionID window_id = system_web_app_manager_->GetActiveSystemWebAppWindowID(); window_id.is_valid()) { + // Unlock SWA window before closing it to ensure we restore things like + // global accelerators, etc. + LockOrUnlockWindow(/*lock_window=*/false); system_web_app_manager_->CloseSystemWebAppWindow(window_id); } active_session_id_ = std::nullopt;
diff --git a/chromeos/ash/components/boca/on_task/on_task_session_manager_unittest.cc b/chromeos/ash/components/boca/on_task/on_task_session_manager_unittest.cc index 82e10c87..72df5c2 100644 --- a/chromeos/ash/components/boca/on_task/on_task_session_manager_unittest.cc +++ b/chromeos/ash/components/boca/on_task/on_task_session_manager_unittest.cc
@@ -239,10 +239,16 @@ TEST_F(OnTaskSessionManagerTest, ShouldCloseBocaSWAOnSessionEnd) { const SessionID kWindowId = SessionID::NewUnique(); + Sequence s; EXPECT_CALL(*system_web_app_manager_ptr_, GetActiveSystemWebAppWindowID()) - .WillOnce(Return(kWindowId)); + .WillRepeatedly(Return(kWindowId)); + EXPECT_CALL(*system_web_app_manager_ptr_, + SetPinStateForSystemWebAppWindow(false, kWindowId)) + .Times(1) + .InSequence(s); EXPECT_CALL(*system_web_app_manager_ptr_, CloseSystemWebAppWindow(kWindowId)) - .Times(1); + .Times(1) + .InSequence(s); session_manager_->OnSessionEnded("test_session_id"); // Verify session end notification was shown and window lock state was reset. @@ -256,7 +262,7 @@ const SessionID kWindowId = SessionID::NewUnique(); EXPECT_CALL(*system_web_app_manager_ptr_, GetActiveSystemWebAppWindowID()) .WillRepeatedly(Return(kWindowId)); - EXPECT_CALL(*extensions_manager_ptr_, ReEnableExtensions).Times(1); + EXPECT_CALL(*extensions_manager_ptr_, ReEnableExtensions).Times(AtLeast(1)); session_manager_->OnSessionEnded("test_session_id"); // Verify session end notification was shown.
diff --git a/chromeos/ash/components/login/auth/password_update_flow.cc b/chromeos/ash/components/login/auth/password_update_flow.cc index 5fdd8ec..ac549f4 100644 --- a/chromeos/ash/components/login/auth/password_update_flow.cc +++ b/chromeos/ash/components/login/auth/password_update_flow.cc
@@ -14,6 +14,8 @@ #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/functional/callback_helpers.h" +#include "base/strings/stringprintf.h" +#include "base/syslog_logging.h" #include "chromeos/ash/components/cryptohome/auth_factor.h" #include "chromeos/ash/components/cryptohome/cryptohome_parameters.h" #include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h" @@ -44,7 +46,9 @@ AuthErrorCallback error_callback) { DCHECK(user_context); DCHECK(user_context->GetAuthSessionId().empty()); - LOGIN_LOG(USER) << "Attempting to update user password"; + const std::string msg = "(LOGIN) Attempting to update user password"; + SYSLOG(INFO) << msg; + LOGIN_LOG(USER) << msg; bool is_ephemeral_user = user_manager::UserManager::Get()->IsUserCryptohomeDataEphemeral( @@ -67,8 +71,11 @@ DCHECK(user_context); if (error.has_value()) { - LOGIN_LOG(ERROR) << "Error starting AuthSession for key migration " - << error.value().get_cryptohome_code(); + const std::string error_message = base::StringPrintf( + "(LOGIN) Error starting AuthSession for key migration %d", + error.value().get_cryptohome_code()); + LOGIN_LOG(ERROR) << error_message; + SYSLOG(INFO) << error_message; std::move(error_callback).Run(std::move(user_context), error.value()); return; }
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 05a86cc2..a42f431 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -3643,6 +3643,92 @@ Suggestions shuffled </message> + <!-- Sea Pen Freeform Suggestions --> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_4K" desc="A suggestion of text that could be added to an image generation prompt"> + 4k + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_REALISTIC_PHOTO" desc="A suggestion of text that could be added to an image generation prompt"> + realistic photo + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_SURREAL" desc="A suggestion of text that could be added to an image generation prompt"> + surreal + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_BEAUTIFUL" desc="A suggestion of text that could be added to an image generation prompt"> + beautiful + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_MINIMAL" desc="A suggestion of text that could be added to an image generation prompt"> + minimal + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_SUNSET" desc="A suggestion of text that could be added to an image generation prompt"> + sunset + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_PASTEL_COLORS" desc="A suggestion of text that could be added to an image generation prompt"> + pastel colors + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_GLOWING" desc="A suggestion of text that could be added to an image generation prompt"> + glowing + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_STAR_FILLED_SKY" desc="A suggestion of text that could be added to an image generation prompt"> + star-filled sky + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_DRAMATIC_SHADOWS" desc="A suggestion of text that could be added to an image generation prompt"> + dramatic shadows + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_COVERED_IN_SNOW" desc="A suggestion of text that could be added to an image generation prompt"> + covered in snow + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_BIOLUMINESCENT" desc="A suggestion of text that could be added to an image generation prompt"> + bioluminescent + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_LONG_EXPOSURE" desc="A suggestion of text that could be added to an image generation prompt"> + long exposure + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_FOGGY" desc="A suggestion of text that could be added to an image generation prompt"> + foggy + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_GALAXY" desc="A suggestion of text that could be added to an image generation prompt"> + galaxy + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_NEON_LIGHTS" desc="A suggestion of text that could be added to an image generation prompt"> + neon lights + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_REFLECTIONS" desc="A suggestion of text that could be added to an image generation prompt"> + reflections + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_LIGHTNING" desc="A suggestion of text that could be added to an image generation prompt"> + lightning + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_BOKEH_EFFECT" desc="A suggestion of text that could be added to an image generation prompt"> + bokeh effect + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_WITH_COLOR_GRADING" desc="A suggestion of text that could be added to an image generation prompt"> + with color grading + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_VOLUMETRIC_LIGHT" desc="A suggestion of text that could be added to an image generation prompt"> + volumetric light + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_NEGATIVE_SPACE" desc="A suggestion of text that could be added to an image generation prompt"> + negative space + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_DIGITAL_ART" desc="A suggestion of text that could be added to an image generation prompt"> + digital art + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_T_REX" desc="A suggestion of text that could be added to an image generation prompt"> + t-rex + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_UNICORN" desc="A suggestion of text that could be added to an image generation prompt"> + unicorn + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_CATS" desc="A suggestion of text that could be added to an image generation prompt"> + cats + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_VECTOR_ART_STYLE" desc="A suggestion of text that could be added to an image generation prompt"> + vector art style + </message> + <message name="IDS_SEA_PEN_FREEFORM_SUGGESTION_3D_RENDER" desc="A suggestion of text that could be added to an image generation prompt"> + 3D render + </message> + <!-- Sea Pen Templates (AUTOGENERATED - contact assistive-eng@google.com before editing) --> <!-- Wallpaper template glowscapes --> <message name="IDS_SEA_PEN_TEMPLATE_TITLE_GLOWSCAPES" desc="Title of the image generation template IDS_SEA_PEN_TEMPLATE_GLOWSCAPES.">
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_3D_RENDER.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_3D_RENDER.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_3D_RENDER.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_4K.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_4K.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_4K.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_BEAUTIFUL.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_BEAUTIFUL.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_BEAUTIFUL.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_BIOLUMINESCENT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_BIOLUMINESCENT.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_BIOLUMINESCENT.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_BOKEH_EFFECT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_BOKEH_EFFECT.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_BOKEH_EFFECT.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_CATS.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_CATS.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_CATS.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_COVERED_IN_SNOW.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_COVERED_IN_SNOW.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_COVERED_IN_SNOW.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_DIGITAL_ART.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_DIGITAL_ART.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_DIGITAL_ART.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_DRAMATIC_SHADOWS.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_DRAMATIC_SHADOWS.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_DRAMATIC_SHADOWS.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_FOGGY.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_FOGGY.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_FOGGY.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_GALAXY.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_GALAXY.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_GALAXY.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_GLOWING.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_GLOWING.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_GLOWING.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_LIGHTNING.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_LIGHTNING.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_LIGHTNING.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_LONG_EXPOSURE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_LONG_EXPOSURE.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_LONG_EXPOSURE.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_MINIMAL.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_MINIMAL.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_MINIMAL.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_NEGATIVE_SPACE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_NEGATIVE_SPACE.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_NEGATIVE_SPACE.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_NEON_LIGHTS.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_NEON_LIGHTS.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_NEON_LIGHTS.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_PASTEL_COLORS.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_PASTEL_COLORS.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_PASTEL_COLORS.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_REALISTIC_PHOTO.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_REALISTIC_PHOTO.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_REALISTIC_PHOTO.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_REFLECTIONS.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_REFLECTIONS.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_REFLECTIONS.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_STAR_FILLED_SKY.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_STAR_FILLED_SKY.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_STAR_FILLED_SKY.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_SUNSET.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_SUNSET.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_SUNSET.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_SURREAL.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_SURREAL.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_SURREAL.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_T_REX.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_T_REX.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_T_REX.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_UNICORN.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_UNICORN.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_UNICORN.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_VECTOR_ART_STYLE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_VECTOR_ART_STYLE.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_VECTOR_ART_STYLE.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_VOLUMETRIC_LIGHT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_VOLUMETRIC_LIGHT.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_VOLUMETRIC_LIGHT.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_WITH_COLOR_GRADING.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_WITH_COLOR_GRADING.png.sha1 new file mode 100644 index 0000000..710a75b --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SEA_PEN_FREEFORM_SUGGESTION_WITH_COLOR_GRADING.png.sha1
@@ -0,0 +1 @@ +1053c521e509a308a2f7b2d306e61657f825fbf3 \ No newline at end of file
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni index b859446..17ee8a3 100644 --- a/chromeos/tast_control.gni +++ b/chromeos/tast_control.gni
@@ -96,9 +96,6 @@ # b/408102591 "network.ARCEAPWifiProvisioning.eap_wifi_tls", - # b/404605466, Failing on reven-vmtest, blocking uprev. - "flex.HWIS", - # b/404564227, Failing on jacuzzi, blocking uprev. "oobe.SmokeEndToEnd",
diff --git a/clank b/clank index 5c66745..618a8eb 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 5c66745b33cda1230040a42b22046206497c6580 +Subproject commit 618a8ebb6ca63dee8c6b5066c777e88ec88596d2
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 0d1c5bfe5..5a69746 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
@@ -463,6 +463,23 @@ NotifyObservers(); } +bool PaymentsDataManager::ShouldShowBnplSettings() const { +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) + // Check `kAutofillEnableBuyNowPayLater` only if the user has seen a BNPL + // suggestion before to avoid unnecessary feature flag checks. Ensures that + // only relevant sessions are included in BNPL related A/B experiments. + // Otherwise, users that navigate to the settings page can enroll in the + // experiment, with very little guarantee they will actually use the BNPL + // feature. + return IsAutofillHasSeenBnplPrefEnabled() && + base::FeatureList::IsEnabled(features::kAutofillEnableBuyNowPayLater); +#else + return false; +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) +} + CoreAccountInfo PaymentsDataManager::GetAccountInfoForPaymentsServer() const { // Return the account of the active signed-in user irrespective of whether // they enabled sync or not.
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 cd04ce5..b15cbf7 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
@@ -369,6 +369,10 @@ #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || // BUILDFLAG(IS_CHROMEOS) + // Returns if the user has seen a BNPL suggestion before and if the BNPL + // feature is enabled. Does not check for user's locale. + bool ShouldShowBnplSettings() const; + // Returns whether sync's integration with payments is on. virtual bool IsAutofillWalletImportEnabled() const;
diff --git a/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc b/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc index a8b4925..668b691 100644 --- a/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc +++ b/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc
@@ -3850,6 +3850,27 @@ EXPECT_EQ(1U, payments_data_manager().GetLinkedBnplIssuers().size()); EXPECT_EQ(2U, payments_data_manager().GetEwalletAccounts().size()); } + +TEST_F(PaymentsDataManagerTest, ShouldShowBnplSettings) { + base::test::ScopedFeatureList feature_list{ + features::kAutofillEnableBuyNowPayLater}; + prefs_.get()->SetBoolean(prefs::kAutofillHasSeenBnpl, true); + EXPECT_TRUE(payments_data_manager().ShouldShowBnplSettings()); + + prefs_.get()->SetBoolean(prefs::kAutofillHasSeenBnpl, false); + EXPECT_FALSE(payments_data_manager().ShouldShowBnplSettings()); +} + +TEST_F(PaymentsDataManagerTest, ShouldShowBnplSettings_FlagOff) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature(features::kAutofillEnableBuyNowPayLater); + prefs_.get()->SetBoolean(prefs::kAutofillHasSeenBnpl, true); + EXPECT_FALSE(payments_data_manager().ShouldShowBnplSettings()); + + prefs_.get()->SetBoolean(prefs::kAutofillHasSeenBnpl, false); + EXPECT_FALSE(payments_data_manager().ShouldShowBnplSettings()); +} + #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || // BUILDFLAG(IS_CHROMEOS)
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager.cc b/components/autofill/core/browser/foundations/browser_autofill_manager.cc index 3882aa7..b894978 100644 --- a/components/autofill/core/browser/foundations/browser_autofill_manager.cc +++ b/components/autofill/core/browser/foundations/browser_autofill_manager.cc
@@ -624,8 +624,20 @@ // Retrieves the AutofillAI predictions for `form` in `cache` and adds them to // `form`'s fields. -void AddAutofillAiPredictions(const AutofillAiModelCache& cache, - FormStructure& form) { +void AddCachedAutofillAiPredictions(const AutofillAiModelCache& cache, + FormStructure& form) { + // Mixing Autofill AI model predictions (which come from the online LLM) and + // Autofill AI server predictions (which come from the Autofill crowdsourcing + // server) may lead to too many false positives. We therefore favor server + // predictions over model predictions. (There's no specific reason for this + // precedence -- preferring model predictions may work just as well.) + if (std::ranges::any_of( + form.fields(), [](const std::unique_ptr<AutofillField>& field) { + return field->GetAutofillAiServerTypePredictions().has_value(); + })) { + return; + } + using FieldIdentifier = AutofillAiModelCache::FieldIdentifier; using ModelFieldPrediction = AutofillAiModelCache::FieldPrediction; const base::flat_map<FieldIdentifier, ModelFieldPrediction> predictions = @@ -705,6 +717,18 @@ ->GetCreditCardAccessManager(); } +payments::BnplManager* BrowserAutofillManager::GetPaymentsBnplManager() { +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) + if (!bnpl_manager_) { + bnpl_manager_ = std::make_unique<payments::BnplManager>(this); + } +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) + + return bnpl_manager_.get(); +} + bool BrowserAutofillManager::ShouldShowScanCreditCard( const FormData& form, const FormFieldData& field) { @@ -1454,8 +1478,7 @@ context, ShouldSuppressSuggestions(context.suppress_reason, log_manager()), !suggestions.empty(), autofill_field->Type().GetStorableType())) { - if (payments::BnplManager* bnpl_manager = - client().GetPaymentsAutofillClient()->GetPaymentsBnplManager()) { + if (payments::BnplManager* bnpl_manager = GetPaymentsBnplManager()) { bnpl_manager->NotifyOfSuggestionGeneration(trigger_source); } amount_extraction_manager_->TriggerCheckoutAmountExtraction(); @@ -1936,8 +1959,8 @@ // Notify the BNPL manager about suggestion shown if the current shown // suggestion list contains a credit card entry. - if (payments::BnplManager* bnpl_manager = - client().GetPaymentsAutofillClient()->GetPaymentsBnplManager(); + + if (payments::BnplManager* bnpl_manager = GetPaymentsBnplManager(); bnpl_manager && shown_suggestion_types.contains(SuggestionType::kCreditCardEntry)) { bnpl_manager->OnSuggestionsShown(suggestions, update_suggestions_callback); @@ -2134,6 +2157,7 @@ base::span<const raw_ptr<FormStructure, VectorExperimental>> forms) { const AutofillAiModelCache* const model_cache = client().GetAutofillAiModelCache(); + if (!model_cache) { return; } @@ -2144,15 +2168,10 @@ } if (model_cache->Contains(form->form_signature())) { - // Do not override server predictions. if (MayPerformAutofillAiAction( client(), - AutofillAiAction::kUseCachedServerClassificationModelResults) && - std::ranges::none_of( - form->fields(), [](const std::unique_ptr<AutofillField>& field) { - return field->GetAutofillAiServerTypePredictions().has_value(); - })) { - AddAutofillAiPredictions(*model_cache, *form); + AutofillAiAction::kUseCachedServerClassificationModelResults)) { + AddCachedAutofillAiPredictions(*model_cache, *form); } continue; } @@ -2181,19 +2200,43 @@ continue; } + auto deferred_add_cached_autofill_ai_predictions = + [](base::WeakPtr<AutofillManager> self, const FormGlobalId& form_id) { + if (!self) { + return; + } + AutofillAiModelCache* model_cache = + self->client().GetAutofillAiModelCache(); + if (!model_cache) { + return; + } + FormStructure* form = self->FindCachedFormById(form_id); + if (!form) { + return; + } + AddCachedAutofillAiPredictions(*model_cache, *form); + form->RationalizeAndAssignSections( + self->client().GetCurrentLogManager()); + }; if (features::kAutofillAiServerModelSendPageContent.Get()) { LOG_AF(log_manager()) << LoggingScope::kAutofillAi << "Requesting page page content for model run for form." << Br{} << *form; - client().GetAiPageContent( - base::BindOnce(&AutofillAiModelExecutor::GetPredictions, - model_executor->GetWeakPtr(), form->ToFormData())); + client().GetAiPageContent(base::BindOnce( + &AutofillAiModelExecutor::GetPredictions, + model_executor->GetWeakPtr(), form->ToFormData(), + base::BindOnce(deferred_add_cached_autofill_ai_predictions, + GetWeakPtr()))); } else { LOG_AF(log_manager()) << LoggingScope::kAutofillAi << "Requesting model run for form." << Br{} << *form; - model_executor->GetPredictions(form->ToFormData(), {}); + model_executor->GetPredictions( + form->ToFormData(), + base::BindOnce(deferred_add_cached_autofill_ai_predictions, + GetWeakPtr()), + std::nullopt); } } }
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager.h b/components/autofill/core/browser/foundations/browser_autofill_manager.h index 297b5dd..c302821 100644 --- a/components/autofill/core/browser/foundations/browser_autofill_manager.h +++ b/components/autofill/core/browser/foundations/browser_autofill_manager.h
@@ -45,6 +45,7 @@ #include "components/autofill/core/browser/metrics/log_event.h" #include "components/autofill/core/browser/payments/amount_extraction_manager.h" #include "components/autofill/core/browser/payments/autofill_offer_manager.h" +#include "components/autofill/core/browser/payments/bnpl_manager.h" #include "components/autofill/core/browser/payments/card_unmask_delegate.h" #include "components/autofill/core/browser/payments/full_card_request.h" #include "components/autofill/core/browser/payments/payments_autofill_client.h" @@ -209,6 +210,11 @@ CreditCardAccessManager& GetCreditCardAccessManager(); const CreditCardAccessManager& GetCreditCardAccessManager() const; + // Gets the payments BNPL manager owned by `this`. This will be used to + // handle BNPL flows. May return nullptr if BNPL is not supported on the + // current platform. + virtual payments::BnplManager* GetPaymentsBnplManager(); + // Handles post-filling logic of `form_structure`, like notifying observers // and logging form metrics. // `filled_fields` are the fields that were filled by the browser. @@ -631,6 +637,10 @@ // Lazily initialized: access only through GetCreditCardAccessManager(). std::unique_ptr<CreditCardAccessManager> credit_card_access_manager_; + // Manages Buy Now, Pay Later related autofill flows and logic. + // Lazily initialized: access only through GetPaymentsBnplManager(). + std::unique_ptr<payments::BnplManager> bnpl_manager_; + // The amount extraction manager, used to trigger the final checkout // amount from merchant websites. std::unique_ptr<payments::AmountExtractionManager> @@ -643,9 +653,9 @@ std::make_unique<FormFiller>(*this); // Contains a list of four digit combinations that were found in the webpage - // DOM. Populated after a standalone cvc field is processed on a form. Used to - // confirm that the virtual card last four is present in the webpage for card - // on file case. + // DOM. Populated after a standalone cvc field is processed on a form. + // Used to confirm that the virtual card last four is present in the webpage + // for card on file case. std::vector<std::string> four_digit_combinations_in_dom_; std::u16string last_unlocked_credit_card_cvc_;
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager_test_api.h b/components/autofill/core/browser/foundations/browser_autofill_manager_test_api.h index e1a9210..c8eea9f 100644 --- a/components/autofill/core/browser/foundations/browser_autofill_manager_test_api.h +++ b/components/autofill/core/browser/foundations/browser_autofill_manager_test_api.h
@@ -18,6 +18,7 @@ #include "components/autofill/core/browser/foundations/autofill_manager_test_api.h" #include "components/autofill/core/browser/foundations/browser_autofill_manager.h" #include "components/autofill/core/browser/payments/amount_extraction_manager.h" +#include "components/autofill/core/browser/payments/bnpl_manager.h" #include "components/autofill/core/browser/payments/credit_card_access_manager.h" #include "components/autofill/core/browser/single_field_fillers/single_field_fill_router.h" #include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h" @@ -59,6 +60,10 @@ manager_->amount_extraction_manager_ = std::move(manager); } + void set_bnpl_manager(std::unique_ptr<payments::BnplManager> bnpl_manager) { + manager_->bnpl_manager_ = std::move(bnpl_manager); + } + payments::AmountExtractionManager& get_amount_extraction_manager_for_testing() { return *manager_->amount_extraction_manager_;
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/foundations/browser_autofill_manager_unittest.cc index 18a5973..863751a7c 100644 --- a/components/autofill/core/browser/foundations/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/foundations/browser_autofill_manager_unittest.cc
@@ -2698,20 +2698,16 @@ const FormFieldData& card_number_field = form.fields()[1]; ASSERT_EQ(card_number_field.name(), u"cardnumber"); - // Set up `BnplManager` for testing. - MockBnplManager& bnpl_manager_ = - payments_client().CreateOrGetMockBnplManager(); - // Verify that the amount extraction is triggered. #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ BUILDFLAG(IS_CHROMEOS) EXPECT_CALL(amount_extraction_manager(), TriggerCheckoutAmountExtraction) .Times(1); - EXPECT_CALL(bnpl_manager_, NotifyOfSuggestionGeneration).Times(1); + EXPECT_CALL(*manager().GetPaymentsBnplManager(), NotifyOfSuggestionGeneration) + .Times(1); #else EXPECT_CALL(amount_extraction_manager(), TriggerCheckoutAmountExtraction) .Times(0); - EXPECT_CALL(bnpl_manager_, NotifyOfSuggestionGeneration).Times(0); #endif OnAskForValuesToFill(form, card_number_field); @@ -2738,14 +2734,14 @@ FormData form = CreateTestAddressFormData(); FormsSeen({form}); - // Set up `BnplManager` for testing. - MockBnplManager& bnpl_manager_ = - payments_client().CreateOrGetMockBnplManager(); - // Verify that the amount extraction is not triggered. EXPECT_CALL(amount_extraction_manager(), TriggerCheckoutAmountExtraction) .Times(0); - EXPECT_CALL(bnpl_manager_, NotifyOfSuggestionGeneration).Times(0); +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) + EXPECT_CALL(*manager().GetPaymentsBnplManager(), NotifyOfSuggestionGeneration) + .Times(0); +#endif OnAskForValuesToFill(form, form.fields()[0]); @@ -2772,10 +2768,6 @@ CreateTestCreditCardFormData(/*is_https=*/true, /*use_month_type=*/false); FormsSeen({form}); - // Set up `BnplManager` for testing. - MockBnplManager& bnpl_manager_ = - payments_client().CreateOrGetMockBnplManager(); - // Remove all credit cards under testing profile so that there is no // suggestion is generated. personal_data().test_payments_data_manager().ClearAllLocalData(); @@ -2783,7 +2775,11 @@ // Verify that the amount extraction is not triggered. EXPECT_CALL(amount_extraction_manager(), TriggerCheckoutAmountExtraction) .Times(0); - EXPECT_CALL(bnpl_manager_, NotifyOfSuggestionGeneration).Times(0); +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) + EXPECT_CALL(*manager().GetPaymentsBnplManager(), NotifyOfSuggestionGeneration) + .Times(0); +#endif OnAskForValuesToFill(form, form.fields()[0]); @@ -2810,10 +2806,6 @@ CreateTestCreditCardFormData(/*is_https=*/true, /*use_month_type=*/false); FormsSeen({form}); - // Set up `BnplManager` for testing. - MockBnplManager& bnpl_manager_ = - payments_client().CreateOrGetMockBnplManager(); - // Disable Autofill. client().SetAutofillProfileEnabled(false); client().SetAutofillPaymentMethodsEnabled(false); @@ -2821,7 +2813,11 @@ // Verify that the amount extraction is not triggered. EXPECT_CALL(amount_extraction_manager(), TriggerCheckoutAmountExtraction) .Times(0); - EXPECT_CALL(bnpl_manager_, NotifyOfSuggestionGeneration).Times(0); +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) + EXPECT_CALL(*manager().GetPaymentsBnplManager(), NotifyOfSuggestionGeneration) + .Times(0); +#endif OnAskForValuesToFill(form, form.fields()[0]); @@ -7011,7 +7007,7 @@ EXPECT_CALL(client(), GetAiPageContent) .WillOnce(RunOnceCallback<0>( optimization_guide::proto::AnnotatedPageContent())); - EXPECT_CALL(executor(), GetPredictions(_, Not(Eq(std::nullopt)))); + EXPECT_CALL(executor(), GetPredictions(_, _, Not(Eq(std::nullopt)))); SeeForm(/*may_run_model=*/true); }
diff --git a/components/autofill/core/browser/foundations/test_browser_autofill_manager.cc b/components/autofill/core/browser/foundations/test_browser_autofill_manager.cc index 96f349d..b185aeb 100644 --- a/components/autofill/core/browser/foundations/test_browser_autofill_manager.cc +++ b/components/autofill/core/browser/foundations/test_browser_autofill_manager.cc
@@ -16,6 +16,7 @@ #include "components/autofill/core/browser/foundations/browser_autofill_manager_test_api.h" #include "components/autofill/core/browser/foundations/test_autofill_driver.h" #include "components/autofill/core/browser/foundations/test_autofill_manager_waiter.h" +#include "components/autofill/core/browser/payments/test/mock_bnpl_manager.h" #include "components/autofill/core/browser/single_field_fillers/mock_single_field_fill_router.h" #include "components/autofill/core/browser/suggestions/suggestion.h" #include "components/autofill/core/browser/test_utils/autofill_test_utils.h" @@ -32,6 +33,17 @@ TestBrowserAutofillManager::~TestBrowserAutofillManager() = default; +testing::NiceMock<MockBnplManager>* +TestBrowserAutofillManager::GetPaymentsBnplManager() { +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) + return &mock_bnpl_manager_; +#else + return nullptr; +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) +} + void TestBrowserAutofillManager::OnLanguageDetermined( const translate::LanguageDetectionDetails& details) { AutofillManager::OnLanguageDetermined(details);
diff --git a/components/autofill/core/browser/foundations/test_browser_autofill_manager.h b/components/autofill/core/browser/foundations/test_browser_autofill_manager.h index 6864077..e6c1467c 100644 --- a/components/autofill/core/browser/foundations/test_browser_autofill_manager.h +++ b/components/autofill/core/browser/foundations/test_browser_autofill_manager.h
@@ -18,10 +18,12 @@ #include "components/autofill/core/browser/foundations/browser_autofill_manager.h" #include "components/autofill/core/browser/foundations/browser_autofill_manager_test_api.h" #include "components/autofill/core/browser/foundations/test_autofill_manager_waiter.h" +#include "components/autofill/core/browser/payments/test/mock_bnpl_manager.h" #include "ui/gfx/image/image_unittest_util.h" namespace autofill { +class MockBnplManager; class AutofillDriver; class FormStructure; class TestPersonalDataManager; @@ -71,6 +73,7 @@ // BrowserAutofillManager overrides. const gfx::Image& GetCardImage(const CreditCard& credit_card) override; + testing::NiceMock<MockBnplManager>* GetPaymentsBnplManager() override; // Unique to TestBrowserAutofillManager: @@ -110,6 +113,8 @@ private: const gfx::Image card_image_ = gfx::test::CreateImage(40, 24); + testing::NiceMock<MockBnplManager> mock_bnpl_manager_{this}; + TestAutofillManagerWaiter waiter_{*this}; };
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor.h b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor.h index e38c105..91513807 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor.h +++ b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor.h
@@ -7,7 +7,9 @@ #include <optional> +#include "base/functional/callback_forward.h" #include "base/memory/weak_ptr.h" +#include "components/autofill/core/common/unique_ids.h" #include "components/keyed_service/core/keyed_service.h" namespace optimization_guide::proto { @@ -30,6 +32,7 @@ // model. virtual void GetPredictions( FormData form_data, + base::OnceCallback<void(const FormGlobalId&)> on_model_executed, std::optional<optimization_guide::proto::AnnotatedPageContent> annotated_page_content) = 0;
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.cc b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.cc index 6b7266f..63ccb31 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.cc +++ b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.cc
@@ -41,6 +41,7 @@ void AutofillAiModelExecutorImpl::GetPredictions( FormData form_data, + base::OnceCallback<void(const FormGlobalId&)> on_model_executed, std::optional<optimization_guide::proto::AnnotatedPageContent> annotated_page_content) { // If there is already an ongoing request for the same form signature, then @@ -66,11 +67,13 @@ *std::move(annotated_page_content); } + FormGlobalId form_id = form_data.global_id(); optimization_guide::ModelExecutionCallbackWithLogging< optimization_guide::proto::FormsClassificationsLoggingData> wrapper_callback = base::BindOnce(&AutofillAiModelExecutorImpl::OnModelExecuted, - weak_ptr_factory_.GetWeakPtr(), std::move(form_data)); + weak_ptr_factory_.GetWeakPtr(), std::move(form_data)) + .Then(base::BindOnce(std::move(on_model_executed), form_id)); optimization_guide::ExecuteModelWithLogging( &model_executor_.get(), optimization_guide::ModelBasedCapabilityKey::kFormsClassifications,
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.h b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.h index d591e23..752cf99d 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.h +++ b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.h
@@ -15,6 +15,7 @@ #include "base/types/expected.h" #include "components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor.h" #include "components/autofill/core/common/signatures.h" +#include "components/autofill/core/common/unique_ids.h" #include "components/optimization_guide/core/model_quality/model_quality_logs_uploader_service.h" #include "components/optimization_guide/core/optimization_guide_model_executor.h" #include "components/optimization_guide/proto/features/forms_classifications.pb.h" @@ -35,6 +36,7 @@ // AutofillAiModelExecutor: void GetPredictions( FormData form_data, + base::OnceCallback<void(const FormGlobalId&)> on_model_executed, std::optional<optimization_guide::proto::AnnotatedPageContent> annotated_page_content) override; base::WeakPtr<AutofillAiModelExecutor> GetWeakPtr() override;
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl_unittest.cc b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl_unittest.cc index da7bd8f..f5283f8 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl_unittest.cc +++ b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl_unittest.cc
@@ -9,6 +9,7 @@ #include "base/test/gmock_callback_support.h" #include "base/test/gmock_move_support.h" +#include "base/test/mock_callback.h" #include "base/test/protobuf_matchers.h" #include "base/test/task_environment.h" #include "base/test/test_future.h" @@ -41,6 +42,8 @@ using ::testing::An; using ::testing::ElementsAre; using ::testing::IsEmpty; +using MockOnModelExecutedCallback = + base::MockCallback<base::OnceCallback<void(const FormGlobalId&)>>; class AutofillAiModelExecutorImplTest : public testing::Test { public: @@ -76,6 +79,7 @@ field_response->set_field_index(0); } + MockOnModelExecutedCallback on_model_executed; EXPECT_CALL( *model_executor(), ExecuteModel( @@ -92,8 +96,9 @@ ElementsAre(FieldIdentifier{ .signature = CalculateFieldSignatureForField(form.fields()[0]), .rank_in_signature_group = 0}))); + EXPECT_CALL(on_model_executed, Run(form.global_id())); - engine()->GetPredictions(form, std::nullopt); + engine()->GetPredictions(form, on_model_executed.Get(), std::nullopt); } // Tests that if the field index of a prediction is out of bounds of the @@ -108,6 +113,7 @@ field_response->set_field_index(1); } + MockOnModelExecutedCallback on_model_executed; EXPECT_CALL( *model_executor(), ExecuteModel( @@ -122,8 +128,9 @@ model_cache(), Update(CalculateFormSignature(form), base::test::EqualsProto(AutofillAiTypeResponse()), IsEmpty())); + EXPECT_CALL(on_model_executed, Run(form.global_id())); - engine()->GetPredictions(form, std::nullopt); + engine()->GetPredictions(form, on_model_executed.Get(), std::nullopt); } // Tests that if the field index of a prediction is negative, then nothing is @@ -138,6 +145,7 @@ field_response->set_field_index(-1); } + MockOnModelExecutedCallback on_model_executed; EXPECT_CALL( *model_executor(), ExecuteModel( @@ -152,8 +160,9 @@ model_cache(), Update(CalculateFormSignature(form), base::test::EqualsProto(AutofillAiTypeResponse()), IsEmpty())); + EXPECT_CALL(on_model_executed, Run(form.global_id())); - engine()->GetPredictions(form, std::nullopt); + engine()->GetPredictions(form, on_model_executed.Get(), std::nullopt); } // Tests that if there are duplicate field indices, then nothing is written @@ -174,6 +183,7 @@ field_response->set_field_index(0); } + MockOnModelExecutedCallback on_model_executed; EXPECT_CALL( *model_executor(), ExecuteModel( @@ -188,8 +198,9 @@ model_cache(), Update(CalculateFormSignature(form), base::test::EqualsProto(AutofillAiTypeResponse()), IsEmpty())); + EXPECT_CALL(on_model_executed, Run(form.global_id())); - engine()->GetPredictions(form, std::nullopt); + engine()->GetPredictions(form, on_model_executed.Get(), std::nullopt); } // Tests that if there is an ongoing request with the same form signature, then @@ -236,14 +247,14 @@ .signature = CalculateFieldSignatureForField(form1.fields()[0]), .rank_in_signature_group = 0}))); - engine()->GetPredictions(form1, std::nullopt); + engine()->GetPredictions(form1, base::DoNothing(), std::nullopt); // We expect this call not to trigger a run. - engine()->GetPredictions(form1, std::nullopt); + engine()->GetPredictions(form1, base::DoNothing(), std::nullopt); // The simulated model call for a different form runs immediately and // completes successfully. - engine()->GetPredictions(form2, std::nullopt); + engine()->GetPredictions(form2, base::DoNothing(), std::nullopt); ASSERT_TRUE(model_callback2); std::move(model_callback2) .Run(OptimizationGuideModelExecutionResult( @@ -263,6 +274,7 @@ // Tests that model errors are handled by writing an empty entry into the cache. TEST_F(AutofillAiModelExecutorImplTest, ModelError) { const FormData form; + MockOnModelExecutedCallback on_model_executed; EXPECT_CALL( *model_executor(), ExecuteModel( @@ -280,14 +292,16 @@ model_cache(), Update(CalculateFormSignature(form), base::test::EqualsProto(AutofillAiTypeResponse()), IsEmpty())); + EXPECT_CALL(on_model_executed, Run(form.global_id())); - engine()->GetPredictions(form, std::nullopt); + engine()->GetPredictions(form, on_model_executed.Get(), std::nullopt); } // Tests that wrongly typed model responses are handled by writing an empty // entry into the cache. TEST_F(AutofillAiModelExecutorImplTest, WrongTypeReturned) { const FormData form; + MockOnModelExecutedCallback on_model_executed; EXPECT_CALL( *model_executor(), ExecuteModel( @@ -301,8 +315,9 @@ model_cache(), Update(CalculateFormSignature(form), base::test::EqualsProto(AutofillAiTypeResponse()), IsEmpty())); + EXPECT_CALL(on_model_executed, Run(form.global_id())); - engine()->GetPredictions(form, std::nullopt); + engine()->GetPredictions(form, on_model_executed.Get(), std::nullopt); } } // namespace
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.h b/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.h index b434ea28..8890ca8c 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.h +++ b/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.h
@@ -24,6 +24,7 @@ MOCK_METHOD(void, GetPredictions, (FormData, + base::OnceCallback<void(const FormGlobalId&)>, std::optional<optimization_guide::proto::AnnotatedPageContent>), (override)); base::WeakPtr<AutofillAiModelExecutor> GetWeakPtr() override;
diff --git a/components/autofill/core/browser/payments/amount_extraction_manager.cc b/components/autofill/core/browser/payments/amount_extraction_manager.cc index b0819e6..5f6cf85c 100644 --- a/components/autofill/core/browser/payments/amount_extraction_manager.cc +++ b/components/autofill/core/browser/payments/amount_extraction_manager.cc
@@ -178,9 +178,7 @@ std::optional<uint64_t> parsed_extracted_amount = MaybeParseAmountToMonetaryMicroUnits(extracted_amount); - if (BnplManager* bnpl_manager = autofill_manager_->client() - .GetPaymentsAutofillClient() - ->GetPaymentsBnplManager()) { + if (BnplManager* bnpl_manager = autofill_manager_->GetPaymentsBnplManager()) { bnpl_manager->OnAmountExtractionReturned(parsed_extracted_amount); } if constexpr (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) ||
diff --git a/components/autofill/core/browser/payments/amount_extraction_manager_unittest.cc b/components/autofill/core/browser/payments/amount_extraction_manager_unittest.cc index b1b535d..1dfb2b5 100644 --- a/components/autofill/core/browser/payments/amount_extraction_manager_unittest.cc +++ b/components/autofill/core/browser/payments/amount_extraction_manager_unittest.cc
@@ -606,10 +606,7 @@ // extraction receives a empty result. TEST_F(AmountExtractionManagerTest, OnCheckoutAmountReceived_EmptyResult_BnplManagerNotified) { - MockBnplManager& bnpl_manager_ = autofill_client_->GetPaymentsAutofillClient() - ->CreateOrGetMockBnplManager(); - - EXPECT_CALL(bnpl_manager_, + EXPECT_CALL(*autofill_manager_->GetPaymentsBnplManager(), OnAmountExtractionReturned(std::optional<uint64_t>())) .Times(1); @@ -620,11 +617,9 @@ // extraction receives a result with correct format. TEST_F(AmountExtractionManagerTest, OnCheckoutAmountReceived_AmountInCorrectFormat_BnplManagerNotified) { - MockBnplManager& bnpl_manager_ = autofill_client_->GetPaymentsAutofillClient() - ->CreateOrGetMockBnplManager(); - - EXPECT_CALL(bnpl_manager_, OnAmountExtractionReturned( - std::optional<uint64_t>(123'450'000ULL))) + EXPECT_CALL( + *autofill_manager_->GetPaymentsBnplManager(), + OnAmountExtractionReturned(std::optional<uint64_t>(123'450'000ULL))) .Times(1); FakeCheckoutAmountReceived("$ 123.45");
diff --git a/components/autofill/core/browser/payments/bnpl_manager.cc b/components/autofill/core/browser/payments/bnpl_manager.cc index 082dc13..6825f6ce 100644 --- a/components/autofill/core/browser/payments/bnpl_manager.cc +++ b/components/autofill/core/browser/payments/bnpl_manager.cc
@@ -18,6 +18,7 @@ #include "base/functional/bind.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/data_model/payments/credit_card.h" +#include "components/autofill/core/browser/foundations/autofill_manager.h" #include "components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide.h" #include "components/autofill/core/browser/metrics/payments/bnpl_metrics.h" #include "components/autofill/core/browser/payments/constants.h" @@ -49,8 +50,8 @@ BnplManager::OngoingFlowState::~OngoingFlowState() = default; -BnplManager::BnplManager(AutofillClient* autofill_client) - : autofill_client_(CHECK_DEREF(autofill_client)) {} +BnplManager::BnplManager(AutofillManager* autofill_manager) + : autofill_manager_(CHECK_DEREF(autofill_manager)) {} BnplManager::~BnplManager() = default; @@ -68,7 +69,7 @@ ongoing_flow_state_ = std::make_unique<OngoingFlowState>(); ongoing_flow_state_->final_checkout_amount = final_checkout_amount; - ongoing_flow_state_->app_locale = autofill_client_->GetAppLocale(); + ongoing_flow_state_->app_locale = autofill_manager_->client().GetAppLocale(); ongoing_flow_state_->billing_customer_number = GetBillingCustomerId(payments_autofill_client().GetPaymentsDataManager()); ongoing_flow_state_->on_bnpl_vcn_fetched_callback = @@ -126,26 +127,6 @@ } } -bool BnplManager::ShouldShowBnplSettings() const { -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ - BUILDFLAG(IS_CHROMEOS) - const PaymentsDataManager& payments_data_manager = - payments_autofill_client().GetPaymentsDataManager(); - - // Check `kAutofillEnableBuyNowPayLater` only if user has seen a BNPL - // suggestion before to avoid unnecessary feature flag checks. Ensures that - // only relevant sessions are included in BNPL related A/B experiments. - // Otherwise, users that navigate to the settings page can enroll in the - // experiment, with very little guarantee they will actually use the BNPL - // feature. - return payments_data_manager.IsAutofillHasSeenBnplPrefEnabled() && - base::FeatureList::IsEnabled(features::kAutofillEnableBuyNowPayLater); -#else - return false; -#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || - // BUILDFLAG(IS_CHROMEOS) -} - void BnplManager::FetchVcnDetails(GURL url) { GetBnplPaymentInstrumentForFetchingVcnRequestDetails request_details; request_details.billing_customer_number = @@ -242,8 +223,8 @@ ongoing_flow_state_->billing_customer_number; request_details.issuer_id = ongoing_flow_state_->issuer.issuer_id(); - autofill_client_->GetPaymentsAutofillClient() - ->GetPaymentsNetworkInterface() + payments_autofill_client() + .GetPaymentsNetworkInterface() ->GetDetailsForCreateBnplPaymentInstrument( std::move(request_details), base::BindOnce( @@ -315,7 +296,9 @@ request_details.instrument_id = ongoing_flow_state_->instrument_id; request_details.risk_data = ongoing_flow_state_->risk_data; request_details.merchant_domain = - autofill_client_->GetLastCommittedPrimaryMainFrameOrigin().GetURL(); + autofill_manager_->client() + .GetLastCommittedPrimaryMainFrameOrigin() + .GetURL(); request_details.total_amount = ongoing_flow_state_->final_checkout_amount; // Only `USD` is supported for MVP. request_details.currency = "USD"; @@ -523,9 +506,10 @@ std::vector<BnplIssuerContext> BnplManager::GetSortedBnplIssuerContext() { AutofillOptimizationGuide* autofill_optimization_guide = - autofill_client_->GetAutofillOptimizationGuide(); - const GURL& merchant_url = - autofill_client_->GetLastCommittedPrimaryMainFrameOrigin().GetURL(); + autofill_manager_->client().GetAutofillOptimizationGuide(); + const GURL& merchant_url = autofill_manager_->client() + .GetLastCommittedPrimaryMainFrameOrigin() + .GetURL(); // Check BNPL issuer eligibility for the current page and save the // eligibility with the corresponding issuer to the vector of
diff --git a/components/autofill/core/browser/payments/bnpl_manager.h b/components/autofill/core/browser/payments/bnpl_manager.h index 4db7a84..36942e34 100644 --- a/components/autofill/core/browser/payments/bnpl_manager.h +++ b/components/autofill/core/browser/payments/bnpl_manager.h
@@ -16,7 +16,7 @@ #include "base/memory/raw_ref.h" #include "base/memory/weak_ptr.h" #include "components/autofill/core/browser/data_model/payments/bnpl_issuer.h" -#include "components/autofill/core/browser/foundations/autofill_client.h" +#include "components/autofill/core/browser/foundations/autofill_manager.h" #include "components/autofill/core/browser/payments/legal_message_line.h" #include "components/autofill/core/browser/payments/payments_autofill_client.h" #include "components/autofill/core/browser/payments/payments_window_manager.h" @@ -32,14 +32,13 @@ struct BnplFetchUrlResponseDetails; struct BnplIssuerContext; -// Owned by PaymentsAutofillClient. There is one instance of this class per Web -// Contents. This class manages the flow for BNPL to complete a payment -// transaction. +// Owned by AutofillManager. There is one instance of this class per frame. This +// class manages the flow for BNPL to complete a payment transaction. class BnplManager { public: using OnBnplVcnFetchedCallback = base::OnceCallback<void(const CreditCard&)>; - explicit BnplManager(AutofillClient* autofill_client); + explicit BnplManager(AutofillManager* autofill_manager); BnplManager(const BnplManager& other) = delete; BnplManager& operator=(const BnplManager& other) = delete; virtual ~BnplManager(); @@ -79,10 +78,6 @@ virtual void OnAmountExtractionReturned( const std::optional<uint64_t>& extracted_amount); - // Returns if user has seen a BNPL suggestion before and if the BNPL - // feature is enabled. Does not check for user's locale. - bool ShouldShowBnplSettings() const; - private: friend class BnplManagerTestApi; friend class BnplManagerTest; @@ -238,16 +233,16 @@ // uneligible + unlinked. std::vector<BnplIssuerContext> GetSortedBnplIssuerContext(); - PaymentsAutofillClient& payments_autofill_client() { - return *autofill_client_->GetPaymentsAutofillClient(); - } - const PaymentsAutofillClient& payments_autofill_client() const { return const_cast<BnplManager*>(this)->payments_autofill_client(); } - // The associated autofill client. - const raw_ref<AutofillClient> autofill_client_; + PaymentsAutofillClient& payments_autofill_client() { + return *autofill_manager_->client().GetPaymentsAutofillClient(); + } + + // The associated autofill manager. + const raw_ref<AutofillManager> autofill_manager_; // The state for the ongoing flow. Only present if there is a flow currently // ongoing. Set when a flow is initiated, and reset upon flow completion.
diff --git a/components/autofill/core/browser/payments/bnpl_manager_unittest.cc b/components/autofill/core/browser/payments/bnpl_manager_unittest.cc index 4ef5493b..9ef95d9e 100644 --- a/components/autofill/core/browser/payments/bnpl_manager_unittest.cc +++ b/components/autofill/core/browser/payments/bnpl_manager_unittest.cc
@@ -13,6 +13,8 @@ #include "components/autofill/core/browser/data_manager/payments/payments_data_manager_test_api.h" #include "components/autofill/core/browser/data_model/payments/bnpl_issuer.h" #include "components/autofill/core/browser/foundations/test_autofill_client.h" +#include "components/autofill/core/browser/foundations/test_autofill_driver.h" +#include "components/autofill/core/browser/foundations/test_browser_autofill_manager.h" #include "components/autofill/core/browser/integrators/optimization_guide/mock_autofill_optimization_guide.h" #include "components/autofill/core/browser/metrics/payments/bnpl_metrics.h" #include "components/autofill/core/browser/payments/bnpl_manager_test_api.h" @@ -155,8 +157,13 @@ autofill_client_.get())); autofill_client_->GetPaymentsAutofillClient() ->set_payments_network_interface(std::move(payments_network_interface)); - - bnpl_manager_ = std::make_unique<BnplManager>(autofill_client_.get()); + autofill_driver_ = + std::make_unique<TestAutofillDriver>(autofill_client_.get()); + autofill_driver_->set_autofill_manager( + std::make_unique<TestBrowserAutofillManager>(autofill_driver_.get())); + bnpl_manager_ = + std::make_unique<BnplManager>(static_cast<BrowserAutofillManager*>( + &autofill_driver_->GetAutofillManager())); } // Sets up the PersonalDataManager with a unlinked bnpl issuer. @@ -221,6 +228,7 @@ protected: base::test::TaskEnvironment task_environment_; std::unique_ptr<TestAutofillClient> autofill_client_; + std::unique_ptr<TestAutofillDriver> autofill_driver_; std::unique_ptr<BnplManager> bnpl_manager_; raw_ptr<PaymentsNetworkInterfaceMock> payments_network_interface_; base::test::ScopedFeatureList scoped_feature_list_; @@ -1294,89 +1302,6 @@ bnpl_manager_->OnAmountExtractionReturned(1'234'560'000ULL); } -// Tests that BNPL settings toggle should not be shown if all BNPL -// feature flags are disabled. -TEST_F(BnplManagerTest, BnplSettingsToggleNotShown_BnplFeatureDisabled) { - // Add one linked issuer and one unlinked issuer to payments data manager. - SetUpLinkedBnplIssuer(/*price_lower_bound_in_micros=*/40'000'000, - /*price_higher_bound_in_micros=*/1'000'000'000, - std::string(kBnplAffirmIssuerId), - /*instrument_id=*/1234); - SetUpUnlinkedBnplIssuer(/*price_lower_bound_in_micros=*/1'000'000'000, - /*price_higher_bound_in_micros=*/2'000'000'000, - std::string(kBnplZipIssuerId)); - - // Enable `HasSeenBnpl` flag by generating BNPL suggestion. - TriggerBnplUpdateSuggestionsFlow( - /*expect_suggestions_are_updated=*/true, - /*extracted_amount=*/1'234'560'000ULL); - - EXPECT_TRUE(bnpl_manager_->ShouldShowBnplSettings()); - - scoped_feature_list_.Reset(); - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{}, - /*disabled_features=*/{features::kAutofillEnableBuyNowPayLaterSyncing, - features::kAutofillEnableBuyNowPayLater}); - - EXPECT_FALSE(bnpl_manager_->ShouldShowBnplSettings()); -} - -// Tests that BNPL settings toggle should not be shown if BNPL -// issuer feature flags are disabled. -TEST_F(BnplManagerTest, BnplSettingsToggleNotShown_BnplIssuerFeaturesDisabled) { - // Add one linked issuer and one unlinked issuer to payments data manager. - SetUpLinkedBnplIssuer(/*price_lower_bound_in_micros=*/40'000'000, - /*price_higher_bound_in_micros=*/1'000'000'000, - std::string(kBnplAffirmIssuerId), - /*instrument_id=*/1234); - SetUpUnlinkedBnplIssuer(/*price_lower_bound_in_micros=*/1'000'000'000, - /*price_higher_bound_in_micros=*/2'000'000'000, - std::string(kBnplZipIssuerId)); - - // Enable `HasSeenBnpl` flag by generating BNPL suggestion. - TriggerBnplUpdateSuggestionsFlow( - /*expect_suggestions_are_updated=*/true, - /*extracted_amount=*/1'234'560'000ULL); - - EXPECT_TRUE(bnpl_manager_->ShouldShowBnplSettings()); - - scoped_feature_list_.Reset(); - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{features::kAutofillEnableBuyNowPayLaterSyncing}, - /*disabled_features=*/{features::kAutofillEnableBuyNowPayLater}); - - EXPECT_FALSE(bnpl_manager_->ShouldShowBnplSettings()); -} - -// Tests that BNPL settings toggle should be shown only after BNPL suggestions -// have been generated before. -TEST_F(BnplManagerTest, BnplSettingsToggleNotShown_HasSeenBnpl) { - // Add one linked issuer and one unlinked issuer to payments data manager. - SetUpLinkedBnplIssuer(/*price_lower_bound_in_micros=*/40'000'000, - /*price_higher_bound_in_micros=*/1'000'000'000, - std::string(kBnplAffirmIssuerId), - /*instrument_id=*/1234); - SetUpUnlinkedBnplIssuer(/*price_lower_bound_in_micros=*/1'000'000'000, - /*price_higher_bound_in_micros=*/2'000'000'000, - std::string(kBnplZipIssuerId)); - - EXPECT_FALSE(autofill_client_->GetPersonalDataManager() - .payments_data_manager() - .IsAutofillHasSeenBnplPrefEnabled()); - EXPECT_FALSE(bnpl_manager_->ShouldShowBnplSettings()); - - // Enable `HasSeenBnpl` flag by generating BNPL suggestion. - TriggerBnplUpdateSuggestionsFlow( - /*expect_suggestions_are_updated=*/true, - /*extracted_amount=*/1'234'560'000ULL); - - EXPECT_TRUE(autofill_client_->GetPersonalDataManager() - .payments_data_manager() - .IsAutofillHasSeenBnplPrefEnabled()); - EXPECT_TRUE(bnpl_manager_->ShouldShowBnplSettings()); -} - // Tests that when CreateBnplPaymentInstrument and responds with a success // response, expecting GetBnplPaymentInstrumentForFetchingUrl call with the // returned instrument ID.
diff --git a/components/autofill/core/browser/payments/payments_autofill_client.cc b/components/autofill/core/browser/payments/payments_autofill_client.cc index 392011e..23c952a0 100644 --- a/components/autofill/core/browser/payments/payments_autofill_client.cc +++ b/components/autofill/core/browser/payments/payments_autofill_client.cc
@@ -243,10 +243,6 @@ return nullptr; } -payments::BnplManager* PaymentsAutofillClient::GetPaymentsBnplManager() { - return nullptr; -} - void PaymentsAutofillClient::ShowCreditCardSaveAndFillDialog() {} void PaymentsAutofillClient::ShowSelectBnplIssuerDialog(
diff --git a/components/autofill/core/browser/payments/payments_autofill_client.h b/components/autofill/core/browser/payments/payments_autofill_client.h index c0bd5e08a..8e4c038 100644 --- a/components/autofill/core/browser/payments/payments_autofill_client.h +++ b/components/autofill/core/browser/payments/payments_autofill_client.h
@@ -58,7 +58,6 @@ namespace payments { struct BnplIssuerContext; -class BnplManager; class MandatoryReauthManager; class PaymentsNetworkInterface; class PaymentsWindowManager; @@ -564,11 +563,6 @@ virtual payments::MandatoryReauthManager* GetOrCreatePaymentsMandatoryReauthManager(); - // Gets the payments BNPL manager owned by the client. This will be used to - // handle BNPL flows. It is not implemented on iOS and iOS WebView, and should - // not be used on those platforms. - virtual payments::BnplManager* GetPaymentsBnplManager(); - // Shows the `Save and Fill` modal dialog. virtual void ShowCreditCardSaveAndFillDialog();
diff --git a/components/autofill/core/browser/payments/test/mock_bnpl_manager.cc b/components/autofill/core/browser/payments/test/mock_bnpl_manager.cc index cce190a..dc769ef 100644 --- a/components/autofill/core/browser/payments/test/mock_bnpl_manager.cc +++ b/components/autofill/core/browser/payments/test/mock_bnpl_manager.cc
@@ -4,10 +4,13 @@ #include "components/autofill/core/browser/payments/test/mock_bnpl_manager.h" +#include "components/autofill/core/browser/foundations/test_browser_autofill_manager.h" + namespace autofill { -MockBnplManager::MockBnplManager(TestAutofillClient* test_autofill_client) - : BnplManager(test_autofill_client) { +MockBnplManager::MockBnplManager( + TestBrowserAutofillManager* test_browser_autofill_manager) + : BnplManager(test_browser_autofill_manager) { ON_CALL(*this, NotifyOfSuggestionGeneration) .WillByDefault( [this](const AutofillSuggestionTriggerSource trigger_source) {
diff --git a/components/autofill/core/browser/payments/test/mock_bnpl_manager.h b/components/autofill/core/browser/payments/test/mock_bnpl_manager.h index 8d57463f..f8946a3 100644 --- a/components/autofill/core/browser/payments/test/mock_bnpl_manager.h +++ b/components/autofill/core/browser/payments/test/mock_bnpl_manager.h
@@ -5,16 +5,18 @@ #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_MOCK_BNPL_MANAGER_H_ #define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_MOCK_BNPL_MANAGER_H_ -#include "components/autofill/core/browser/foundations/test_autofill_client.h" #include "components/autofill/core/browser/payments/bnpl_manager.h" #include "components/autofill/core/browser/suggestions/suggestion.h" #include "testing/gmock/include/gmock/gmock.h" namespace autofill { +class TestBrowserAutofillManager; + class MockBnplManager : public payments::BnplManager { public: - explicit MockBnplManager(TestAutofillClient* test_autofill_client); + explicit MockBnplManager( + TestBrowserAutofillManager* test_browser_autofill_manager); ~MockBnplManager() override; MOCK_METHOD(void,
diff --git a/components/autofill/core/browser/payments/test_payments_autofill_client.cc b/components/autofill/core/browser/payments/test_payments_autofill_client.cc index 000778d..da4d88d 100644 --- a/components/autofill/core/browser/payments/test_payments_autofill_client.cc +++ b/components/autofill/core/browser/payments/test_payments_autofill_client.cc
@@ -14,11 +14,9 @@ #include "components/autofill/core/browser/foundations/autofill_client.h" #include "components/autofill/core/browser/integrators/touch_to_fill_delegate.h" #include "components/autofill/core/browser/payments/autofill_offer_manager.h" -#include "components/autofill/core/browser/payments/bnpl_manager.h" #include "components/autofill/core/browser/payments/credit_card_cvc_authenticator.h" #include "components/autofill/core/browser/payments/credit_card_otp_authenticator.h" #include "components/autofill/core/browser/payments/mandatory_reauth_manager.h" -#include "components/autofill/core/browser/payments/test/mock_bnpl_manager.h" #include "components/autofill/core/browser/payments/test/mock_payments_window_manager.h" #include "components/autofill/core/browser/payments/virtual_card_enrollment_manager.h" #include "components/autofill/core/browser/single_field_fillers/payments/merchant_promo_code_manager.h" @@ -174,15 +172,6 @@ mandatory_reauth_opt_in_prompt_was_shown_ = true; } -BnplManager* TestPaymentsAutofillClient::GetPaymentsBnplManager() { - if (!bnpl_manager_) { - bnpl_manager_ = std::make_unique<BnplManager>( - &static_cast<TestAutofillClient&>(client_.get())); - } - - return bnpl_manager_.get(); -} - MockIbanManager* TestPaymentsAutofillClient::GetIbanManager() { if (!mock_iban_manager_) { mock_iban_manager_ = std::make_unique<testing::NiceMock<MockIbanManager>>( @@ -271,15 +260,6 @@ unmask_authenticator_selection_dialog_shown_ = true; } -MockBnplManager& TestPaymentsAutofillClient::CreateOrGetMockBnplManager() { - if (!bnpl_manager_) { - bnpl_manager_ = std::make_unique<testing::NiceMock<MockBnplManager>>( - &static_cast<TestAutofillClient&>(client_.get())); - } - - return static_cast<MockBnplManager&>(*bnpl_manager_.get()); -} - #if BUILDFLAG(IS_ANDROID) void TestPaymentsAutofillClient:: SetUpDeviceBiometricAuthenticatorSuccessOnAutomotive() {
diff --git a/components/autofill/core/browser/payments/test_payments_autofill_client.h b/components/autofill/core/browser/payments/test_payments_autofill_client.h index 74282207..26cca1a 100644 --- a/components/autofill/core/browser/payments/test_payments_autofill_client.h +++ b/components/autofill/core/browser/payments/test_payments_autofill_client.h
@@ -38,13 +38,11 @@ #endif // !BUILDFLAG(IS_IOS) class CreditCardCvcAuthenticator; class CreditCardOtpAuthenticator; -class MockBnplManager; class TouchToFillDelegate; class VirtualCardEnrollmentManager; namespace payments { -class BnplManager; class PaymentsWindowManager; // This class is for easier writing of tests. It is owned by TestAutofillClient. @@ -100,7 +98,6 @@ base::OnceClosure accept_mandatory_reauth_callback, base::OnceClosure cancel_mandatory_reauth_callback, base::RepeatingClosure close_mandatory_reauth_callback) override; - BnplManager* GetPaymentsBnplManager() override; MockIbanManager* GetIbanManager() override; MockIbanAccessManager* GetIbanAccessManager() override; void ShowMandatoryReauthOptInConfirmation() override; @@ -188,8 +185,6 @@ autofill_offer_manager_ = std::move(autofill_offer_manager); } - MockBnplManager& CreateOrGetMockBnplManager(); - bool unmask_authenticator_selection_dialog_shown() const { return unmask_authenticator_selection_dialog_shown_; } @@ -251,7 +246,6 @@ std::unique_ptr<VirtualCardEnrollmentManager> virtual_card_enrollment_manager_; - std::unique_ptr<BnplManager> bnpl_manager_; std::unique_ptr<CreditCardCvcAuthenticator> cvc_authenticator_;
diff --git a/components/autofill/core/browser/ui/autofill_external_delegate.cc b/components/autofill/core/browser/ui/autofill_external_delegate.cc index 2be65ad1..a7169aa 100644 --- a/components/autofill/core/browser/ui/autofill_external_delegate.cc +++ b/components/autofill/core/browser/ui/autofill_external_delegate.cc
@@ -1365,29 +1365,29 @@ base::BindOnce(&AutofillExternalDelegate::OnCreditCardScanned, GetWeakPtr())); break; - case SuggestionType::kBnplEntry: + case SuggestionType::kBnplEntry: { CHECK(suggestion.GetPayload<Suggestion::PaymentsPayload>() .extracted_amount_in_micros.has_value()); - manager_->client() - .GetPaymentsAutofillClient() - ->GetPaymentsBnplManager() - ->InitBnplFlow( - /*final_checkout_amount=*/suggestion - .GetPayload<Suggestion::PaymentsPayload>() - .extracted_amount_in_micros.value(), - base::BindOnce( - [](base::WeakPtr<AutofillExternalDelegate> delegate, - const CreditCard& card) { - if (delegate) { - delegate->manager_->FillOrPreviewCreditCardForm( - mojom::ActionPersistence::kFill, - delegate->query_form_, - delegate->query_field_.global_id(), card, - AutofillTriggerSource::kPopup); - } - }, - GetWeakPtr())); + payments::BnplManager* bnpl_manager = manager_->GetPaymentsBnplManager(); + CHECK(bnpl_manager); + + bnpl_manager->InitBnplFlow( + /*final_checkout_amount=*/suggestion + .GetPayload<Suggestion::PaymentsPayload>() + .extracted_amount_in_micros.value(), + base::BindOnce( + [](base::WeakPtr<AutofillExternalDelegate> delegate, + const CreditCard& card) { + if (delegate) { + delegate->manager_->FillOrPreviewCreditCardForm( + mojom::ActionPersistence::kFill, delegate->query_form_, + delegate->query_field_.global_id(), card, + AutofillTriggerSource::kPopup); + } + }, + GetWeakPtr())); break; + } default: NOTREACHED(); // Should be handled elsewhere }
diff --git a/components/autofill/core/browser/ui/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/ui/autofill_external_delegate_unittest.cc index dfa33327..67d75f4 100644 --- a/components/autofill/core/browser/ui/autofill_external_delegate_unittest.cc +++ b/components/autofill/core/browser/ui/autofill_external_delegate_unittest.cc
@@ -260,6 +260,8 @@ test_api(*this).set_credit_card_access_manager( std::make_unique<TestCreditCardAccessManager>( this, test_api(*this).credit_card_form_event_logger())); + test_api(*this).set_bnpl_manager( + std::make_unique<testing::NiceMock<MockBnplManager>>(this)); } MockBrowserAutofillManager(const MockBrowserAutofillManager&) = delete; MockBrowserAutofillManager& operator=(const MockBrowserAutofillManager&) = @@ -753,14 +755,13 @@ OnSuggestionsReturned(queried_field().global_id(), autocomplete_items); } +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) // Test that `BnplManager::OnSuggestionsShown` will not be called if the // suggestion list doesn't contain a credit card entry. -TEST_F(AutofillExternalDelegateTest, SuggestionsShownWithoutCreditCardEntry) { - // Set up `BnplManager` for testing. - MockBnplManager& bnpl_manager = - client().GetPaymentsAutofillClient()->CreateOrGetMockBnplManager(); - - EXPECT_CALL(bnpl_manager, OnSuggestionsShown).Times(0); +TEST_F(AutofillExternalDelegateTest, + BnplSuggestionsNotShownWithoutCreditCardEntry) { + EXPECT_CALL(*manager().GetPaymentsBnplManager(), OnSuggestionsShown).Times(0); const std::vector<Suggestion> suggestions = { test::CreateAutofillSuggestion(SuggestionType::kAddressEntry), @@ -772,12 +773,8 @@ // Test that `BnplManager::OnSuggestionsShown` will be called if the // suggestion list contains a credit card entry. -TEST_F(AutofillExternalDelegateTest, SuggestionsShownWithCreditCardEntry) { - // Set up `BnplManager` for testing. - MockBnplManager& bnpl_manager = - client().GetPaymentsAutofillClient()->CreateOrGetMockBnplManager(); - - EXPECT_CALL(bnpl_manager, OnSuggestionsShown).Times(1); +TEST_F(AutofillExternalDelegateTest, BnplSuggestionsShownWithCreditCardEntry) { + EXPECT_CALL(*manager().GetPaymentsBnplManager(), OnSuggestionsShown).Times(1); const std::vector<Suggestion> suggestions = { test::CreateAutofillSuggestion(SuggestionType::kCreditCardEntry), @@ -795,9 +792,9 @@ card.set_issuer_id(payments::BnplManager::GetSupportedBnplIssuerIds()[0]); const uint64_t expected_amount = 50'000'000; - EXPECT_CALL( - client().GetPaymentsAutofillClient()->CreateOrGetMockBnplManager(), - InitBnplFlow(expected_amount, _)) + + EXPECT_CALL(*manager().GetPaymentsBnplManager(), + InitBnplFlow(expected_amount, _)) .WillOnce(RunOnceCallback<1>(card)); EXPECT_CALL(manager(), FillOrPreviewCreditCardForm( @@ -812,6 +809,8 @@ payments_payload), {}); } +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) // Test that the Autofill popup is able to display warnings explaining why // Autofill is disabled for a website.
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index 3d70e95..9e19706a 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -193,12 +193,6 @@ "AutofillEnableVcn3dsAuthentication", base::FEATURE_DISABLED_BY_DEFAULT); -// When enabled, Chrome will display grayed out virtual card suggestions on -// merchant websites where the merchant has opted-out of virtual cards. -BASE_FEATURE(kAutofillEnableVcnGrayOutForMerchantOptOut, - "AutofillEnableVcnGrayOutForMerchantOptOut", - base::FEATURE_ENABLED_BY_DEFAULT); - #if BUILDFLAG(IS_IOS) // When enabled, save card bottomsheet will be shown when the user has not // previously rejected the offer to save the card, and both a valid expiry date
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index 3e2ccf5..25c48138 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -78,8 +78,6 @@ COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillEnableVcn3dsAuthentication); COMPONENT_EXPORT(AUTOFILL) -BASE_DECLARE_FEATURE(kAutofillEnableVcnGrayOutForMerchantOptOut); -COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillParseVcnCardOnFileStandaloneCvcFields); #if BUILDFLAG(IS_IOS) COMPONENT_EXPORT(AUTOFILL)
diff --git a/components/browser_ui/util/android/BUILD.gn b/components/browser_ui/util/android/BUILD.gn index ece02fd..5c49b72 100644 --- a/components/browser_ui/util/android/BUILD.gn +++ b/components/browser_ui/util/android/BUILD.gn
@@ -18,7 +18,6 @@ "java/src/org/chromium/components/browser_ui/util/DrawableUtils.java", "java/src/org/chromium/components/browser_ui/util/FirstDrawDetector.java", "java/src/org/chromium/components/browser_ui/util/GlobalDiscardableReferencePool.java", - "java/src/org/chromium/components/browser_ui/util/KeyboardNavigationListener.java", "java/src/org/chromium/components/browser_ui/util/ToolbarUtils.java", "java/src/org/chromium/components/browser_ui/util/TraceEventVectorDrawableCompat.java", "java/src/org/chromium/components/browser_ui/util/date/CalendarFactory.java",
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableListToolbar.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableListToolbar.java index 9ee18472e..83ce8cc 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableListToolbar.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/selectable_list/SelectableListToolbar.java
@@ -44,7 +44,6 @@ import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.Nullable; import org.chromium.components.browser_ui.styles.SemanticColorUtils; -import org.chromium.components.browser_ui.util.KeyboardNavigationListener; import org.chromium.components.browser_ui.widget.NumberRollView; import org.chromium.components.browser_ui.widget.R; import org.chromium.components.browser_ui.widget.TintedDrawable; @@ -56,6 +55,7 @@ import org.chromium.ui.UiUtils; import org.chromium.ui.text.EmptyTextWatcher; import org.chromium.ui.util.ColorUtils; +import org.chromium.ui.util.KeyboardNavigationListener; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;
diff --git a/components/collaboration/internal/messaging/messaging_backend_service_impl.cc b/components/collaboration/internal/messaging/messaging_backend_service_impl.cc index bff9e83..f77a9a5 100644 --- a/components/collaboration/internal/messaging/messaging_backend_service_impl.cc +++ b/components/collaboration/internal/messaging/messaging_backend_service_impl.cc
@@ -634,17 +634,9 @@ void MessagingBackendServiceImpl::ClearDirtyTabMessagesForGroup( const data_sharing::GroupId& collaboration_group_id) { - std::optional<tab_groups::SavedTabGroup> tab_group; - for (const auto& group : tab_group_sync_service_->GetAllGroups()) { - if (group.collaboration_id() && - data_sharing::GroupId(group.collaboration_id().value().value()) == - collaboration_group_id) { - tab_group = group; - break; - } - } - - ClearDirtyTabMessagesForGroup(collaboration_group_id, tab_group); + ClearDirtyTabMessagesForGroup( + collaboration_group_id, + GetTabGroupFromCollaborationId(collaboration_group_id.value())); } void MessagingBackendServiceImpl::OnStoreInitialized(bool success) { @@ -1096,15 +1088,8 @@ return; } - std::optional<tab_groups::SavedTabGroup> tab_group; - for (const auto& group : tab_group_sync_service_->GetAllGroups()) { - if (group.collaboration_id() && - data_sharing::GroupId(group.collaboration_id().value().value()) == - group_data.group_token.group_id) { - tab_group = group; - break; - } - } + std::optional<tab_groups::SavedTabGroup> tab_group = + GetTabGroupFromCollaborationId(group_data.group_token.group_id.value()); if (!tab_group) { // The tab group may be deleted or not synced. // TODO(386420717): Maybe persist the message to disk in case the tab group @@ -1274,17 +1259,16 @@ item.activity_metadata.id = base::Uuid::ParseLowercase(message.uuid()); item.activity_metadata.collaboration_id = collaboration_group_id; + std::optional<tab_groups::SavedTabGroup> tab_group = + GetTabGroupFromCollaborationId(message.collaboration_id()); + item.activity_metadata.tab_group_metadata = + CreateTabGroupMessageMetadataFromMessageOrTabGroup(message, tab_group); + // The code below needs to fill in `activity_metadata`, and optionally // `show_favicon` if it is true. switch (GetMessageCategory(message)) { case MessageCategory::kTab: { item.show_favicon = true; - - std::optional<tab_groups::SavedTabGroup> tab_group = - GetTabGroupFromMessage(message); - item.activity_metadata.tab_group_metadata = - CreateTabGroupMessageMetadataFromMessageOrTabGroup(message, - tab_group); item.activity_metadata.tab_metadata = CreateTabMessageMetadataFromMessageOrTab( message, GetTabFromGroup(message, tab_group)); @@ -1302,9 +1286,6 @@ case MessageCategory::kTabGroup: { item.activity_metadata.triggering_user = group_member; item.activity_metadata.triggering_user_is_self = is_self; - 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) { @@ -1376,25 +1357,26 @@ } return CreateTabGroupMessageMetadataFromCollaborationId( - message, GetTabGroupFromMessage(message), + message, GetTabGroupFromCollaborationId(message.collaboration_id()), 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()) { +MessagingBackendServiceImpl::GetTabGroupFromCollaborationId( + const std::string& collaboration_id) { + if (collaboration_id.empty()) { return std::nullopt; } - return tab_group_sync_service_->GetGroup( - base::Uuid::ParseLowercase(sync_tab_group_id)); + tab_groups::CollaborationId collaboration_group_id(collaboration_id); + for (const auto& group : tab_group_sync_service_->GetAllGroups()) { + if (group.collaboration_id().has_value() && + group.collaboration_id().value() == collaboration_group_id) { + return group; + } + } + + return std::nullopt; } std::optional<data_sharing::GroupMember> @@ -1473,7 +1455,7 @@ bool allow_dirty_tab_group_message) { std::vector<PersistentMessage> persistent_messages; std::optional<tab_groups::SavedTabGroup> tab_group = - GetTabGroupFromMessage(message); + GetTabGroupFromCollaborationId(message.collaboration_id()); // Special case: First handle if it's of type TOMBSTONED. bool has_tombstoned =
diff --git a/components/collaboration/internal/messaging/messaging_backend_service_impl.h b/components/collaboration/internal/messaging/messaging_backend_service_impl.h index 4544579..f35c8f68 100644 --- a/components/collaboration/internal/messaging/messaging_backend_service_impl.h +++ b/components/collaboration/internal/messaging/messaging_backend_service_impl.h
@@ -153,9 +153,9 @@ 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); + // Tries to retrieve the tab group from CollaborationId. + std::optional<tab_groups::SavedTabGroup> GetTabGroupFromCollaborationId( + const std::string& collaboration_id); // Uses the available data to look up a GroupMember. std::optional<data_sharing::GroupMember> GetGroupMemberFromGaiaId(
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 f05ccde..2a887900 100644 --- a/components/collaboration/internal/messaging/messaging_backend_service_impl_unittest.cc +++ b/components/collaboration/internal/messaging/messaging_backend_service_impl_unittest.cc
@@ -476,6 +476,14 @@ .WillRepeatedly(Return(CreatePartialMember( GaiaId("gaia_2"), "gaia2@gmail.com", "Display Name 2", ""))); + 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)); + ActivityLogQueryParams params; params.collaboration_id = collaboration_group_id; std::vector<ActivityLogItem> activity_log = service_->GetActivityLog(params); @@ -541,6 +549,9 @@ Return(CreatePartialMember(GaiaId("gaia_1"), "gaia1@gmail.com", "Display Name", "Given Name 1"))); + 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)); @@ -710,6 +721,9 @@ Return(CreatePartialMember(GaiaId("gaia_2"), "gaia2@gmail.com", "Display Name", "Given Name 2"))); + 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)); @@ -1214,6 +1228,9 @@ Eq(GaiaId("gaia_3")))) .WillRepeatedly(Return(std::nullopt)); + 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));
diff --git a/components/content_settings/browser/ui/cookie_controls_controller.cc b/components/content_settings/browser/ui/cookie_controls_controller.cc index 94507e09..1a04580 100644 --- a/components/content_settings/browser/ui/cookie_controls_controller.cc +++ b/components/content_settings/browser/ui/cookie_controls_controller.cc
@@ -688,18 +688,6 @@ if (!controls_visible) { return false; } - if (ShowActFeatures()) { - bool has_controllable_feature = false; - std::vector<TrackingProtectionFeature>::iterator it; - for (it = features.begin(); it != features.end(); it++) { - has_controllable_feature |= - it->enforcement == CookieControlsEnforcement::kNoEnforcement; - } - // Don't show UB if none of the ACT features can be controlled - if (!has_controllable_feature) { - return false; - } - } // 3PCD prevents SameSite=None cookies from being sent when the top-level // document is sandboxed without `allow-origin`. For instance when loaded // with: `Content-Security-Policy: sandbox`. In that case, we render the UI to
diff --git a/components/enterprise/browser/reporting/report_scheduler.cc b/components/enterprise/browser/reporting/report_scheduler.cc index 9c60b8c..579e73ad 100644 --- a/components/enterprise/browser/reporting/report_scheduler.cc +++ b/components/enterprise/browser/reporting/report_scheduler.cc
@@ -81,6 +81,8 @@ base::BindRepeating(&ReportScheduler::GenerateAndUploadReport, weak_ptr_factory_.GetWeakPtr())); RegisterPrefObserver(); + + delegate_->OnInitializationCompleted(); } ReportScheduler::~ReportScheduler() = default; @@ -275,6 +277,7 @@ std::make_unique<ReportUploader>(cloud_policy_client_, kMaximumRetry); } RecordUploadTrigger(active_trigger_); + // TODO(crbug.com/399164647): Add cookie to upload request for signals reports report_uploader_->SetRequestAndUpload( TriggerToReportType(active_trigger_), std::move(requests), base::BindOnce(&ReportScheduler::OnReportUploaded, @@ -323,6 +326,15 @@ if (pending_triggers_ & kTriggerManual) pending_triggers_ -= kTriggerManual; } + + // TODO(crbug.com/402486791): Add Security signals report trigger to this + // check. Full report from timer and manual trigger contain security signals + // as well (if required and allowed), in form delegate to refresh the signals + // report timer as well. + if ((active_trigger_ == kTriggerManual || active_trigger_ == kTriggerTimer)) { + delegate_->OnSecuritySignalsUploaded(); + } + active_trigger_ = kTriggerNone; RunPendingTriggers(); }
diff --git a/components/enterprise/browser/reporting/report_scheduler.h b/components/enterprise/browser/reporting/report_scheduler.h index b70a08b..487da68 100644 --- a/components/enterprise/browser/reporting/report_scheduler.h +++ b/components/enterprise/browser/reporting/report_scheduler.h
@@ -60,6 +60,9 @@ virtual PrefService* GetPrefService() = 0; + // Run once after initialization of the scheduler is complete. + virtual void OnInitializationCompleted() = 0; + // Browser version virtual void StartWatchingUpdatesIfNeeded( base::Time last_upload, @@ -70,6 +73,12 @@ virtual policy::DMToken GetProfileDMToken() = 0; virtual std::string GetProfileClientId() = 0; + // Security signals + virtual bool AreSecurityReportsEnabled() = 0; + virtual bool UseCookiesInUploads() = 0; + // Invoked when security signals was uploaded by a report. + virtual void OnSecuritySignalsUploaded() = 0; + protected: ReportTriggerCallback trigger_report_callback_; };
diff --git a/components/enterprise/browser/reporting/user_security_signals_service.cc b/components/enterprise/browser/reporting/user_security_signals_service.cc index 88daca57..2f2c8e20 100644 --- a/components/enterprise/browser/reporting/user_security_signals_service.cc +++ b/components/enterprise/browser/reporting/user_security_signals_service.cc
@@ -83,12 +83,8 @@ void UserSecuritySignalsService::TriggerReport(SecurityReportTrigger trigger) { base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, - base::BindOnce( - &Delegate::OnReportEventTriggered, base::Unretained(delegate_), - trigger, - base::BindOnce(&UserSecuritySignalsService::OnReportUploaded, - weak_factory_.GetWeakPtr()))); + FROM_HERE, base::BindOnce(&Delegate::OnReportEventTriggered, + base::Unretained(delegate_), trigger)); } } // namespace enterprise_reporting
diff --git a/components/enterprise/browser/reporting/user_security_signals_service.h b/components/enterprise/browser/reporting/user_security_signals_service.h index a9928d4..c2eb2cc 100644 --- a/components/enterprise/browser/reporting/user_security_signals_service.h +++ b/components/enterprise/browser/reporting/user_security_signals_service.h
@@ -23,8 +23,7 @@ public: // Invoked when `trigger` happens, and will only be invoked if the current // policy values dictate that this trigger is meaningful. - virtual void OnReportEventTriggered(SecurityReportTrigger trigger, - base::OnceClosure done_closure) = 0; + virtual void OnReportEventTriggered(SecurityReportTrigger trigger) = 0; }; UserSecuritySignalsService(PrefService* profile_prefs, Delegate* delegate);
diff --git a/components/enterprise/browser/reporting/user_security_signals_service_unittest.cc b/components/enterprise/browser/reporting/user_security_signals_service_unittest.cc index a2765bf..b101a90 100644 --- a/components/enterprise/browser/reporting/user_security_signals_service_unittest.cc +++ b/components/enterprise/browser/reporting/user_security_signals_service_unittest.cc
@@ -28,7 +28,7 @@ MOCK_METHOD(void, OnReportEventTriggered, - (SecurityReportTrigger, base::OnceClosure), + (SecurityReportTrigger), (override)); }; @@ -44,11 +44,9 @@ } void SetUp() override { - ON_CALL(delegate_, OnReportEventTriggered(_, _)) + ON_CALL(delegate_, OnReportEventTriggered(_)) .WillByDefault( - [&](SecurityReportTrigger, base::OnceClosure done_closure) { - std::move(done_closure).Run(); - }); + [&](SecurityReportTrigger) { service_->OnReportUploaded(); }); } void SetEnabledPolicy(bool enabled) { @@ -59,16 +57,14 @@ testing_prefs_.SetBoolean(kUserSecurityAuthenticatedReporting, use_auth); } - std::unique_ptr<UserSecuritySignalsService> CreateUserSecuritySignalsService( - bool start_service = false) { - auto service = std::make_unique<UserSecuritySignalsService>(&testing_prefs_, - &delegate_); + void CreateUserSecuritySignalsService(bool start_service = false) { + service_ = std::make_unique<UserSecuritySignalsService>(&testing_prefs_, + &delegate_); if (start_service) { - service->Start(); + service_->Start(); task_environment_.RunUntilIdle(); } - return service; } void FastForwardTimeToTrigger() { @@ -87,33 +83,34 @@ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; TestingPrefServiceSimple testing_prefs_; + std::unique_ptr<UserSecuritySignalsService> service_ = nullptr; testing::StrictMock<MockUserSecuritySignalsServiceDelegate> delegate_; }; TEST_F(UserSecuritySignalsServiceTest, NotStarted) { - auto service = CreateUserSecuritySignalsService(); + CreateUserSecuritySignalsService(); - EXPECT_FALSE(service->IsSecuritySignalsReportingEnabled()); - EXPECT_FALSE(service->ShouldUseCookies()); + EXPECT_FALSE(service_->IsSecuritySignalsReportingEnabled()); + EXPECT_FALSE(service_->ShouldUseCookies()); SetEnabledPolicy(true); SetUseAuthPolicy(true); // Pref values should be available even if the service was not started. - EXPECT_TRUE(service->IsSecuritySignalsReportingEnabled()); - EXPECT_TRUE(service->ShouldUseCookies()); + EXPECT_TRUE(service_->IsSecuritySignalsReportingEnabled()); + EXPECT_TRUE(service_->ShouldUseCookies()); // No trigger should occur even if we fast forward. FastForwardTimeToTrigger(); } TEST_F(UserSecuritySignalsServiceTest, PolicyDefault) { - EXPECT_CALL(delegate_, OnReportEventTriggered(_, _)).Times(0); + EXPECT_CALL(delegate_, OnReportEventTriggered(_)).Times(0); - auto service = CreateUserSecuritySignalsService(/*start_service=*/true); + CreateUserSecuritySignalsService(/*start_service=*/true); - EXPECT_FALSE(service->IsSecuritySignalsReportingEnabled()); - EXPECT_FALSE(service->ShouldUseCookies()); + EXPECT_FALSE(service_->IsSecuritySignalsReportingEnabled()); + EXPECT_FALSE(service_->ShouldUseCookies()); // No trigger should occur even if we fast forward. FastForwardTimeToTrigger(); @@ -124,14 +121,13 @@ // Creation of the service with the pref value already enabled will trigger an // upload. - EXPECT_CALL(delegate_, - OnReportEventTriggered(SecurityReportTrigger::kTimer, _)) + EXPECT_CALL(delegate_, OnReportEventTriggered(SecurityReportTrigger::kTimer)) .Times(1); - auto service = CreateUserSecuritySignalsService(/*start_service=*/true); + CreateUserSecuritySignalsService(/*start_service=*/true); - EXPECT_TRUE(service->IsSecuritySignalsReportingEnabled()); - EXPECT_FALSE(service->ShouldUseCookies()); + EXPECT_TRUE(service_->IsSecuritySignalsReportingEnabled()); + EXPECT_FALSE(service_->ShouldUseCookies()); } TEST_F(UserSecuritySignalsServiceTest, PolicyEnabledWithCookies_FastForwards) { @@ -139,26 +135,23 @@ SetUseAuthPolicy(true); // A upload should occur first on service creation. - EXPECT_CALL(delegate_, - OnReportEventTriggered(SecurityReportTrigger::kTimer, _)) + EXPECT_CALL(delegate_, OnReportEventTriggered(SecurityReportTrigger::kTimer)) .Times(1); - auto service = CreateUserSecuritySignalsService(/*start_service=*/true); + CreateUserSecuritySignalsService(/*start_service=*/true); - EXPECT_TRUE(service->IsSecuritySignalsReportingEnabled()); - EXPECT_TRUE(service->ShouldUseCookies()); + EXPECT_TRUE(service_->IsSecuritySignalsReportingEnabled()); + EXPECT_TRUE(service_->ShouldUseCookies()); // Fast forwarding should trigger another upload. Mock::VerifyAndClearExpectations(&delegate_); - EXPECT_CALL(delegate_, - OnReportEventTriggered(SecurityReportTrigger::kTimer, _)) + EXPECT_CALL(delegate_, OnReportEventTriggered(SecurityReportTrigger::kTimer)) .Times(1); FastForwardTimeToTrigger(); // Fast forwarding again should trigger another upload. Mock::VerifyAndClearExpectations(&delegate_); - EXPECT_CALL(delegate_, - OnReportEventTriggered(SecurityReportTrigger::kTimer, _)) + EXPECT_CALL(delegate_, OnReportEventTriggered(SecurityReportTrigger::kTimer)) .Times(1); FastForwardTimeToTrigger(); } @@ -172,30 +165,27 @@ SetUseAuthPolicy(true); // A upload should occur first on service creation. - EXPECT_CALL(delegate_, - OnReportEventTriggered(SecurityReportTrigger::kTimer, _)) + EXPECT_CALL(delegate_, OnReportEventTriggered(SecurityReportTrigger::kTimer)) .Times(1); - auto service = CreateUserSecuritySignalsService(/*start_service=*/true); + CreateUserSecuritySignalsService(/*start_service=*/true); - EXPECT_TRUE(service->IsSecuritySignalsReportingEnabled()); - EXPECT_TRUE(service->ShouldUseCookies()); + EXPECT_TRUE(service_->IsSecuritySignalsReportingEnabled()); + EXPECT_TRUE(service_->ShouldUseCookies()); // Signaling that a report was uploaded after waiting a halftime means waiting // another halftime should not result in a second report being triggered. Mock::VerifyAndClearExpectations(&delegate_); - EXPECT_CALL(delegate_, - OnReportEventTriggered(SecurityReportTrigger::kTimer, _)) + EXPECT_CALL(delegate_, OnReportEventTriggered(SecurityReportTrigger::kTimer)) .Times(0); FastForwardByHalfTimeToTrigger(); - service->OnReportUploaded(); + service_->OnReportUploaded(); FastForwardByHalfTimeToTrigger(); } TEST_F(UserSecuritySignalsServiceTest, PolicyBecomesEnabledWithoutCookies) { - auto service = CreateUserSecuritySignalsService(/*start_service=*/true); - EXPECT_FALSE(service->IsSecuritySignalsReportingEnabled()); - EXPECT_CALL(delegate_, - OnReportEventTriggered(SecurityReportTrigger::kTimer, _)) + CreateUserSecuritySignalsService(/*start_service=*/true); + EXPECT_FALSE(service_->IsSecuritySignalsReportingEnabled()); + EXPECT_CALL(delegate_, OnReportEventTriggered(SecurityReportTrigger::kTimer)) .Times(0); // No trigger should occur even if we fast forward. @@ -203,8 +193,7 @@ Mock::VerifyAndClearExpectations(&delegate_); // A report should be triggered when the policy becomes enabled. - EXPECT_CALL(delegate_, - OnReportEventTriggered(SecurityReportTrigger::kTimer, _)) + EXPECT_CALL(delegate_, OnReportEventTriggered(SecurityReportTrigger::kTimer)) .Times(1); SetEnabledPolicy(true); task_environment_.RunUntilIdle();
diff --git a/components/enterprise/connectors/core/features.cc b/components/enterprise/connectors/core/features.cc index 784b936..58a772a 100644 --- a/components/enterprise/connectors/core/features.cc +++ b/components/enterprise/connectors/core/features.cc
@@ -14,4 +14,8 @@ "EnterpriseUrlFilteringEventReportingOnAndroid", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kEnterpriseRealtimeEventReportingOnIOS, + "EnterpriseRealtimeEventReportingOnIOS", + base::FEATURE_DISABLED_BY_DEFAULT); + } // namespace enterprise_connectors
diff --git a/components/enterprise/connectors/core/features.h b/components/enterprise/connectors/core/features.h index cc03a51..5074fac 100644 --- a/components/enterprise/connectors/core/features.h +++ b/components/enterprise/connectors/core/features.h
@@ -16,6 +16,9 @@ // `kEnterpriseSecurityEventReportingOnAndroid` is not enabled. BASE_DECLARE_FEATURE(kEnterpriseUrlFilteringEventReportingOnAndroid); +// Controls whether the realtime events reporting is enabled on iOS. +BASE_DECLARE_FEATURE(kEnterpriseRealtimeEventReportingOnIOS); + } // namespace enterprise_connectors #endif // COMPONENTS_ENTERPRISE_CONNECTORS_CORE_FEATURES_H_
diff --git a/components/eye_dropper/eye_dropper_view.cc b/components/eye_dropper/eye_dropper_view.cc index 716172de3..f31eca9 100644 --- a/components/eye_dropper/eye_dropper_view.cc +++ b/components/eye_dropper/eye_dropper_view.cc
@@ -202,8 +202,6 @@ view_position_handler_(std::make_unique<ViewPositionHandler>(this)), screen_capturer_(std::make_unique<ScreenCapturer>(this)) { SetModalType(ui::mojom::ModalType::kWindow); - // This is owned as a unique_ptr<EyeDropper> elsewhere. - SetOwnedByWidget(false); // TODO(pbos): Remove this, perhaps by separating the contents view from the // EyeDropper/WidgetDelegate. set_owned_by_client();
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java index e385338..3c2285b 100644 --- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java +++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
@@ -71,6 +71,7 @@ FeatureConstants.FEED_CARD_MENU_FEATURE, FeatureConstants.IDENTITY_DISC_FEATURE, FeatureConstants.TAB_GROUP_SHARE_NOTICE_FEATURE, + FeatureConstants.TAB_GROUP_SHARE_UPDATE_FEATURE, FeatureConstants.TAB_GROUPS_DRAG_AND_DROP_FEATURE, FeatureConstants.TAB_GROUPS_REMOTE_GROUP, FeatureConstants.TAB_GROUPS_SURFACE, @@ -237,6 +238,12 @@ String TAB_GROUP_SHARE_NOTICE_FEATURE = "IPH_TabGroupShareNotice"; /** + * A simple IPH bubble and highlight on the tab switcher button the first time there's an + * activity dot visible. Teaches the user what the dot means. + */ + String TAB_GROUP_SHARE_UPDATE_FEATURE = "IPH_TabGroupShareUpdate"; + + /** * An IPH feature that shows a notification bubble for updated tab groups. The bubble appears on * the group title when the group is collapsed and on updated tabs when the group is expanded. */
diff --git a/components/feature_engagement/public/feature_configurations.cc b/components/feature_engagement/public/feature_configurations.cc index e10368f..333d267 100644 --- a/components/feature_engagement/public/feature_configurations.cc +++ b/components/feature_engagement/public/feature_configurations.cc
@@ -778,6 +778,19 @@ return config; } + if (kIPHTabGroupShareUpdateFeature.name == feature->name) { + // Allows an IPH for showing the tab group share update explanation the + // first time the activity bubble appears. This will only be shown once. + FeatureConfig config; + config.valid = true; + config.availability = Comparator(ANY, 0); + config.session_rate = Comparator(EQUAL, 0); + config.trigger = + EventConfig("tab_group_share_update_iph_triggered", + Comparator(LESS_THAN, 1), k10YearsInDays, k10YearsInDays); + return config; + } + if (kIPHTabGroupCreationDialogSyncTextFeature.name == feature->name) { // A config that allows the sync text IPH on the TabGroupCreationDialog to // be shown up to 3 times total (10 year max in place of unlimited window).
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc index 5f5c427..e7a49ca 100644 --- a/components/feature_engagement/public/feature_constants.cc +++ b/components/feature_engagement/public/feature_constants.cc
@@ -431,6 +431,9 @@ BASE_FEATURE(kIPHTabGroupShareNotificationBubbleOnStripFeature, "IPH_TabGroupSharedNotificationBubbleOnStrip", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kIPHTabGroupShareUpdateFeature, + "IPH_TabGroupShareUpdate", + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kIPHTabGroupsRemoteGroupFeature, "IPH_TabGroupsRemoteGroup", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h index b5c424d..e284a0c 100644 --- a/components/feature_engagement/public/feature_constants.h +++ b/components/feature_engagement/public/feature_constants.h
@@ -196,6 +196,7 @@ FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHTabGroupShareNoticeFeature); FEATURE_CONSTANTS_DECLARE_FEATURE( kIPHTabGroupShareNotificationBubbleOnStripFeature); +FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHTabGroupShareUpdateFeature); FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHTabGroupsRemoteGroupFeature); FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHTabGroupsSurfaceFeature); FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHTabGroupsSurfaceOnHideFeature);
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc index e808f1e..f23f9f1 100644 --- a/components/feature_engagement/public/feature_list.cc +++ b/components/feature_engagement/public/feature_list.cc
@@ -85,6 +85,7 @@ &kIPHTabGroupsDragAndDropFeature, &kIPHTabGroupShareNoticeFeature, &kIPHTabGroupShareNotificationBubbleOnStripFeature, + &kIPHTabGroupShareUpdateFeature, &kIPHTabGroupsRemoteGroupFeature, &kIPHTabGroupsSurfaceFeature, &kIPHTabGroupsSurfaceOnHideFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h index 5f4b4a6..7be2c9f37 100644 --- a/components/feature_engagement/public/feature_list.h +++ b/components/feature_engagement/public/feature_list.h
@@ -164,6 +164,8 @@ "IPH_TabGroupShareNotice"); DEFINE_VARIATION_PARAM(kIPHTabGroupShareNotificationBubbleOnStripFeature, "IPH_TabGroupSharedNotificationBubbleOnStrip"); +DEFINE_VARIATION_PARAM(kIPHTabGroupShareUpdateFeature, + "IPH_TabGroupShareUpdate"); DEFINE_VARIATION_PARAM(kIPHTabGroupsRemoteGroupFeature, "IPH_TabGroupsRemoteGroup"); DEFINE_VARIATION_PARAM(kIPHTabGroupsSurfaceFeature, "IPH_TabGroupsSurface"); @@ -615,6 +617,7 @@ VARIATION_ENTRY(kIPHShoppingListSaveFlowFeature), VARIATION_ENTRY(kIPHTabGroupCreationDialogSyncTextFeature), VARIATION_ENTRY(kIPHTabGroupShareNoticeFeature), + VARIATION_ENTRY(kIPHTabGroupShareUpdateFeature), VARIATION_ENTRY(kIPHTabGroupsDragAndDropFeature), VARIATION_ENTRY(kIPHTabGroupsRemoteGroupFeature), VARIATION_ENTRY(kIPHTabGroupsSurfaceFeature),
diff --git a/components/omnibox/browser/mock_tab_matcher.h b/components/omnibox/browser/mock_tab_matcher.h index 9d567d7..7bd63a3 100644 --- a/components/omnibox/browser/mock_tab_matcher.h +++ b/components/omnibox/browser/mock_tab_matcher.h
@@ -14,6 +14,11 @@ public: MOCK_CONST_METHOD3(IsTabOpenWithURL, bool(const GURL&, const AutocompleteInput*, bool)); + MOCK_CONST_METHOD4(IsTabOpenWithSameTitleOrSimilarURL, + bool(const std::u16string&, + const GURL& url, + const GURL::Replacements&, + bool)); MockTabMatcher(); ~MockTabMatcher() override; };
diff --git a/components/omnibox/browser/most_visited_sites_provider.cc b/components/omnibox/browser/most_visited_sites_provider.cc index ea0153f..233aa62 100644 --- a/components/omnibox/browser/most_visited_sites_provider.cc +++ b/components/omnibox/browser/most_visited_sites_provider.cc
@@ -129,6 +129,10 @@ } const TabMatcher& tab_matcher = client->GetTabMatcher(); + // Explicitly clear the query since this isn't done in the + // `GURLToStrippedGURL()`. + GURL::Replacements replacements; + replacements.ClearQuery(); TemplateURLService* const url_service = client->GetTemplateURLService(); int relevance = kMostVisitedTilesIndividualHighRelevance; @@ -137,8 +141,8 @@ // - It is an SRP result from DSP // - A tab already exists with the match url if (url_service->IsSearchResultsPageFromDefaultSearchProvider(url.url) || - tab_matcher.IsTabOpenWithURL(url.url, &input, - /*exclude_active_tab =*/false) || + tab_matcher.IsTabOpenWithSameTitleOrSimilarURL( + url.title, url.url, replacements, /*exclude_active_tab=*/false) || IsURLBlocklisted(url.url)) { continue; }
diff --git a/components/omnibox/browser/tab_matcher.cc b/components/omnibox/browser/tab_matcher.cc index 6518c23..3f7de72 100644 --- a/components/omnibox/browser/tab_matcher.cc +++ b/components/omnibox/browser/tab_matcher.cc
@@ -12,6 +12,14 @@ } } +bool TabMatcher::IsTabOpenWithSameTitleOrSimilarURL( + const std::u16string& title, + const GURL& url, + const GURL::Replacements& replacements, + bool exclude_active_tab) const { + return false; +} + std::vector<TabMatcher::TabWrapper> TabMatcher::GetOpenTabs( const AutocompleteInput* input) const { return std::vector<TabMatcher::TabWrapper>();
diff --git a/components/omnibox/browser/tab_matcher.h b/components/omnibox/browser/tab_matcher.h index d4b3e52..7330a75 100644 --- a/components/omnibox/browser/tab_matcher.h +++ b/components/omnibox/browser/tab_matcher.h
@@ -72,6 +72,16 @@ const AutocompleteInput* input, bool exclude_active_tab = true) const = 0; + // For a given tab, check if another tab already exists with the same title or + // if another tab exists with the same stripped URL. Allows affordance for + // replacing any other components of the URL before stripping it. + // ** NOTE: Only implemented in Desktop ** + virtual bool IsTabOpenWithSameTitleOrSimilarURL( + const std::u16string& title, + const GURL& url, + const GURL::Replacements& replacements, + bool exclude_active_tab) const; + // For a given input GURLToTabInfoMap, in-place update the map with the // TabInfo details. // The matching operation is performed in a batch, offering performance
diff --git a/components/optimization_guide/internal b/components/optimization_guide/internal index a96fd8c..6200c82 160000 --- a/components/optimization_guide/internal +++ b/components/optimization_guide/internal
@@ -1 +1 @@ -Subproject commit a96fd8cc0fc8feab1676ce8076f5ec60079e6d7a +Subproject commit 6200c82b11623748653bcac9e5293f347bf072fb
diff --git a/components/passage_embeddings/passage_embeddings_service_controller.cc b/components/passage_embeddings/passage_embeddings_service_controller.cc index 8e792df..c6e052a 100644 --- a/components/passage_embeddings/passage_embeddings_service_controller.cc +++ b/components/passage_embeddings/passage_embeddings_service_controller.cc
@@ -170,11 +170,6 @@ return embedder_.get(); } -void PassageEmbeddingsServiceController::SetEmbedderForTesting( - std::unique_ptr<Embedder> embedder) { - embedder_ = std::move(embedder); -} - void PassageEmbeddingsServiceController::AddObserver( EmbedderMetadataObserver* observer) { if (EmbedderReady()) {
diff --git a/components/passage_embeddings/passage_embeddings_service_controller.h b/components/passage_embeddings/passage_embeddings_service_controller.h index 1c23b24a..719da18 100644 --- a/components/passage_embeddings/passage_embeddings_service_controller.h +++ b/components/passage_embeddings/passage_embeddings_service_controller.h
@@ -37,8 +37,6 @@ // Returns the embedder used to generate embeddings. Embedder* GetEmbedder(); - void SetEmbedderForTesting(std::unique_ptr<Embedder> embedder); - protected: // EmbedderMetadataProvider: void AddObserver(EmbedderMetadataObserver* observer) override; @@ -120,7 +118,7 @@ // This holds the main scheduler that receives requests from multiple clients, // prioritizes all the jobs, and ultimately submits batches of work via // `GetEmbeddings` when the time is right. - std::unique_ptr<Embedder> embedder_; + const std::unique_ptr<Embedder> embedder_; // Used to generate weak pointers to self. base::WeakPtrFactory<PassageEmbeddingsServiceController> weak_ptr_factory_{
diff --git a/components/passage_embeddings/passage_embeddings_service_controller_unittest.cc b/components/passage_embeddings/passage_embeddings_service_controller_unittest.cc index fecf019..92b11c6 100644 --- a/components/passage_embeddings/passage_embeddings_service_controller_unittest.cc +++ b/components/passage_embeddings/passage_embeddings_service_controller_unittest.cc
@@ -25,10 +25,8 @@ namespace { -using ComputePassagesEmbeddingsFuture = - base::test::TestFuture<std::vector<std::string>, - std::vector<Embedding>, - Embedder::TaskId, +using GetEmbeddingsTestFuture = + base::test::TestFuture<std::vector<mojom::PassageEmbeddingsResultPtr>, ComputeEmbeddingsStatus>; class FakePassageEmbedder : public mojom::PassageEmbedder { @@ -49,9 +47,10 @@ if (input == "error") { return std::move(callback).Run({}); } + + // Otherwise just copy the inputs to the passages to provide a signal that + // the PassageEmbedder was executed. results.push_back(mojom::PassageEmbeddingsResult::New()); - results.back()->embeddings = - std::vector<float>(kEmbeddingsModelOutputSize, 1.0); results.back()->passage = input; } std::move(callback).Run(std::move(results)); @@ -110,43 +109,6 @@ std::unique_ptr<FakePassageEmbeddingsService> service_; }; -class FakeEmbedder : public Embedder { - public: - explicit FakeEmbedder( - FakePassageEmbeddingsServiceController::GetEmbeddingsCallback - get_embeddings_callback) - : get_embeddings_callback_(get_embeddings_callback) {} - - // Embedder: - Embedder::TaskId ComputePassagesEmbeddings( - PassagePriority priority, - std::vector<std::string> passages, - ComputePassagesEmbeddingsCallback callback) override { - get_embeddings_callback_.Run( - passages, priority, - base::BindOnce( - [](std::vector<std::string> passages, - ComputePassagesEmbeddingsCallback callback, - std::vector<mojom::PassageEmbeddingsResultPtr> results, - ComputeEmbeddingsStatus status) { - std::vector<Embedding> embeddings; - if (status == ComputeEmbeddingsStatus::kSuccess) { - embeddings = ComputeEmbeddingsForPassages(passages); - } - std::move(callback).Run(passages, embeddings, kInvalidTaskId, - status); - }, - passages, std::move(callback))); - return kInvalidTaskId; - } - - bool TryCancel(TaskId task_id) override { return false; } - - private: - FakePassageEmbeddingsServiceController::GetEmbeddingsCallback - get_embeddings_callback_; -}; - class MetadataObserver : public EmbedderMetadataObserver { public: explicit MetadataObserver( @@ -176,11 +138,6 @@ std::make_unique<FakePassageEmbeddingsServiceController>(); metadata_observer_.emplace(service_controller_.get(), &embedder_metadata_future_); - service_controller_->SetEmbedderForTesting(std::make_unique<FakeEmbedder>( - /*get_embeddings_callback=*/ - base::BindRepeating( - &FakePassageEmbeddingsServiceController::GetEmbeddings, - base::Unretained(service_controller_.get())))); EXPECT_FALSE(embedder_metadata_future()->IsReady()); } @@ -195,7 +152,9 @@ return &embedder_metadata_future_; } - Embedder* embedder() { return service_controller_->GetEmbedder(); } + FakePassageEmbeddingsServiceController* service_controller() { + return service_controller_.get(); + } base::test::TaskEnvironment task_environment_; base::HistogramTester histogram_tester_; @@ -275,34 +234,33 @@ 1); } -TEST_F(PassageEmbeddingsServiceControllerTest, ReceivesEmptyPassages) { +TEST_F(PassageEmbeddingsServiceControllerTest, GetEmbeddingsEmpty) { EXPECT_TRUE(service_controller_->MaybeUpdateModelInfo( *GetBuilderWithValidModelInfo().Build())); - ComputePassagesEmbeddingsFuture future; - embedder()->ComputePassagesEmbeddings(PassagePriority::kPassive, {}, - future.GetCallback()); - auto [passages, embeddings, task_id, status] = future.Get(); + GetEmbeddingsTestFuture future; + service_controller()->GetEmbeddings({}, PassagePriority::kPassive, + future.GetCallback()); + + auto [results, status] = future.Take(); EXPECT_EQ(status, ComputeEmbeddingsStatus::kSuccess); - EXPECT_TRUE(passages.empty()); - EXPECT_TRUE(embeddings.empty()); + EXPECT_TRUE(results.empty()); } -TEST_F(PassageEmbeddingsServiceControllerTest, ReturnsEmbeddings) { +TEST_F(PassageEmbeddingsServiceControllerTest, GetEmbeddingsNonEmpty) { EXPECT_TRUE(service_controller_->MaybeUpdateModelInfo( *GetBuilderWithValidModelInfo().Build())); - ComputePassagesEmbeddingsFuture future; - embedder()->ComputePassagesEmbeddings(PassagePriority::kPassive, - {"foo", "bar"}, future.GetCallback()); - auto [passages, embeddings, task_id, status] = future.Get(); + GetEmbeddingsTestFuture future; + service_controller()->GetEmbeddings({"foo", "bar"}, PassagePriority::kPassive, + future.GetCallback()); + auto [results, status] = future.Take(); EXPECT_EQ(status, ComputeEmbeddingsStatus::kSuccess); - EXPECT_EQ(passages[0], "foo"); - EXPECT_EQ(passages[1], "bar"); - EXPECT_EQ(embeddings[0].Dimensions(), kEmbeddingsModelOutputSize); - EXPECT_EQ(embeddings[1].Dimensions(), kEmbeddingsModelOutputSize); + ASSERT_EQ(results.size(), 2u); + EXPECT_EQ(results[0]->passage, "foo"); + EXPECT_EQ(results[1]->passage, "bar"); } TEST_F(PassageEmbeddingsServiceControllerTest, @@ -313,69 +271,59 @@ EXPECT_FALSE(service_controller_->MaybeUpdateModelInfo(*builder.Build())); - ComputePassagesEmbeddingsFuture future; - embedder()->ComputePassagesEmbeddings(PassagePriority::kPassive, - {"foo", "bar"}, future.GetCallback()); - auto [passages, embeddings, task_id, status] = future.Get(); + GetEmbeddingsTestFuture future; + service_controller()->GetEmbeddings({"foo", "bar"}, PassagePriority::kPassive, + future.GetCallback()); + auto [results, status] = future.Take(); EXPECT_EQ(status, ComputeEmbeddingsStatus::kModelUnavailable); - EXPECT_EQ(passages[0], "foo"); - EXPECT_EQ(passages[1], "bar"); - EXPECT_TRUE(embeddings.empty()); + EXPECT_EQ(results.size(), 0u); } TEST_F(PassageEmbeddingsServiceControllerTest, ReturnsExecutionFailure) { EXPECT_TRUE(service_controller_->MaybeUpdateModelInfo( *GetBuilderWithValidModelInfo().Build())); - ComputePassagesEmbeddingsFuture future; - embedder()->ComputePassagesEmbeddings(PassagePriority::kPassive, - {"error", "baz"}, future.GetCallback()); - auto [passages, embeddings, task_id, status] = future.Get(); + GetEmbeddingsTestFuture future; + service_controller()->GetEmbeddings( + {"error", "bar"}, PassagePriority::kPassive, future.GetCallback()); + auto [results, status] = future.Take(); EXPECT_EQ(status, ComputeEmbeddingsStatus::kExecutionFailure); - EXPECT_EQ(passages[0], "error"); - EXPECT_EQ(passages[1], "baz"); - EXPECT_TRUE(embeddings.empty()); + EXPECT_EQ(results.size(), 0u); } TEST_F(PassageEmbeddingsServiceControllerTest, EmbedderRunningStatus) { EXPECT_TRUE(service_controller_->MaybeUpdateModelInfo( *GetBuilderWithValidModelInfo().Build())); + + const auto get_embeddings = [this] { + GetEmbeddingsTestFuture future; + service_controller()->GetEmbeddings( + {"foo", "bar"}, PassagePriority::kPassive, future.GetCallback()); + return future; + }; + { - ComputePassagesEmbeddingsFuture future1; - embedder()->ComputePassagesEmbeddings( - PassagePriority::kPassive, {"foo", "bar"}, future1.GetCallback()); - // Embedder is running. + GetEmbeddingsTestFuture future1 = get_embeddings(); EXPECT_TRUE(service_controller_->EmbedderRunning()); - ComputePassagesEmbeddingsFuture future2; - embedder()->ComputePassagesEmbeddings( - PassagePriority::kPassive, {"baz", "qux"}, future2.GetCallback()); - // Embedder is running. + GetEmbeddingsTestFuture future2 = get_embeddings(); EXPECT_TRUE(service_controller_->EmbedderRunning()); - auto status1 = future1.Get<3>(); - EXPECT_EQ(status1, ComputeEmbeddingsStatus::kSuccess); + EXPECT_EQ(future1.Get<1>(), ComputeEmbeddingsStatus::kSuccess); // Embedder is still running. EXPECT_TRUE(service_controller_->EmbedderRunning()); - auto status2 = future2.Get<3>(); - EXPECT_EQ(status2, ComputeEmbeddingsStatus::kSuccess); + EXPECT_EQ(future2.Get<1>(), ComputeEmbeddingsStatus::kSuccess); // Embedder is NOT running. EXPECT_FALSE(service_controller_->EmbedderRunning()); } { - ComputePassagesEmbeddingsFuture future1; - embedder()->ComputePassagesEmbeddings( - PassagePriority::kPassive, {"foo", "bar"}, future1.GetCallback()); - // Embedder is running. + GetEmbeddingsTestFuture future1 = get_embeddings(); EXPECT_TRUE(service_controller_->EmbedderRunning()); - ComputePassagesEmbeddingsFuture future2; - embedder()->ComputePassagesEmbeddings( - PassagePriority::kPassive, {"baz", "qux"}, future2.GetCallback()); - // Embedder is running. + GetEmbeddingsTestFuture future2 = get_embeddings(); EXPECT_TRUE(service_controller_->EmbedderRunning()); // Callbacks are invoked synchronously on embedder remote disconnect. @@ -383,45 +331,30 @@ // Embedder is NOT running. EXPECT_FALSE(service_controller_->EmbedderRunning()); - auto status1 = future1.Get<3>(); - EXPECT_EQ(status1, ComputeEmbeddingsStatus::kExecutionFailure); - auto status2 = future2.Get<3>(); - EXPECT_EQ(status2, ComputeEmbeddingsStatus::kExecutionFailure); + EXPECT_EQ(future1.Get<1>(), ComputeEmbeddingsStatus::kExecutionFailure); + EXPECT_EQ(future2.Get<1>(), ComputeEmbeddingsStatus::kExecutionFailure); } { // Calling `ComputePassagesEmbeddings()` again launches the service. - ComputePassagesEmbeddingsFuture future1; - embedder()->ComputePassagesEmbeddings( - PassagePriority::kPassive, {"foo", "bar"}, future1.GetCallback()); - // Embedder is running. + GetEmbeddingsTestFuture future1 = get_embeddings(); EXPECT_TRUE(service_controller_->EmbedderRunning()); - ComputePassagesEmbeddingsFuture future2; - embedder()->ComputePassagesEmbeddings( - PassagePriority::kPassive, {"baz", "qux"}, future2.GetCallback()); - // Embedder is running. + GetEmbeddingsTestFuture future2 = get_embeddings(); EXPECT_TRUE(service_controller_->EmbedderRunning()); - auto status1 = future1.Get<3>(); - EXPECT_EQ(status1, ComputeEmbeddingsStatus::kSuccess); + EXPECT_EQ(future1.Get<1>(), ComputeEmbeddingsStatus::kSuccess); // Embedder is still running. EXPECT_TRUE(service_controller_->EmbedderRunning()); - auto status2 = future2.Get<3>(); - EXPECT_EQ(status2, ComputeEmbeddingsStatus::kSuccess); + EXPECT_EQ(future2.Get<1>(), ComputeEmbeddingsStatus::kSuccess); // Embedder is NOT running. EXPECT_FALSE(service_controller_->EmbedderRunning()); } { - ComputePassagesEmbeddingsFuture future1; - embedder()->ComputePassagesEmbeddings( - PassagePriority::kPassive, {"foo", "bar"}, future1.GetCallback()); - // Embedder is running. + GetEmbeddingsTestFuture future1 = get_embeddings(); EXPECT_TRUE(service_controller_->EmbedderRunning()); - ComputePassagesEmbeddingsFuture future2; - embedder()->ComputePassagesEmbeddings( - PassagePriority::kPassive, {"baz", "qux"}, future2.GetCallback()); + GetEmbeddingsTestFuture future2 = get_embeddings(); // Embedder is still running. EXPECT_TRUE(service_controller_->EmbedderRunning()); @@ -430,10 +363,8 @@ // Embedder is NOT running. EXPECT_FALSE(service_controller_->EmbedderRunning()); - auto status1 = future1.Get<3>(); - EXPECT_EQ(status1, ComputeEmbeddingsStatus::kExecutionFailure); - auto status2 = future2.Get<3>(); - EXPECT_EQ(status2, ComputeEmbeddingsStatus::kExecutionFailure); + EXPECT_EQ(future1.Get<1>(), ComputeEmbeddingsStatus::kExecutionFailure); + EXPECT_EQ(future2.Get<1>(), ComputeEmbeddingsStatus::kExecutionFailure); } }
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/AndroidPaymentAppFinder.java b/components/payments/content/android/java/src/org/chromium/components/payments/AndroidPaymentAppFinder.java index ea52ace..26cbc03 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/AndroidPaymentAppFinder.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/AndroidPaymentAppFinder.java
@@ -754,6 +754,14 @@ return; } + String readyToPayServiceName = mIsReadyToPayServices.get(packageName); + debugLogPaymentAppServicePresence( + packageName, ACTION_IS_READY_TO_PAY, readyToPayServiceName); + + String updatePaymentDetailsServiceName = mUpdatePaymentDetailsServices.get(packageName); + debugLogPaymentAppServicePresence( + packageName, ACTION_UPDATE_PAYMENT_DETAILS, updatePaymentDetailsServiceName); + // Dedupe corresponding payment handler which is registered with the default // payment method name as the scope and the scope is used as the app Id. String webAppIdCanDeduped = @@ -769,8 +777,8 @@ mFactoryDelegate.getDialogController(), packageName, resolveInfo.activityInfo.name, - mIsReadyToPayServices.get(packageName), - mUpdatePaymentDetailsServices.get(packageName), + readyToPayServiceName, + updatePaymentDetailsServiceName, label.toString(), mPackageManagerDelegate.getAppIcon(resolveInfo), mIsOffTheRecord, @@ -789,6 +797,24 @@ app.addMethodName(methodName); } + private static void debugLogPaymentAppServicePresence( + String packageName, String actionIntentFilterName, @Nullable String serviceName) { + if (TextUtils.isEmpty(serviceName)) { + Log.e( + TAG, + "Payment app \"%s\": No \"%s\" service.", + packageName, + actionIntentFilterName); + } else { + Log.i( + TAG, + "Payment app \"%s\": \"%s\" service in \"%s\".", + packageName, + actionIntentFilterName, + serviceName); + } + } + private SupportedDelegations getAppsSupportedDelegations(ActivityInfo activityInfo) { String[] supportedDelegationNames = getStringArrayMetaData(activityInfo, META_DATA_NAME_OF_SUPPORTED_DELEGATIONS);
diff --git a/components/performance_manager/scenarios/browser_performance_scenarios.cc b/components/performance_manager/scenarios/browser_performance_scenarios.cc index a964f6cd..fdcb059 100644 --- a/components/performance_manager/scenarios/browser_performance_scenarios.cc +++ b/components/performance_manager/scenarios/browser_performance_scenarios.cc
@@ -67,15 +67,15 @@ // No trace event. return; case LoadingScenario::kBackgroundPageLoading: - TRACE_EVENT_BEGIN("loading", "BackgroundPageLoading", + TRACE_EVENT_BEGIN("performance_scenarios", "BackgroundPageLoading", *state_ptr->loading_tracing_track()); return; case LoadingScenario::kVisiblePageLoading: - TRACE_EVENT_BEGIN("loading", "VisiblePageLoading", + TRACE_EVENT_BEGIN("performance_scenarios", "VisiblePageLoading", *state_ptr->loading_tracing_track()); return; case LoadingScenario::kFocusedPageLoading: - TRACE_EVENT_BEGIN("loading", "FocusedPageLoading", + TRACE_EVENT_BEGIN("performance_scenarios", "FocusedPageLoading", *state_ptr->loading_tracing_track()); return; } @@ -93,7 +93,8 @@ case LoadingScenario::kBackgroundPageLoading: case LoadingScenario::kVisiblePageLoading: case LoadingScenario::kFocusedPageLoading: - TRACE_EVENT_END("loading", *state_ptr->loading_tracing_track()); + TRACE_EVENT_END("performance_scenarios", + *state_ptr->loading_tracing_track()); return; } NOTREACHED(); @@ -120,7 +121,8 @@ // No trace event. return; case InputScenario::kTyping: - TRACE_EVENT_BEGIN("input", "Typing", *state_ptr->input_tracing_track()); + TRACE_EVENT_BEGIN("performance_scenarios", "Typing", + *state_ptr->input_tracing_track()); return; } NOTREACHED(); @@ -135,7 +137,8 @@ // No trace event. return; case InputScenario::kTyping: - TRACE_EVENT_END("input", *state_ptr->input_tracing_track()); + TRACE_EVENT_END("performance_scenarios", + *state_ptr->input_tracing_track()); return; } NOTREACHED();
diff --git a/components/performance_manager/scenarios/performance_scenario_data.cc b/components/performance_manager/scenarios/performance_scenario_data.cc index b9f2867b..429bc26 100644 --- a/components/performance_manager/scenarios/performance_scenario_data.cc +++ b/components/performance_manager/scenarios/performance_scenario_data.cc
@@ -24,8 +24,7 @@ if (process_node) { return CreateProcessTracingTrack(process_node, name, track_id); } else { - return perfetto::NamedTrack(name, track_id, - perfetto::ProcessTrack::Current()); + return perfetto::NamedTrack(name, track_id, perfetto::Track::Global(0)); } }
diff --git a/components/performance_manager/scenarios/performance_scenario_data.h b/components/performance_manager/scenarios/performance_scenario_data.h index 6fe67a2..df9e723 100644 --- a/components/performance_manager/scenarios/performance_scenario_data.h +++ b/components/performance_manager/scenarios/performance_scenario_data.h
@@ -72,8 +72,8 @@ // Creates tracing tracks under the ProcessTrack for `process_node`. The // tracks will log trace events when updating scenarios in the shared memory - // region. If `process_node` is null, tracks for the global scenario state - // will be created under the current ProcessTrack. + // region. If `process_node` is null, creates tracks for the global scenario + // state. void EnsureTracingTracks(const ProcessNode* process_node = nullptr); private:
diff --git a/components/persistent_cache/BUILD.gn b/components/persistent_cache/BUILD.gn index f3f5409..78b2f15 100644 --- a/components/persistent_cache/BUILD.gn +++ b/components/persistent_cache/BUILD.gn
@@ -12,6 +12,7 @@ "backend_params_manager.h", "entry.cc", "entry.h", + "entry_metadata.h", "sqlite/sqlite_entry_impl.cc", "sqlite/sqlite_entry_impl.h", ]
diff --git a/components/persistent_cache/backend.h b/components/persistent_cache/backend.h index 43e2597..2a61a4c1 100644 --- a/components/persistent_cache/backend.h +++ b/components/persistent_cache/backend.h
@@ -8,6 +8,7 @@ #include "base/component_export.h" #include "base/containers/span.h" #include "components/persistent_cache/backend_params.h" +#include "components/persistent_cache/entry_metadata.h" namespace persistent_cache { @@ -37,6 +38,8 @@ virtual std::unique_ptr<Entry> Find(std::string_view key) = 0; // Used to add an entry containing `content` and associated with `key`. + // Metadata associated with the entry can be provided in `metadata` or the + // object can be default initialized to signify no metadata. // // This call will never report failure and `content` is expected (but not // guaranteed) to be resident upon return. @@ -46,7 +49,8 @@ // // Thread-safe. virtual void Insert(std::string_view key, - base::span<const uint8_t> content) = 0; + base::span<const uint8_t> content, + EntryMetadata metadata) = 0; protected: Backend();
diff --git a/components/persistent_cache/entry.h b/components/persistent_cache/entry.h index b2a5bed..b17e9a9 100644 --- a/components/persistent_cache/entry.h +++ b/components/persistent_cache/entry.h
@@ -9,6 +9,7 @@ #include "base/component_export.h" #include "base/containers/span.h" +#include "components/persistent_cache/entry_metadata.h" namespace persistent_cache { @@ -36,6 +37,10 @@ // Use to get the size of the entry's value in bytes. virtual size_t GetContentSize() const; + // Use to retrieve metadata tied to the entry. Partially or completely + // populated by default values if the metadata was not supplied on insert. + virtual EntryMetadata GetMetadata() const = 0; + protected: // Ownership and liveness is managed by the backend and thus Entry should not // be created outside of their scope.
diff --git a/components/persistent_cache/entry_metadata.h b/components/persistent_cache/entry_metadata.h new file mode 100644 index 0000000..d1e0e51 --- /dev/null +++ b/components/persistent_cache/entry_metadata.h
@@ -0,0 +1,28 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PERSISTENT_CACHE_ENTRY_METADATA_H_ +#define COMPONENTS_PERSISTENT_CACHE_ENTRY_METADATA_H_ + +#include "base/component_export.h" +#include "base/time/time.h" + +namespace persistent_cache { + +// Metadata that can be optionally attached to an `Entry`. Leaving +// some or all members to their default value is always valid. EntryMetadata is +// not a replacement or an enhancement to either keys or values. It represents +// information that aids the internal operations of the cache such as +// eviction. In some cases the data might be of some use to code outside of +// persistent_cache. As such it is externally accessible through `Entry`. +// Attempts to use metadata as additional storage for arbitrary values may +// result in performance degradation or unexpected behavior. +struct COMPONENT_EXPORT(PERSISTENT_CACHE) EntryMetadata { + // Opaque token indicating whether the cached entry is still valid + int64_t input_signature = 0; +}; + +} // namespace persistent_cache + +#endif // COMPONENTS_PERSISTENT_CACHE_ENTRY_METADATA_H_
diff --git a/components/persistent_cache/mock/mock_backend_impl.h b/components/persistent_cache/mock/mock_backend_impl.h index 607ef72f..57dad6e 100644 --- a/components/persistent_cache/mock/mock_backend_impl.h +++ b/components/persistent_cache/mock/mock_backend_impl.h
@@ -9,6 +9,7 @@ #include "components/persistent_cache/backend.h" #include "components/persistent_cache/entry.h" +#include "components/persistent_cache/entry_metadata.h" #include "testing/gmock/include/gmock/gmock.h" namespace persistent_cache { @@ -28,7 +29,7 @@ MOCK_METHOD(std::unique_ptr<Entry>, Find, (std::string_view), (override)); MOCK_METHOD(void, Insert, - (std::string_view, base::span<const uint8_t>), + (std::string_view, base::span<const uint8_t>, EntryMetadata), (override)); };
diff --git a/components/persistent_cache/mock/mock_entry_impl.h b/components/persistent_cache/mock/mock_entry_impl.h index a030f94..e70962e 100644 --- a/components/persistent_cache/mock/mock_entry_impl.h +++ b/components/persistent_cache/mock/mock_entry_impl.h
@@ -18,6 +18,7 @@ // `Entry` overrides MOCK_METHOD(base::span<const uint8_t>, GetContentSpan, (), (const override)); + MOCK_METHOD(EntryMetadata, GetMetadata, (), (const override)); protected: explicit MockEntryImpl();
diff --git a/components/persistent_cache/persistent_cache.cc b/components/persistent_cache/persistent_cache.cc index 9737aa6e..a146d7d 100644 --- a/components/persistent_cache/persistent_cache.cc +++ b/components/persistent_cache/persistent_cache.cc
@@ -48,12 +48,13 @@ } void PersistentCache::Insert(std::string_view key, - base::span<const uint8_t> content) { + base::span<const uint8_t> content, + EntryMetadata metadata) { if (!backend_) { return; } - backend_->Insert(key, content); + backend_->Insert(key, content, metadata); } Backend* PersistentCache::GetBackendForTesting() {
diff --git a/components/persistent_cache/persistent_cache.h b/components/persistent_cache/persistent_cache.h index cc09b3d..cdb6da0 100644 --- a/components/persistent_cache/persistent_cache.h +++ b/components/persistent_cache/persistent_cache.h
@@ -13,6 +13,7 @@ #include "base/containers/span.h" #include "base/files/file.h" #include "components/persistent_cache/backend_params.h" +#include "components/persistent_cache/entry_metadata.h" namespace persistent_cache { @@ -79,7 +80,9 @@ // Used to add an entry containing `content` and associated with `key`. // // Thread-safe. - void Insert(std::string_view key, base::span<const uint8_t> content); + void Insert(std::string_view key, + base::span<const uint8_t> content, + EntryMetadata metadata = EntryMetadata{}); Backend* GetBackendForTesting();
diff --git a/components/persistent_cache/persistent_cache_unittest.cc b/components/persistent_cache/persistent_cache_unittest.cc index 9e27df1f..94ab02f 100644 --- a/components/persistent_cache/persistent_cache_unittest.cc +++ b/components/persistent_cache/persistent_cache_unittest.cc
@@ -66,13 +66,13 @@ TEST_F(PersistentCacheMockedBackendTest, CacheInsertCallsBackendInsert) { CreateCache(true); - EXPECT_CALL(*GetBackend(), Insert(kKey, _)); + EXPECT_CALL(*GetBackend(), Insert(kKey, _, _)); cache_->Insert(kKey, base::byte_span_from_cstring("1")); } TEST_F(PersistentCacheMockedBackendTest, FailedBackendInitializationMeansNoFurtherCalls) { - EXPECT_CALL(*backend_, Insert(kKey, _)).Times(0); + EXPECT_CALL(*backend_, Insert(kKey, _, _)).Times(0); EXPECT_CALL(*backend_, Find(kKey)).Times(0); CreateCache(false); @@ -160,6 +160,30 @@ base::byte_span_from_cstring("2")); } +TEST_P(PersistentCacheTest, MetadataIsRetrievable) { + EntryMetadata metadata{.input_signature = + base::Time::Now().InMillisecondsSinceUnixEpoch()}; + + auto cache = OpenCache(); + cache->Insert(kKey, base::byte_span_from_cstring("1"), metadata); + + EXPECT_EQ(cache->Find(kKey)->GetMetadata().input_signature, + metadata.input_signature); +} + +TEST_P(PersistentCacheTest, OverwritingChangesMetadata) { + EntryMetadata metadata{.input_signature = + base::Time::Now().InMillisecondsSinceUnixEpoch()}; + + auto cache = OpenCache(); + cache->Insert(kKey, base::byte_span_from_cstring("1"), metadata); + EXPECT_EQ(cache->Find(kKey)->GetMetadata().input_signature, + metadata.input_signature); + + cache->Insert(kKey, base::byte_span_from_cstring("1"), EntryMetadata{}); + EXPECT_EQ(cache->Find(kKey)->GetMetadata().input_signature, 0); +} + TEST_P(PersistentCacheTest, MultipleEphemeralCachesAreIndependent) { for (int i = 0; i < 3; ++i) { auto cache = OpenCache();
diff --git a/components/persistent_cache/sqlite/sqlite_backend_impl.cc b/components/persistent_cache/sqlite/sqlite_backend_impl.cc index 1cd6fb9..9e8e764 100644 --- a/components/persistent_cache/sqlite/sqlite_backend_impl.cc +++ b/components/persistent_cache/sqlite/sqlite_backend_impl.cc
@@ -72,7 +72,7 @@ if (!db_.Execute( "CREATE TABLE IF NOT EXISTS entries(key TEXT PRIMARY KEY UNIQUE NOT " - "NULL, content BLOB NOT NULL)")) { + "NULL, content BLOB NOT NULL, input_signature INTEGER)")) { TRACE_EVENT_INSTANT1("persistent_cache", "create_failed", TRACE_EVENT_SCOPE_THREAD, "error_code", db_.GetErrorCode()); @@ -89,7 +89,8 @@ TRACE_EVENT0("persistent_cache", "Find"); sql::Statement stm = sql::Statement(db_.GetCachedStatement( - SQL_FROM_HERE, "SELECT content FROM entries WHERE key = ?")); + SQL_FROM_HERE, + "SELECT content, input_signature FROM entries WHERE key = ?")); stm.BindString(0, key); DCHECK(stm.is_valid()); @@ -104,20 +105,26 @@ return nullptr; } - return SqliteEntryImpl::MakeUnique(Passkey(), stm.ColumnString(0)); + EntryMetadata metadata; + metadata.input_signature = stm.ColumnInt64(1); + + return SqliteEntryImpl::MakeUnique(Passkey(), stm.ColumnString(0), metadata); } void SqliteBackendImpl::Insert(std::string_view key, - base::span<const uint8_t> content) { + base::span<const uint8_t> content, + EntryMetadata metadata) { CHECK(initialized_); CHECK_GT(key.length(), 0ull); TRACE_EVENT0("persistent_cache", "insert"); sql::Statement stm(db_.GetCachedStatement( - SQL_FROM_HERE, "REPLACE INTO entries (key, content) VALUES (?, ?)")); + SQL_FROM_HERE, + "REPLACE INTO entries (key, content, input_signature) VALUES (?, ?, ?)")); stm.BindString(0, key); stm.BindString(1, base::as_string_view(content)); + stm.BindInt64(2, metadata.input_signature); DCHECK(stm.is_valid()); if (!stm.Run()) {
diff --git a/components/persistent_cache/sqlite/sqlite_backend_impl.h b/components/persistent_cache/sqlite/sqlite_backend_impl.h index a1be2c2..e004e7a 100644 --- a/components/persistent_cache/sqlite/sqlite_backend_impl.h +++ b/components/persistent_cache/sqlite/sqlite_backend_impl.h
@@ -34,7 +34,9 @@ // `Backend`: [[nodiscard]] bool Initialize() override; [[nodiscard]] std::unique_ptr<Entry> Find(std::string_view key) override; - void Insert(std::string_view key, base::span<const uint8_t> content) override; + void Insert(std::string_view key, + base::span<const uint8_t> content, + EntryMetadata metadata) override; private: static SqliteVfsFileSet GetVfsFileSetFromParams(BackendParams backend_params);
diff --git a/components/persistent_cache/sqlite/sqlite_entry_impl.cc b/components/persistent_cache/sqlite/sqlite_entry_impl.cc index c016798..9fa84fe3 100644 --- a/components/persistent_cache/sqlite/sqlite_entry_impl.cc +++ b/components/persistent_cache/sqlite/sqlite_entry_impl.cc
@@ -12,18 +12,19 @@ namespace persistent_cache { -SqliteEntryImpl::SqliteEntryImpl(std::string&& content) - : content_(std::move(content)) {} +SqliteEntryImpl::SqliteEntryImpl(std::string&& content, EntryMetadata metadata) + : content_(std::move(content)), metadata_(metadata) {} SqliteEntryImpl::~SqliteEntryImpl() = default; // static std::unique_ptr<SqliteEntryImpl> SqliteEntryImpl::MakeUnique( base::PassKey<SqliteBackendImpl> passkey, - std::string&& content) { + std::string&& content, + EntryMetadata metadata) { // Avoid `make_unique` as it requires friending it which in turn lets any // class create `unique_ptr`s of this class. auto ptr = base::WrapUnique<SqliteEntryImpl>( - new SqliteEntryImpl(std::move(content))); + new SqliteEntryImpl(std::move(content), metadata)); return ptr; } @@ -31,4 +32,8 @@ return base::as_byte_span(content_); } +EntryMetadata SqliteEntryImpl::GetMetadata() const { + return metadata_; +} + } // namespace persistent_cache
diff --git a/components/persistent_cache/sqlite/sqlite_entry_impl.h b/components/persistent_cache/sqlite/sqlite_entry_impl.h index e22e75d3..d071497 100644 --- a/components/persistent_cache/sqlite/sqlite_entry_impl.h +++ b/components/persistent_cache/sqlite/sqlite_entry_impl.h
@@ -22,6 +22,7 @@ // Entry: [[nodiscard]] base::span<const uint8_t> GetContentSpan() const override; + [[nodiscard]] EntryMetadata GetMetadata() const override; // Use to create `unique_ptr`s of this class from `SqliteBackendImpl`. // Protected with `PassKey` so that only `SqliteBackendImpl` can create @@ -29,7 +30,8 @@ // implementation to the backend. static std::unique_ptr<SqliteEntryImpl> MakeUnique( base::PassKey<SqliteBackendImpl> passkey, - std::string&& content); + std::string&& content, + EntryMetadata metadata); private: FRIEND_TEST_ALL_PREFIXES(SqliteEntryTest, ConstructionTakesOwnershipOfValue); @@ -43,9 +45,10 @@ // unwanted copies as much as possible. There is precedent for copies coming // from disk caches leading to OOMs and this class tries to avoid the // situation. - explicit SqliteEntryImpl(std::string&& content); + explicit SqliteEntryImpl(std::string&& content, EntryMetadata metadata); std::string content_; + EntryMetadata metadata_; }; } // namespace persistent_cache
diff --git a/components/persistent_cache/sqlite/sqlite_entry_unittest.cc b/components/persistent_cache/sqlite/sqlite_entry_unittest.cc index 0f4a662..1547ef4 100644 --- a/components/persistent_cache/sqlite/sqlite_entry_unittest.cc +++ b/components/persistent_cache/sqlite/sqlite_entry_unittest.cc
@@ -19,7 +19,7 @@ TEST(SqliteEntryTest, ConstructionTakesOwnershipOfValue) { std::string copy = kContent; - SqliteEntryImpl sql_entry(std::move(copy)); + SqliteEntryImpl sql_entry(std::move(copy), EntryMetadata{}); // Move took place. EXPECT_TRUE(copy.empty()); EXPECT_EQ(sql_entry.GetContentSpan(), base::span_from_cstring(kContent)); @@ -27,7 +27,7 @@ } TEST(SqliteEntryTest, ConstructionFromEmptyValueLeadsToEmptyEntry) { - SqliteEntryImpl sql_entry(std::string("")); + SqliteEntryImpl sql_entry(std::string(""), EntryMetadata{}); EXPECT_TRUE(sql_entry.GetContentSpan().empty()); EXPECT_EQ(sql_entry.GetContentSize(), 0ull); }
diff --git a/components/segmentation_platform/embedder/default_model/android_home_module_ranker.cc b/components/segmentation_platform/embedder/default_model/android_home_module_ranker.cc index 73e4e9f9..6a5299f 100644 --- a/components/segmentation_platform/embedder/default_model/android_home_module_ranker.cc +++ b/components/segmentation_platform/embedder/default_model/android_home_module_ranker.cc
@@ -22,7 +22,7 @@ // Default parameters for AndroidHomeModuleRanker model. constexpr SegmentId kSegmentId = SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_ANDROID_HOME_MODULE_RANKER; -constexpr int64_t kModelVersion = 8; +constexpr int64_t kModelVersion = 9; // Store 28 buckets of input data (28 days). constexpr int64_t kSignalStorageLength = 28; // Wait until we have 0 days of data. @@ -30,12 +30,11 @@ // Refresh the result every time. constexpr int64_t kResultTTLMinutes = 5; -constexpr std::array<const char*, 4> kAndroidHomeModuleLabels = { - kPriceChange, kSingleTab, kTabResumptionForAndroidHome, kSafetyHub}; +constexpr std::array<const char*, 3> kAndroidHomeModuleLabels = { + kPriceChange, kSingleTab, kSafetyHub}; -constexpr std::array<const char*, 4> kAndroidHomeModuleInputContextKeys = { - kPriceChangeFreshness, kSingleTabFreshness, - kTabResumptionForAndroidHomeFreshness, kSafetyHubFreshness}; +constexpr std::array<const char*, 3> kAndroidHomeModuleInputContextKeys = { + kPriceChangeFreshness, kSingleTabFreshness, kSafetyHubFreshness}; // InputFeatures. @@ -45,13 +44,10 @@ constexpr std::array<int32_t, 1> kEnumValueForPriceChange{/*PriceChange=*/1}; -constexpr std::array<int32_t, 1> kEnumValueForTabResumption{ - /*TabResumption=*/2}; - constexpr std::array<int32_t, 1> kEnumValueForSafetyHub{/*SafetyHub=*/3}; // Set UMA metrics to use as input. -constexpr std::array<MetadataWriter::UMAFeature, 8> kUMAFeatures = { +constexpr std::array<MetadataWriter::UMAFeature, 6> kUMAFeatures = { // Single Tab Module // 0 : click MetadataWriter::UMAFeature::FromEnumHistogram( @@ -78,27 +74,14 @@ 28, kEnumValueForPriceChange.data(), kEnumValueForPriceChange.size()), - // Tab Resumption Module - // 4 : click - MetadataWriter::UMAFeature::FromEnumHistogram( - "MagicStack.Clank.NewTabPage.Module.Click", - 28, - kEnumValueForTabResumption.data(), - kEnumValueForTabResumption.size()), - // 5 : impression - MetadataWriter::UMAFeature::FromEnumHistogram( - "MagicStack.Clank.NewTabPage.Module.TopImpressionV2", - 28, - kEnumValueForTabResumption.data(), - kEnumValueForTabResumption.size()), // Safety Hub Module - // 6 : click + // 4 : click MetadataWriter::UMAFeature::FromEnumHistogram( "MagicStack.Clank.NewTabPage.Module.Click", 28, kEnumValueForSafetyHub.data(), kEnumValueForSafetyHub.size()), - // 7 : impression + // 5 : impression MetadataWriter::UMAFeature::FromEnumHistogram( "MagicStack.Clank.NewTabPage.Module.TopImpressionV2", 28, @@ -161,8 +144,6 @@ // Add freshness for all modules as custom input. writer.AddFromInputContext("single_tab_input", kSingleTabFreshness); writer.AddFromInputContext("price_change_input", kPriceChangeFreshness); - writer.AddFromInputContext("tab_resumption_input", - kTabResumptionForAndroidHomeFreshness); writer.AddFromInputContext("safety_hub_input", kSafetyHubFreshness); } @@ -189,7 +170,7 @@ float single_tab_engagement = inputs[0]; float single_tab_impression = inputs[1]; float single_tab_freshness = is_android_home_module_ranker_v2_enabled - ? TransformFreshness(inputs[8], 1.0) + ? TransformFreshness(inputs[6], 1.0) : 0.0; float single_tab_score = single_tab_weights[0] * single_tab_engagement + single_tab_weights[1] * single_tab_impression + @@ -200,30 +181,18 @@ float price_change_engagement = inputs[2]; float price_change_impression = inputs[3]; float price_change_freshness = is_android_home_module_ranker_v2_enabled - ? TransformFreshness(inputs[9], 1.0) + ? TransformFreshness(inputs[7], 1.0) : 0.0; float price_change_score = price_change_weights[0] * price_change_engagement + price_change_weights[1] * price_change_impression + price_change_weights[2] * price_change_freshness; - // Tab Resumption score calculation. - float tab_resumption_weights[3] = {1.5, -0.5, 1.0}; - float tab_resumption_engagement = inputs[4]; - float tab_resumption_impression = inputs[5]; - float tab_resumption_freshness = is_android_home_module_ranker_v2_enabled - ? TransformFreshness(inputs[10], 1.0) - : 0.0; - float tab_resumption_score = - tab_resumption_weights[0] * tab_resumption_engagement + - tab_resumption_weights[1] * tab_resumption_impression + - tab_resumption_weights[2] * tab_resumption_freshness; - // Safety Hub score calculation. float safety_hub_weights[3] = {2.5, -2, 2.5}; - float safety_hub_engagement = inputs[6]; - float safety_hub_impression = inputs[7]; + float safety_hub_engagement = inputs[4]; + float safety_hub_impression = inputs[5]; float safety_hub_freshness = is_android_home_module_ranker_v2_enabled - ? TransformFreshness(inputs[11], 1.0) + ? TransformFreshness(inputs[8], 1.0) : 0.0; float safety_hub_score = safety_hub_weights[0] * safety_hub_engagement + safety_hub_weights[1] * safety_hub_impression + @@ -233,8 +202,7 @@ // Default ranking response[0] = price_change_score; // Price Change response[1] = single_tab_score; // Single tab - response[2] = tab_resumption_score; // Tab Resumption - response[3] = safety_hub_score; // Safety Hub + response[2] = safety_hub_score; // Safety Hub base::SequencedTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), response));
diff --git a/components/segmentation_platform/embedder/default_model/android_home_module_ranker_unittest.cc b/components/segmentation_platform/embedder/default_model/android_home_module_ranker_unittest.cc index cea131ca..712b495 100644 --- a/components/segmentation_platform/embedder/default_model/android_home_module_ranker_unittest.cc +++ b/components/segmentation_platform/embedder/default_model/android_home_module_ranker_unittest.cc
@@ -21,7 +21,7 @@ DefaultModelTestBase::SetUp(); bool isAndroidHomeModuleRankerV2Enabled = base::FeatureList::IsEnabled( features::kSegmentationPlatformAndroidHomeModuleRankerV2); - input_size = isAndroidHomeModuleRankerV2Enabled ? 12 : 8; + input_size = isAndroidHomeModuleRankerV2Enabled ? 9 : 6; } void TearDown() override { DefaultModelTestBase::TearDown(); } @@ -40,8 +40,7 @@ EXPECT_FALSE(ExecuteWithInput(/*inputs=*/{})); std::vector<float> input(input_size, 0); - ExpectClassifierResults(input, {kPriceChange, kSingleTab, - kTabResumptionForAndroidHome, kSafetyHub}); + ExpectClassifierResults(input, {kPriceChange, kSingleTab, kSafetyHub}); } TEST_F(AndroidHomeModuleRankerTest, @@ -54,9 +53,7 @@ input[0] = 1; input[2] = 1; input[4] = 1; - input[6] = 1; - ExpectClassifierResults(input, {kSafetyHub, kPriceChange, kSingleTab, - kTabResumptionForAndroidHome}); + ExpectClassifierResults(input, {kSafetyHub, kPriceChange, kSingleTab}); } TEST_F(AndroidHomeModuleRankerTest, @@ -69,9 +66,7 @@ input[1] = 1; input[3] = 1; input[5] = 1; - input[7] = 1; - ExpectClassifierResults(input, {kSingleTab, kTabResumptionForAndroidHome, - kPriceChange, kSafetyHub}); + ExpectClassifierResults(input, {kSingleTab, kPriceChange, kSafetyHub}); } } // namespace segmentation_platform
diff --git a/components/segmentation_platform/embedder/home_modules/rank_fetcher_helper.cc b/components/segmentation_platform/embedder/home_modules/rank_fetcher_helper.cc index 37de950..d038b5f1 100644 --- a/components/segmentation_platform/embedder/home_modules/rank_fetcher_helper.cc +++ b/components/segmentation_platform/embedder/home_modules/rank_fetcher_helper.cc
@@ -21,6 +21,8 @@ std::vector<std::string> GetFixedModuleList() { #if BUILDFLAG(IS_IOS) return {}; +#elif BUILDFLAG(IS_ANDROID) + return {kPriceChange, kSingleTab, kSafetyHub, kAuxiliarySearch}; #else return { kPriceChange, kSingleTab, kSafetyHub, kAuxiliarySearch, kTabResumption
diff --git a/components/segmentation_platform/embedder/home_modules/rank_fetcher_helper_unittest.cc b/components/segmentation_platform/embedder/home_modules/rank_fetcher_helper_unittest.cc index 08d49f6..95d7106 100644 --- a/components/segmentation_platform/embedder/home_modules/rank_fetcher_helper_unittest.cc +++ b/components/segmentation_platform/embedder/home_modules/rank_fetcher_helper_unittest.cc
@@ -140,7 +140,7 @@ ClassificationResult result = FetchRank(rank_fetcher_helper); #if BUILDFLAG(IS_ANDROID) - EXPECT_THAT(result.ordered_labels, SizeIs(5)); // Fixed modules size. + EXPECT_THAT(result.ordered_labels, SizeIs(4)); // Fixed modules size. #endif }
diff --git a/components/segmentation_platform/public/constants.h b/components/segmentation_platform/public/constants.h index 01b3986..59c2c87b 100644 --- a/components/segmentation_platform/public/constants.h +++ b/components/segmentation_platform/public/constants.h
@@ -204,14 +204,12 @@ // Labels for Android Home modules for ranking. const char kSingleTab[] = "SingleTab"; const char kPriceChange[] = "PriceChange"; -const char kTabResumptionForAndroidHome[] = "TabResumption"; const char kSafetyHub[] = "SafetyHub"; const char kAuxiliarySearch[] = "AuxiliarySearch"; // Input Context keys for freshness for Android Home modules. const char kSingleTabFreshness[] = "single_tab_freshness"; const char kPriceChangeFreshness[] = "price_change_freshness"; -const char kTabResumptionForAndroidHomeFreshness[] = "tab_resumption_freshness"; const char kSafetyHubFreshness[] = "safety_hub_freshness"; const char kAuxiliarySearchFreshness[] = "auxiliary_search_freshness";
diff --git a/components/update_client/ping_manager_unittest.cc b/components/update_client/ping_manager_unittest.cc index 2532c45..6b900c8 100644 --- a/components/update_client/ping_manager_unittest.cc +++ b/components/update_client/ping_manager_unittest.cc
@@ -154,7 +154,7 @@ EXPECT_TRUE(request.contains("@os")); EXPECT_EQ("fake_prodid", CHECK_DEREF(request.FindString("@updater"))); - EXPECT_EQ("crx3,download,puff,run,xz,zucchini", + EXPECT_EQ("crx3,download,puff,run,xz,zucc", CHECK_DEREF(request.FindString("acceptformat"))); EXPECT_TRUE(request.contains("arch")); EXPECT_EQ("cr", CHECK_DEREF(request.FindString("dedup")));
diff --git a/components/update_client/pipeline.cc b/components/update_client/pipeline.cc index 4d300a47..499857d5 100644 --- a/components/update_client/pipeline.cc +++ b/components/update_client/pipeline.cc
@@ -262,7 +262,7 @@ cache_check, base::BindOnce(&XzOperation, config->GetUnzipperFactory()->Create(), event_adder))); - } else if (operation.type == "zucchini") { + } else if (operation.type == "zucc") { ops.push(SkipIfCached( cache_check, base::BindOnce(&ZucchiniOperation, crx_cache, config->GetPatcherFactory()->Create(),
diff --git a/components/update_client/protocol_serializer_json.cc b/components/update_client/protocol_serializer_json.cc index 6fac4e32..d6408fb 100644 --- a/components/update_client/protocol_serializer_json.cc +++ b/components/update_client/protocol_serializer_json.cc
@@ -24,7 +24,7 @@ request_node.Set("protocol", request.protocol_version); request_node.Set("ismachine", request.is_machine); request_node.Set("dedup", "cr"); - request_node.Set("acceptformat", "crx3,download,puff,run,xz,zucchini"); + request_node.Set("acceptformat", "crx3,download,puff,run,xz,zucc"); if (!request.additional_attributes.empty()) { for (const auto& [name, value] : request.additional_attributes) { request_node.Set(name, value);
diff --git a/components/update_client/protocol_serializer_json_unittest.cc b/components/update_client/protocol_serializer_json_unittest.cc index 3c868ec..0a9c885e 100644 --- a/components/update_client/protocol_serializer_json_unittest.cc +++ b/components/update_client/protocol_serializer_json_unittest.cc
@@ -62,7 +62,7 @@ std::move(apps))); constexpr char regex[] = R"({"request":{"@os":"\w+","@updater":"prod_id",)" - R"("acceptformat":"crx3,download,puff,run,xz,zucchini",)" + R"("acceptformat":"crx3,download,puff,run,xz,zucc",)" R"("apps":\[{"ap":"ap1","appid":"id1","attr1":"1","attr2":"2",)" R"("brand":"BRND","cohort":"c1","cohorthint":"ch1","cohortname":"cn1",)" R"("data":\[{"index":"foobar_install_data_index","name":"install"}],)" @@ -147,7 +147,7 @@ {})); constexpr char regex[] = R"({"request":{"@os":"\w+","@updater":"prod_id",)" - R"("acceptformat":"crx3,download,puff,run,xz,zucchini",)" + R"("acceptformat":"crx3,download,puff,run,xz,zucc",)" R"("arch":"\w+","dedup":"cr",)" R"("dlpref":"cacheable","domainjoined":true,"extra":"params",)" R"("hw":{"avx":(true|false),)"
diff --git a/components/update_client/update_checker_unittest.cc b/components/update_client/update_checker_unittest.cc index b26b17f..324d57e 100644 --- a/components/update_client/update_checker_unittest.cc +++ b/components/update_client/update_checker_unittest.cc
@@ -284,7 +284,7 @@ ASSERT_TRUE(request->FindString("@updater")); EXPECT_EQ("fake_prodid", *request->FindString("@updater")); ASSERT_TRUE(request->FindString("acceptformat")); - EXPECT_EQ("crx3,download,puff,run,xz,zucchini", + EXPECT_EQ("crx3,download,puff,run,xz,zucc", *request->FindString("acceptformat")); EXPECT_TRUE(request->contains("arch")); ASSERT_TRUE(request->FindString("dedup"));
diff --git a/components/visited_url_ranking/internal/url_grouping/group_suggestions_manager.cc b/components/visited_url_ranking/internal/url_grouping/group_suggestions_manager.cc index 6a7247b..1fa0ad7 100644 --- a/components/visited_url_ranking/internal/url_grouping/group_suggestions_manager.cc +++ b/components/visited_url_ranking/internal/url_grouping/group_suggestions_manager.cc
@@ -192,7 +192,14 @@ void GroupSuggestionsManager::OnSuggestionResult( GroupSuggestion shown_suggestion, GroupSuggestionsDelegate::UserResponseMetadata user_response) { + if (user_response.user_response == + GroupSuggestionsDelegate::UserResponse::kNotShown || + user_response.user_response == + GroupSuggestionsDelegate::UserResponse::kUnknown) { + return; + } // TODO(ssid): Track all suggestions instead of assuming UI shows the first. + DCHECK_EQ(user_response.suggestion_id, shown_suggestion.suggestion_id); suggestion_tracker_.AddSuggestion(shown_suggestion, user_response.user_response); }
diff --git a/components/visited_url_ranking/internal/url_grouping/group_suggestions_service_impl_unittest.cc b/components/visited_url_ranking/internal/url_grouping/group_suggestions_service_impl_unittest.cc index 30e27cc..cf47e4c 100644 --- a/components/visited_url_ranking/internal/url_grouping/group_suggestions_service_impl_unittest.cc +++ b/components/visited_url_ranking/internal/url_grouping/group_suggestions_service_impl_unittest.cc
@@ -100,7 +100,12 @@ return candidates; } - GroupSuggestionsDelegate::SuggestionResponseCallback TriggerSuggestions( + struct SuggestionTriggerData { + GroupSuggestionsDelegate::SuggestionResponseCallback callback; + GroupSuggestion suggestion; + }; + + SuggestionTriggerData TriggerSuggestions( std::vector<URLVisitAggregate> candidates) { base::RunLoop wait_for_compute; suggestions_service_->group_suggestions_manager_for_testing() @@ -111,16 +116,24 @@ .WillByDefault(MoveArg<1>(&fetch_callback)); suggestions_service_->GetTabEventTracker()->DidAddTab(1, 0); - GroupSuggestionsDelegate::SuggestionResponseCallback response_callback; + + SuggestionTriggerData data; ON_CALL(*mock_delegate_, ShowSuggestion(_, _)) - .WillByDefault(MoveArg<1>(&response_callback)); + .WillByDefault( + Invoke([&data](const GroupSuggestions& group_suggestions, + GroupSuggestionsDelegate::SuggestionResponseCallback + response_callback) { + data.callback = std::move(response_callback); + data.suggestion = + group_suggestions.suggestions.front().DeepCopy(); + })); std::move(fetch_callback) .Run(ResultStatus::kSuccess, URLVisitsMetadata{}, std::move(candidates)); wait_for_compute.Run(); suggestions_service_->group_suggestions_manager_for_testing() ->set_suggestion_computed_callback_for_testing({}); - return response_callback; + return data; } protected: @@ -157,9 +170,11 @@ GroupSuggestionsService::Scope()); EXPECT_CALL(*mock_delegate_, ShowSuggestion(_, _)); - auto response_callback1 = TriggerSuggestions(GetSampleCandidates()); - std::move(response_callback1) - .Run(GroupSuggestionsDelegate::UserResponseMetadata()); + auto trigger_data = TriggerSuggestions(GetSampleCandidates()); + GroupSuggestionsDelegate::UserResponseMetadata response; + response.user_response = GroupSuggestionsDelegate::UserResponse::kRejected; + response.suggestion_id = trigger_data.suggestion.suggestion_id; + std::move(trigger_data.callback).Run(response); // Triggering suggestions again should not show since its duplicate:
diff --git a/components/visited_url_ranking/internal/url_grouping/group_suggestions_tracker.cc b/components/visited_url_ranking/internal/url_grouping/group_suggestions_tracker.cc index ea401f4..ab51eeff 100644 --- a/components/visited_url_ranking/internal/url_grouping/group_suggestions_tracker.cc +++ b/components/visited_url_ranking/internal/url_grouping/group_suggestions_tracker.cc
@@ -21,7 +21,7 @@ constexpr auto kReasonToMaxOverlappingTabs = base::MakeFixedFlatMap<GroupSuggestion::SuggestionReason, float>({ {GroupSuggestion::SuggestionReason::kRecentlyOpened, 0.55}, - {GroupSuggestion::SuggestionReason::kSwitchedBetween, 0.9}, + {GroupSuggestion::SuggestionReason::kSwitchedBetween, 0.60}, {GroupSuggestion::SuggestionReason::kSimilarSource, 0.55}, });
diff --git a/components/viz/client/client_resource_provider.cc b/components/viz/client/client_resource_provider.cc index 68168a39..00750c0 100644 --- a/components/viz/client/client_resource_provider.cc +++ b/components/viz/client/client_resource_provider.cc
@@ -515,11 +515,22 @@ // If this is false, then the resource has not been removed via // RemoveImportedResource(), and all resources should be removed before // we resort to marking resources as lost during shutdown. - DCHECK(imported.marked_for_deletion) - << "id: " << pair.first << " from:\n" - << imported.stack_trace.ToString() << "==="; - DCHECK(imported.exported_count) << "id: " << pair.first << " from:\n" - << imported.stack_trace.ToString() << "==="; + // Note that |use_imported_resource_id_| is true for TreesInViz. In that + // case, Viz side ClientResourceProvider's imported resources are only + // marked for deletion when signaled by the Renderer. + // ::ShutdownAndReleaseAllResources() can be called when LayerTreeHostImpl + // owning the ClientResourceProvider is being destroyed and Viz + // might not have yet received the marked_for_deletion signal from the + // Renderer, Hence this check is invalid for those scenarios and hence for + // Viz side ClientResourceProvider. + if (!use_imported_resource_id_) { + DCHECK(imported.marked_for_deletion) + << "id: " << pair.first << " from:\n" + << imported.stack_trace.ToString() << "==="; + DCHECK(imported.exported_count) + << "id: " << pair.first << " from:\n" + << imported.stack_trace.ToString() << "==="; + } #endif imported.returned_lost = true;
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index 2abb9b9..4b21d9c4 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -295,6 +295,7 @@ # Note that dependency on //gpu/ipc/client is for GpuMemoryBufferImpl. This # dependency should not be in public_deps. "//components/version_info:version_info", + "//components/viz/client", "//components/viz/common", "//gpu/command_buffer/client", "//gpu/config",
diff --git a/components/viz/service/display_embedder/software_output_device_mac.cc b/components/viz/service/display_embedder/software_output_device_mac.cc index 446229f..80b4d99c 100644 --- a/components/viz/service/display_embedder/software_output_device_mac.cc +++ b/components/viz/service/display_embedder/software_output_device_mac.cc
@@ -78,10 +78,10 @@ { TRACE_EVENT0("browser", "IOSurfaceLock for software copy"); - IOReturn io_result = IOSurfaceLock( + kern_return_t io_result = IOSurfaceLock( previous_io_surface, kIOSurfaceLockReadOnly | kIOSurfaceLockAvoidSync, nullptr); - if (io_result) { + if (io_result != KERN_SUCCESS) { DLOG(ERROR) << "Failed to lock previous IOSurface " << io_result; return; } @@ -101,11 +101,12 @@ { TRACE_EVENT0("browser", "IOSurfaceUnlock"); - IOReturn io_result = IOSurfaceUnlock( + kern_return_t io_result = IOSurfaceUnlock( previous_io_surface, kIOSurfaceLockReadOnly | kIOSurfaceLockAvoidSync, nullptr); - if (io_result) + if (io_result != KERN_SUCCESS) { DLOG(ERROR) << "Failed to unlock previous IOSurface " << io_result; + } } } @@ -156,9 +157,10 @@ // |current_paint_canvas_|. { TRACE_EVENT0("browser", "IOSurfaceLock for software paint"); - IOReturn io_result = IOSurfaceLock(current_paint_buffer_->io_surface.get(), - kIOSurfaceLockAvoidSync, nullptr); - if (io_result) { + kern_return_t io_result = + IOSurfaceLock(current_paint_buffer_->io_surface.get(), + kIOSurfaceLockAvoidSync, nullptr); + if (io_result != KERN_SUCCESS) { DLOG(ERROR) << "Failed to lock IOSurface " << io_result; current_paint_buffer_ = nullptr; return nullptr; @@ -186,11 +188,12 @@ { TRACE_EVENT0("browser", "IOSurfaceUnlock"); - IOReturn io_result = + kern_return_t io_result = IOSurfaceUnlock(current_paint_buffer_->io_surface.get(), kIOSurfaceLockAvoidSync, nullptr); - if (io_result) + if (io_result != KERN_SUCCESS) { DLOG(ERROR) << "Failed to unlock IOSurface " << io_result; + } } current_paint_canvas_.reset();
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc index d9ee653..02d7d6b 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -477,6 +477,11 @@ return; } + DoReturnResources(std::move(resources)); +} + +void CompositorFrameSinkSupport::DoReturnResources( + std::vector<ReturnedResource> resources) { // When features::OnBeginFrameAcks is disabled we attempt to return resources // in DidReceiveCompositorFrameAck. However if there are no pending frames // then we don't expect that signal soon. In which case we return the
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/components/viz/service/frame_sinks/compositor_frame_sink_support.h index 2e651f0..ed1ed6b 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.h +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -281,6 +281,7 @@ friend class CompositorFrameSinkSupportTestBase; friend class DisplayTest; friend class FrameSinkManagerTest; + friend class LayerContextImpl; friend class OnBeginFrameAcksCompositorFrameSinkSupportTest; friend class SurfaceAggregatorWithResourcesTest; @@ -361,6 +362,8 @@ void ForAllReservedResourceDelegates( base::FunctionRef<void(ReservedResourceDelegate&)> func); + void DoReturnResources(std::vector<ReturnedResource> resources); + const raw_ptr<mojom::CompositorFrameSinkClient> client_; const raw_ptr<FrameSinkManagerImpl> frame_sink_manager_;
diff --git a/components/viz/service/layers/DEPS b/components/viz/service/layers/DEPS index 27a6d9aea..a8e544f 100644 --- a/components/viz/service/layers/DEPS +++ b/components/viz/service/layers/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+components/viz/service/frame_sinks", "+mojo/public", + "+components/viz/client/client_resource_provider.h", ]
diff --git a/components/viz/service/layers/layer_context_impl.cc b/components/viz/service/layers/layer_context_impl.cc index 959ec709..f4a9b84 100644 --- a/components/viz/service/layers/layer_context_impl.cc +++ b/components/viz/service/layers/layer_context_impl.cc
@@ -31,6 +31,7 @@ #include "cc/trees/layer_tree_settings.h" #include "cc/trees/property_tree.h" #include "cc/trees/task_runner_provider.h" +#include "components/viz/client/client_resource_provider.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" @@ -943,6 +944,7 @@ LayerContextImpl::~LayerContextImpl() { host_impl_->ReleaseLayerTreeFrameSink(); + DoReturnResources(std::move(resources_to_return_)); } void LayerContextImpl::BeginFrame(const BeginFrameArgs& args) { @@ -968,8 +970,14 @@ void LayerContextImpl::ReturnResources( std::vector<ReturnedResource> resources) { - // TODO(crbug.com/40902503): Release resources at some point. - NOTIMPLEMENTED(); + host_impl_->resource_provider()->ReceiveReturnsFromParent( + std::move(resources)); + DoReturnResources(std::move(resources_to_return_)); +} + +void LayerContextImpl::DoReturnResources( + std::vector<ReturnedResource> resources) { + compositor_sink_->DoReturnResources(std::move(resources)); } void LayerContextImpl::DidLoseLayerTreeFrameSinkOnImplThread() { @@ -1110,11 +1118,6 @@ frame.metadata.send_frame_token_to_embedder = true; - frame.resource_list.insert(frame.resource_list.end(), - next_frame_resources_.begin(), - next_frame_resources_.end()); - next_frame_resources_.clear(); - std::optional<HitTestRegionList> hit_test_region_list = host_impl_->BuildHitTestData(); @@ -1142,6 +1145,27 @@ resources.end()); } +void LayerContextImpl::ImportResource(TransferableResource resource) { + auto release_callback = base::BindOnce( + [](LayerContextImpl* impl, ResourceId id, + const gpu::SyncToken& sync_token, bool is_lost) { + impl->resources_to_return_.emplace_back( + id, sync_token, + /*release_fence=*/gfx::GpuFenceHandle(), + /*count=*/1, is_lost); + }, + base::Unretained(this), resource.id); + + host_impl_->resource_provider()->ImportResource( + resource, /*impl_release_callback=*/std::move(release_callback), + /*main_thread_release_callback=*/base::NullCallback(), + /*evicted_callback=*/base::NullCallback()); +} + +void LayerContextImpl::DiscardResource(ResourceId resource) { + host_impl_->resource_provider()->RemoveImportedResource(resource); +} + void LayerContextImpl::SetVisible(bool visible) { host_impl_->SetVisible(visible); }
diff --git a/components/viz/service/layers/layer_context_impl.h b/components/viz/service/layers/layer_context_impl.h index cb9a64e..045e8d0 100644 --- a/components/viz/service/layers/layer_context_impl.h +++ b/components/viz/service/layers/layer_context_impl.h
@@ -49,6 +49,8 @@ void ReturnResources(std::vector<ReturnedResource> resources); + void DoReturnResources(std::vector<ReturnedResource> resources); + private: // cc::LayerTreeHostImplClient: void DidLoseLayerTreeFrameSinkOnImplThread() override; @@ -115,6 +117,8 @@ // cc::TileDisplayLayerImpl::Client: void DidAppendQuadsWithResources( const std::vector<TransferableResource>& resources) override; + void ImportResource(TransferableResource resource) override; + void DiscardResource(ResourceId resource) override; // mojom::LayerContext: void SetVisible(bool visible) override; @@ -135,6 +139,7 @@ const std::unique_ptr<cc::LayerTreeHostImpl> host_impl_; std::vector<TransferableResource> next_frame_resources_; + std::vector<ReturnedResource> resources_to_return_; raw_ptr<cc::LayerTreeFrameSinkClient> frame_sink_client_ = nullptr; };
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/ArClassProvider.java b/components/webxr/android/java/src/org/chromium/components/webxr/ArClassProvider.java index fe2283c..b73721d6 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/ArClassProvider.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/ArClassProvider.java
@@ -4,9 +4,8 @@ package org.chromium.components.webxr; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.WebContents; /** @@ -15,10 +14,11 @@ * Any method that you add or update the signature of here needs to also be updated in the * corresponding /stubs/ version of this class. */ +@NullMarked /*package*/ class ArClassProvider { - /*package*/ static @Nullable XrImmersiveOverlay.Delegate getOverlayDelegate( - @NonNull ArCompositorDelegate compositorDelegate, - @NonNull final WebContents webContents, + /*package*/ static XrImmersiveOverlay.@Nullable Delegate getOverlayDelegate( + ArCompositorDelegate compositorDelegate, + final WebContents webContents, boolean useOverlay, boolean canRenderDomContent) { return new ArOverlayDelegate(
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/ArCompositorDelegate.java b/components/webxr/android/java/src/org/chromium/components/webxr/ArCompositorDelegate.java index cb9bc596..eaeff1b 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/ArCompositorDelegate.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/ArCompositorDelegate.java
@@ -7,12 +7,13 @@ import android.view.MotionEvent; import android.view.ViewGroup; -import androidx.annotation.NonNull; +import org.chromium.build.annotations.NullMarked; /** - * Interface used by ArOverlayDelegate to communicate with the underlying - * compositor. Used to implement WebXR's DOM Overlay mode correctly. + * Interface used by ArOverlayDelegate to communicate with the underlying compositor. Used to + * implement WebXR's DOM Overlay mode correctly. */ +@NullMarked public interface ArCompositorDelegate { /** Enables/disables immersive AR mode in the compositor. */ void setOverlayImmersiveArMode(boolean enabled, boolean domSurfaceNeedsConfiguring); @@ -25,13 +26,11 @@ void dispatchTouchEvent(MotionEvent ev); /** - * Returns the ViewGroup that the AR SurfaceView should be parented to. Note - * that it should *not* be under the same ViewGroup as |dispatchTouchEvent| - * sends its events to, as an infinite loop can occur. It should however, - * be positioned under the elements that would cause infobars/prompts to - * appear, but over any default (e.g. DOM) content. + * Returns the ViewGroup that the AR SurfaceView should be parented to. Note that it should + * *not* be under the same ViewGroup as |dispatchTouchEvent| sends its events to, as an infinite + * loop can occur. It should however, be positioned under the elements that would cause + * infobars/prompts to appear, but over any default (e.g. DOM) content. */ - @NonNull ViewGroup getArSurfaceParent(); /**
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/ArCompositorDelegateProvider.java b/components/webxr/android/java/src/org/chromium/components/webxr/ArCompositorDelegateProvider.java index 49efd23..97726bef 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/ArCompositorDelegateProvider.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/ArCompositorDelegateProvider.java
@@ -4,12 +4,14 @@ package org.chromium.components.webxr; +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.WebContents; /** - * Interface used to create instances of ArCompositorDelegates, needed by - * ArOverlayDelegate to work correctly for WebXR's DOM Overlay. + * Interface used to create instances of ArCompositorDelegates, needed by ArOverlayDelegate to work + * correctly for WebXR's DOM Overlay. */ +@NullMarked public interface ArCompositorDelegateProvider { ArCompositorDelegate create(WebContents webContents); }
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreInstallUtils.java b/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreInstallUtils.java index 3099819..b1f12d2 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreInstallUtils.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreInstallUtils.java
@@ -15,19 +15,22 @@ 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.content_public.browser.WebContents; import org.chromium.ui.base.ImmutableWeakReference; import org.chromium.ui.base.WindowAndroid; /** Installs AR DFM and ArCore runtimes. */ @JNINamespace("webxr") +@NullMarked public class ArCoreInstallUtils { /** - * Helper class to store a reference to the ArCoreInstallUtils instance and activity - * that requested an install of ArCore, and await that activity being resumed. + * Helper class to store a reference to the ArCoreInstallUtils instance and activity that + * requested an install of ArCore, and await that activity being resumed. */ private static class InstallRequest implements ActivityLifecycleCallbacks { - private ArCoreInstallUtils mInstallInstance; + private @Nullable ArCoreInstallUtils mInstallInstance; private ImmutableWeakReference<Activity> mWeakActivity; private ImmutableWeakReference<Application> mWeakApplication; @@ -63,7 +66,8 @@ // Unfortunately, ActivityLifecycleCallbacks force us to implement all of the methods, but // we only really care about onActivityResumed for our purposes. @Override - public void onActivityCreated(final Activity activity, Bundle savedInstanceState) {} + public void onActivityCreated( + final Activity activity, @Nullable Bundle savedInstanceState) {} @Override public void onActivityDestroyed(Activity activity) {} @@ -87,11 +91,11 @@ // This tracks the relevant information of the instance that requested installation of ARCore. // Should be non-null only if there is a pending request to install ARCore. - private static InstallRequest sInstallRequest; + private static @Nullable InstallRequest sInstallRequest; // Cached ArCoreShim instance - valid only after AR module was installed and // getArCoreShimInstance() was called. - private static ArCoreShim sArCoreInstance; + private static @Nullable ArCoreShim sArCoreInstance; private static ArCoreShim getArCoreShimInstance() { if (sArCoreInstance != null) return sArCoreInstance; @@ -148,7 +152,7 @@ return availability != ArCoreAvailability.SUPPORTED_INSTALLED; } - private Activity getActivity(final WebContents webContents) { + private @Nullable Activity getActivity(final WebContents webContents) { if (webContents == null) return null; WindowAndroid window = webContents.getTopLevelNativeWindow(); if (window == null) return null;
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreShim.java b/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreShim.java index b847b828..319fd06 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreShim.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreShim.java
@@ -9,20 +9,23 @@ import androidx.annotation.IntDef; +import org.chromium.build.annotations.NullMarked; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Interface used to wrap around ArCore SDK Java interface. * - * For detailed documentation of the below methods, please see: + * <p>For detailed documentation of the below methods, please see: * https://developers.google.com/ar/reference/java/arcore/reference/com/google/ar/core/ArCoreApk */ +@NullMarked public interface ArCoreShim { /** * Equivalent of ArCoreApk.ArInstallStatus enum. * - * For detailed description, please see: + * <p>For detailed description, please see: * https://developers.google.com/ar/reference/java/arcore/reference/com/google/ar/core/ArCoreApk.InstallStatus */ @IntDef({InstallStatus.INSTALLED, InstallStatus.INSTALL_REQUESTED})
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreShimImpl.java b/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreShimImpl.java index 2c52ca34..5e298b4 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreShimImpl.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreShimImpl.java
@@ -10,9 +10,11 @@ import com.google.ar.core.ArCoreApk; import org.chromium.base.StrictModeContext; +import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.UsedByReflection; @UsedByReflection("ArCoreInstallUtils.java") +@NullMarked class ArCoreShimImpl implements ArCoreShim { @UsedByReflection("ArCoreInstallUtils.java") public ArCoreShimImpl() {}
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/ArOverlayDelegate.java b/components/webxr/android/java/src/org/chromium/components/webxr/ArOverlayDelegate.java index 847a585..13f5fd3 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/ArOverlayDelegate.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/ArOverlayDelegate.java
@@ -4,6 +4,8 @@ package org.chromium.components.webxr; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.res.Configuration; import android.graphics.PixelFormat; import android.view.MotionEvent; @@ -11,13 +13,13 @@ import android.view.View; import android.view.ViewGroup; -import androidx.annotation.NonNull; - import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsAccessibility; /** Provides a fullscreen overlay for immersive AR mode. */ +@NullMarked public class ArOverlayDelegate implements XrImmersiveOverlay.Delegate { private static final String TAG = "ArOverlayDelegate"; private static final boolean DEBUG_LOGS = false; @@ -29,7 +31,7 @@ private WebContents mWebContents; public ArOverlayDelegate( - @NonNull ArCompositorDelegate compositorDelegate, + ArCompositorDelegate compositorDelegate, final WebContents webContents, boolean useOverlay, boolean canRenderDomContent) { @@ -67,7 +69,10 @@ surfaceView.setZOrderMediaOverlay(!mDomSurfaceNeedsConfiguring); if (!mUseOverlay) { - WebContentsAccessibility.fromWebContents(mWebContents).setObscuredByAnotherView(true); + WebContentsAccessibility webContentsAccessibility = + WebContentsAccessibility.fromWebContents(mWebContents); + assumeNonNull(webContentsAccessibility); + webContentsAccessibility.setObscuredByAnotherView(true); } } @@ -95,7 +100,10 @@ ViewGroup parent = (ViewGroup) surfaceView.getParent(); if (!mUseOverlay) { - WebContentsAccessibility.fromWebContents(mWebContents).setObscuredByAnotherView(false); + WebContentsAccessibility webContentsAccessibility = + WebContentsAccessibility.fromWebContents(mWebContents); + assumeNonNull(webContentsAccessibility); + webContentsAccessibility.setObscuredByAnotherView(false); } if (parent != null) {
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/CardboardClassProvider.java b/components/webxr/android/java/src/org/chromium/components/webxr/CardboardClassProvider.java index b717c2b..84135a4 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/CardboardClassProvider.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/CardboardClassProvider.java
@@ -6,8 +6,8 @@ import android.app.Activity; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * This "real" version of CardboardClassProvider is only built if |enable_cardboard| is true, which @@ -15,9 +15,10 @@ * Any method that you add or update the signature of here needs to also be updated in the * corresponding /stubs/ version of this class. */ +@NullMarked /*package*/ class CardboardClassProvider { - /*package*/ static @Nullable XrImmersiveOverlay.Delegate getOverlayDelegate( - VrCompositorDelegate compositorDelegate, @NonNull Activity activity) { + /*package*/ static XrImmersiveOverlay.@Nullable Delegate getOverlayDelegate( + VrCompositorDelegate compositorDelegate, Activity activity) { return new CardboardOverlayDelegate(compositorDelegate, activity); } }
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/CardboardOverlayDelegate.java b/components/webxr/android/java/src/org/chromium/components/webxr/CardboardOverlayDelegate.java index 08a4e7aa..be419d5 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/CardboardOverlayDelegate.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/CardboardOverlayDelegate.java
@@ -4,6 +4,8 @@ package org.chromium.components.webxr; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.app.Activity; import android.content.res.Configuration; import android.view.Gravity; @@ -18,12 +20,13 @@ import android.widget.ImageButton; import android.widget.PopupMenu; -import androidx.annotation.NonNull; - import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.LoadUrlParams; /** Provides a fullscreen overlay for immersive Cardboard (VR) mode. */ +@NullMarked public class CardboardOverlayDelegate implements XrImmersiveOverlay.Delegate, PopupMenu.OnMenuItemClickListener { private static final String TAG = "CardboardOverlay"; @@ -40,10 +43,9 @@ private Activity mActivity; private VrCompositorDelegate mCompositorDelegate; - private View mCardboardView; + private @Nullable View mCardboardView; - public CardboardOverlayDelegate( - VrCompositorDelegate compositorDelegate, @NonNull Activity activity) { + public CardboardOverlayDelegate(VrCompositorDelegate compositorDelegate, Activity activity) { if (DEBUG_LOGS) { Log.i(TAG, "constructor"); } @@ -145,6 +147,7 @@ int flags = mActivity.getWindow().getDecorView().getSystemUiVisibility(); mActivity.getWindow().getDecorView().setSystemUiVisibility(flags | VR_SYSTEM_UI_FLAGS); + assumeNonNull(mCardboardView); FrameLayout surface_view_holder = (FrameLayout) mCardboardView.findViewById(R.id.surface_view_holder); surface_view_holder.addView(surfaceView);
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/CardboardUtils.java b/components/webxr/android/java/src/org/chromium/components/webxr/CardboardUtils.java index 65ec94f4..a2b6144 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/CardboardUtils.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/CardboardUtils.java
@@ -7,12 +7,15 @@ import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import org.chromium.build.annotations.NullMarked; + /** Helper class for interacting with Cardboard SDK from Java code. */ @JNINamespace("webxr") +@NullMarked public class CardboardUtils { /** - * Forces to always return Cardboard Viewer v1 device parameters to prevent - * any disk read or write and the QR code scanner activity to be launched. + * Forces to always return Cardboard Viewer v1 device parameters to prevent any disk read or + * write and the QR code scanner activity to be launched. */ public static void useCardboardV1DeviceParamsForTesting() { CardboardUtilsJni.get().nativeUseCardboardV1DeviceParamsForTesting();
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/VrCompositorDelegate.java b/components/webxr/android/java/src/org/chromium/components/webxr/VrCompositorDelegate.java index 724ba4b..5802969 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/VrCompositorDelegate.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/VrCompositorDelegate.java
@@ -4,12 +4,14 @@ package org.chromium.components.webxr; +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.LoadUrlParams; /** - * Interface used by ArOverlayDelegate to communicate with the underlying - * compositor. Used to implement WebXR's DOM Overlay mode correctly. + * Interface used by ArOverlayDelegate to communicate with the underlying compositor. Used to + * implement WebXR's DOM Overlay mode correctly. */ +@NullMarked public interface VrCompositorDelegate { /** Enables/disables immersive VR mode in the compositor. */ void setOverlayImmersiveVrMode(boolean enabled);
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/VrCompositorDelegateProvider.java b/components/webxr/android/java/src/org/chromium/components/webxr/VrCompositorDelegateProvider.java index 787ccab..2b46b7f 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/VrCompositorDelegateProvider.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/VrCompositorDelegateProvider.java
@@ -4,12 +4,14 @@ package org.chromium.components.webxr; +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.WebContents; /** - * Interface used to create instances of VrCompositorDelegates, needed to talk - * to the compositor to ensure that the Surface renders correctly. + * Interface used to create instances of VrCompositorDelegates, needed to talk to the compositor to + * ensure that the Surface renders correctly. */ +@NullMarked public interface VrCompositorDelegateProvider { VrCompositorDelegate create(WebContents webContents); }
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/XrActivityListener.java b/components/webxr/android/java/src/org/chromium/components/webxr/XrActivityListener.java index 6a245ce7..3f41d6b 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/XrActivityListener.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/XrActivityListener.java
@@ -15,6 +15,8 @@ import org.chromium.base.Log; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.ImmutableWeakReference; import org.chromium.ui.base.WindowAndroid; @@ -25,6 +27,7 @@ * and the ResumeListener in ArCoreInstallUtils. */ @JNINamespace("webxr") +@NullMarked public class XrActivityListener implements ActivityLifecycleCallbacks { private static final String TAG = "XrActivityListener"; private static final boolean DEBUG_LOGS = false; @@ -81,7 +84,7 @@ // Unfortunately, ActivityLifecycleCallbacks force us to implement all of the methods, but // we only really care about onActivityResumed for our purposes. @Override - public void onActivityCreated(final Activity activity, Bundle savedInstanceState) {} + public void onActivityCreated(final Activity activity, @Nullable Bundle savedInstanceState) {} @Override public void onActivityDestroyed(Activity activity) {}
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/XrDelegateImpl.java b/components/webxr/android/java/src/org/chromium/components/webxr/XrDelegateImpl.java index c5e65df..353de557 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/XrDelegateImpl.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/XrDelegateImpl.java
@@ -6,16 +6,17 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.build.annotations.NullMarked; import org.chromium.components.webxr.XrSessionCoordinator.SessionType; /** - * This class provides methods to interact with and query the state of any Xr - * specific runtimes. Notably, it serves as a "wrapper" to abstract and - * coordinate any AR or VR specific states. It will only be compiled into Chrome - * if either |enable_arcore| or |enable_cardboard| are set, and attempts to load - * the relevant concrete implementations for the various XR Runtime Delegate + * This class provides methods to interact with and query the state of any Xr specific runtimes. + * Notably, it serves as a "wrapper" to abstract and coordinate any AR or VR specific states. It + * will only be compiled into Chrome if either |enable_arcore| or |enable_cardboard| are set, and + * attempts to load the relevant concrete implementations for the various XR Runtime Delegate * interfaces. */ +@NullMarked public class XrDelegateImpl implements XrDelegate { private @SessionType int mActiveSession = SessionType.NONE;
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/XrHostActivity.java b/components/webxr/android/java/src/org/chromium/components/webxr/XrHostActivity.java index 5f87da8b..8acf189 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/XrHostActivity.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/XrHostActivity.java
@@ -11,6 +11,8 @@ import android.view.SurfaceView; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; // TODO(crbug.com/40904930): Investigate if this would benefit from // extending ChromeBaseAppCompatActivity @@ -20,6 +22,7 @@ * separate activity than that of the main browser makes lifetime tracking and returning to the 2D * browser when done cleaner. */ +@NullMarked public class XrHostActivity extends Activity { private static final String TAG = "XrHostActivity"; private static final boolean DEBUG_LOGS = false; @@ -39,7 +42,7 @@ } @Override - public void onCreate(Bundle savedInstanceState) { + public void onCreate(@Nullable Bundle savedInstanceState) { if (DEBUG_LOGS) Log.i(TAG, "onCreate"); super.onCreate(savedInstanceState); @@ -74,6 +77,7 @@ } @Override + @SuppressWarnings("GestureBackNavigation") public void onBackPressed() { if (DEBUG_LOGS) Log.i(TAG, "onBackPressed"); super.onBackPressed();
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/XrImmersiveOverlay.java b/components/webxr/android/java/src/org/chromium/components/webxr/XrImmersiveOverlay.java index f52073a..53c5f445 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/XrImmersiveOverlay.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/XrImmersiveOverlay.java
@@ -4,6 +4,8 @@ package org.chromium.components.webxr; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.annotation.SuppressLint; import android.app.Activity; import android.content.pm.ActivityInfo; @@ -14,9 +16,10 @@ import android.view.SurfaceView; import android.view.View; -import androidx.annotation.NonNull; - import org.chromium.base.Log; +import org.chromium.build.annotations.Initializer; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.ScreenOrientationDelegate; import org.chromium.content_public.browser.ScreenOrientationProvider; import org.chromium.content_public.browser.WebContents; @@ -30,6 +33,7 @@ * Provides a fullscreen overlay for immersive sessions, allows tailoring setup/etc. due to the * particular needs of AR/VR sessions via the XrImmersiveOverlay.Delegate interface. */ +@NullMarked public class XrImmersiveOverlay implements SurfaceHolder.Callback2, View.OnTouchListener, ScreenOrientationDelegate { /** @@ -104,7 +108,7 @@ private Delegate mOverlayDelegate; private Activity mActivity; private boolean mSurfaceReportedReady; - private Integer mRestoreOrientation; + private @Nullable Integer mRestoreOrientation; private boolean mCleanupInProgress; private XrSurfaceView mXrSurfaceView; private WebContents mWebContents; @@ -112,19 +116,18 @@ // Set containing all currently touching pointers. private HashMap<Integer, PointerData> mPointerIdToData; // ID of primary pointer (if present). - private Integer mPrimaryPointerId; + private @Nullable Integer mPrimaryPointerId; + @Initializer public void show( - @NonNull Delegate overlayDelegate, - @NonNull WebContents webContents, - @NonNull XrSessionCoordinator caller) { + Delegate overlayDelegate, WebContents webContents, XrSessionCoordinator caller) { if (DEBUG_LOGS) Log.i(TAG, "constructor"); mXrSessionCoordinator = caller; mWebContents = webContents; mOverlayDelegate = overlayDelegate; - mActivity = XrSessionCoordinator.getActivity(webContents); + mActivity = assumeNonNull(XrSessionCoordinator.getActivity(webContents)); mPointerIdToData = new HashMap<Integer, PointerData>(); mPrimaryPointerId = null; @@ -147,7 +150,7 @@ } private class XrSurfaceView { - private SurfaceView mSurfaceView; + private @Nullable SurfaceView mSurfaceView; private WebContentsObserver mWebContentsObserver; private boolean mSurfaceViewNeedsDestruction; private boolean mDestructionFromVisibilityChanged; @@ -479,6 +482,7 @@ // transport even if the currently-visible part in the surface view is smaller than this. We // shouldn't get resize events since we're using FLAG_LAYOUT_STABLE and are locking screen // orientation. + assumeNonNull(mWebContents.getTopLevelNativeWindow()); DisplayAndroid display = mWebContents.getTopLevelNativeWindow().getDisplay(); if (mSurfaceReportedReady) { int rotation = display.getRotation();
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/XrSessionCoordinator.java b/components/webxr/android/java/src/org/chromium/components/webxr/XrSessionCoordinator.java index dff3089..e470194 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/XrSessionCoordinator.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/XrSessionCoordinator.java
@@ -4,6 +4,8 @@ package org.chromium.components.webxr; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -18,6 +20,8 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid; @@ -26,14 +30,15 @@ import java.lang.ref.WeakReference; /** - * Provides static methods called by the XrDelegateImpl as well as JNI methods to the C/C++ code - * in order to interact with the various bits of the Java side of a session. This includes the - * responsibility to standup/create any needed overlays/SurfaceViews and forwarding events both - * from them and elsewhere within Chrome (forwarded/registered for via XrDelegate). This class is - * also responsible for ensuring that there is only one active session at a time and answering - * questions about that session; mainly via communication of its static members. + * Provides static methods called by the XrDelegateImpl as well as JNI methods to the C/C++ code in + * order to interact with the various bits of the Java side of a session. This includes the + * responsibility to standup/create any needed overlays/SurfaceViews and forwarding events both from + * them and elsewhere within Chrome (forwarded/registered for via XrDelegate). This class is also + * responsible for ensuring that there is only one active session at a time and answering questions + * about that session; mainly via communication of its static members. */ @JNINamespace("webxr") +@NullMarked public class XrSessionCoordinator { private static final String TAG = "XrSessionCoordinator"; private static final boolean DEBUG_LOGS = false; @@ -51,7 +56,7 @@ // in progress, and reset to null on session end. The XrImmersiveOverlay member has a strong // reference to the ChromeActivity, and that shouldn't be retained beyond the duration of a // session. - private static XrSessionCoordinator sActiveSessionInstance; + private static @Nullable XrSessionCoordinator sActiveSessionInstance; /** Whether there is a non-null valid {@link #sActiveSessionInstance}. */ private static XrSessionTypeSupplier sActiveSessionAvailableSupplier = @@ -63,20 +68,20 @@ // and keeps a strong reference to it for the lifetime of the device. It creates and // owns an XrImmersiveOverlay for the duration of an immersive session, which in // turn contains a reference to XrSessionCoordinator for making JNI calls back to the device. - private XrImmersiveOverlay mImmersiveOverlay; + private @Nullable XrImmersiveOverlay mImmersiveOverlay; private @SessionType int mActiveSessionType = SessionType.NONE; // The WebContents that triggered the currently active session. - private WebContents mWebContents; + private @Nullable WebContents mWebContents; - private WeakReference<Activity> mXrHostActivity; + private @Nullable WeakReference<Activity> mXrHostActivity; // Helper, obtains android Activity out of passed in WebContents instance. // Equivalent to ChromeActivity.fromWebContents(), but does not require that // the resulting instance is a ChromeActivity. @CalledByNative - public static Activity getActivity(final WebContents webContents) { + public static @Nullable Activity getActivity(final WebContents webContents) { if (webContents == null) return null; WindowAndroid window = webContents.getTopLevelNativeWindow(); if (window == null) return null; @@ -96,7 +101,7 @@ * @return Context The current activity as a Context. */ @CalledByNative - private static Context getCurrentActivityContext() { + private static @Nullable Context getCurrentActivityContext() { if (sActiveSessionInstance == null || sActiveSessionInstance.mWebContents == null) { return null; } @@ -155,6 +160,7 @@ webContents, useOverlay, canRenderDomContent); + assumeNonNull(overlayDelegate); startSession(SessionType.AR, overlayDelegate, webContents); } @@ -167,9 +173,13 @@ // active session going on. assert (sActiveSessionInstance == null); + Activity activity = getActivity(webContents); + assumeNonNull(activity); + XrImmersiveOverlay.Delegate overlayDelegate = CardboardClassProvider.getOverlayDelegate( - compositorDelegateProvider.create(webContents), getActivity(webContents)); + compositorDelegateProvider.create(webContents), activity); + assumeNonNull(overlayDelegate); startSession(SessionType.VR, overlayDelegate, webContents); } @@ -267,6 +277,7 @@ } public static boolean hasActiveArSession() { + assumeNonNull(sActiveSessionInstance); return sActiveSessionInstance.mActiveSessionType == SessionType.AR; } @@ -275,6 +286,7 @@ } public static void onActiveXrSessionButtonTouched() { + assumeNonNull(sActiveSessionInstance); sActiveSessionInstance.onXrSessionButtonTouched(); } @@ -293,7 +305,7 @@ height); } - public static XrSessionCoordinator getActiveInstanceForTesting() { + public static @Nullable XrSessionCoordinator getActiveInstanceForTesting() { return sActiveSessionInstance; } @@ -389,6 +401,8 @@ void onXrSessionButtonTouched(long nativeXrSessionCoordinator, XrSessionCoordinator caller); void onXrHostActivityReady( - long nativeXrSessionCoordinator, XrSessionCoordinator caller, Activity activity); + long nativeXrSessionCoordinator, + XrSessionCoordinator caller, + @Nullable Activity activity); } }
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/XrSessionTypeSupplier.java b/components/webxr/android/java/src/org/chromium/components/webxr/XrSessionTypeSupplier.java index 4228420..e6968af 100644 --- a/components/webxr/android/java/src/org/chromium/components/webxr/XrSessionTypeSupplier.java +++ b/components/webxr/android/java/src/org/chromium/components/webxr/XrSessionTypeSupplier.java
@@ -5,9 +5,13 @@ package org.chromium.components.webxr; import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.build.annotations.NullMarked; import org.chromium.components.webxr.XrSessionCoordinator.SessionType; -/** A thin wrapper/subclass of ObservableSupplierImpl to add some type safety for the Xr SessionType. */ +/** + * A thin wrapper/subclass of ObservableSupplierImpl to add some type safety for the Xr SessionType. + */ +@NullMarked public class XrSessionTypeSupplier extends ObservableSupplierImpl<Integer> { public XrSessionTypeSupplier(@SessionType int initialValue) { set(initialValue);
diff --git a/components/webxr/android/stubs/java/src/org/chromium/components/webxr/ArClassProvider.java b/components/webxr/android/stubs/java/src/org/chromium/components/webxr/ArClassProvider.java index 5e4c7d3..7c5561cd 100644 --- a/components/webxr/android/stubs/java/src/org/chromium/components/webxr/ArClassProvider.java +++ b/components/webxr/android/stubs/java/src/org/chromium/components/webxr/ArClassProvider.java
@@ -4,9 +4,9 @@ package org.chromium.components.webxr; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.WebContents; /** @@ -15,10 +15,11 @@ * this just returns null for all of the types. Any method signatures updated in the "real" version * need to also be updated here as well. */ +@NullMarked /*package*/ class ArClassProvider { - /*package*/ static @Nullable XrImmersiveOverlay.Delegate getOverlayDelegate( - @NonNull ArCompositorDelegate compositorDelegate, - @NonNull final WebContents webContents, + /*package*/ static XrImmersiveOverlay.@Nullable Delegate getOverlayDelegate( + ArCompositorDelegate compositorDelegate, + final WebContents webContents, boolean useOverlay, boolean canRenderDomContent) { return null;
diff --git a/components/webxr/android/stubs/java/src/org/chromium/components/webxr/CardboardClassProvider.java b/components/webxr/android/stubs/java/src/org/chromium/components/webxr/CardboardClassProvider.java index 48e09e2..7bf0a84 100644 --- a/components/webxr/android/stubs/java/src/org/chromium/components/webxr/CardboardClassProvider.java +++ b/components/webxr/android/stubs/java/src/org/chromium/components/webxr/CardboardClassProvider.java
@@ -6,18 +6,20 @@ import android.app.Activity; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; + /** * This "stub" version of CardboardClassProvider is only built if |enable_cardboard| is false. As * such, none of the concrete implementations for the exposed interfaces are present, and this just * returns null for all of the types. Any method signatures updated in the "real" version need to * also be updated here as well. */ +@NullMarked /*package*/ class CardboardClassProvider { - /*package*/ static @Nullable XrImmersiveOverlay.Delegate getOverlayDelegate( - VrCompositorDelegate compositorDelegate, @NonNull Activity activity) { + /*package*/ static XrImmersiveOverlay.@Nullable Delegate getOverlayDelegate( + VrCompositorDelegate compositorDelegate, Activity activity) { return null; } }
diff --git a/content/browser/accessibility/browser_accessibility_state_impl_win.cc b/content/browser/accessibility/browser_accessibility_state_impl_win.cc index 72d72856..0b3764ea 100644 --- a/content/browser/accessibility/browser_accessibility_state_impl_win.cc +++ b/content/browser/accessibility/browser_accessibility_state_impl_win.cc
@@ -221,7 +221,8 @@ DWORD narrator_value = 0; if (base::win::RegKey(HKEY_CURRENT_USER, kNarratorRegistryKey, KEY_QUERY_VALUE) - .ReadValueDW(kNarratorRunningStateValueName, &narrator_value) && + .ReadValueDW(kNarratorRunningStateValueName, &narrator_value) == + ERROR_SUCCESS && narrator_value) { discovered_ats.push_back({AccessibilityTarget::kNarrator, std::nullopt}); }
diff --git a/content/browser/btm/btm_page_visit_observer.cc b/content/browser/btm/btm_page_visit_observer.cc index c5f1c4f..c92f112 100644 --- a/content/browser/btm/btm_page_visit_observer.cc +++ b/content/browser/btm/btm_page_visit_observer.cc
@@ -98,7 +98,10 @@ urls.push_back(navigation_handle.GetURL()); // TODO - crbug.com/406841434: `CHECK` the result of `filter_.Filter`. - filter_.Filter(urls, accesses); + bool were_all_accesses_matched = filter_.Filter(urls, accesses); + if (!were_all_accesses_matched) { + base::debug::DumpWithoutCrashing(); + } int i = 0; for (const size_t redirect_chain_index : server_redirect_chain_indices_) { @@ -297,6 +300,15 @@ return; } + // Ignore non-navigational cookie accesses reported through this event because + // we can't reliably attribute subresources accesses to the URL that is + // loading the subresource. + // TODO - https://crbug.com/408168195: Attribute non-navigation accesses e.g. + // from Early Hints, to the correct URL. + if (details.source == CookieAccessDetails::Source::kNonNavigation) { + return; + } + auto* state = NavigationState::GetForNavigationHandle(*navigation_handle); if (!state) { // We must have started observing this WebContents after the navigation
diff --git a/content/browser/btm/btm_page_visit_observer_browsertest.cc b/content/browser/btm/btm_page_visit_observer_browsertest.cc index 569ac0e..224d8ba 100644 --- a/content/browser/btm/btm_page_visit_observer_browsertest.cc +++ b/content/browser/btm/btm_page_visit_observer_browsertest.cc
@@ -6,6 +6,7 @@ #include "base/feature_list.h" #include "base/test/simple_test_clock.h" +#include "components/network_session_configurator/common/network_switches.h" #include "components/ukm/content/source_url_recorder.h" #include "content/browser/btm/btm_browsertest_utils.h" #include "content/browser/btm/btm_page_visit_observer_test_utils.h" @@ -16,12 +17,18 @@ #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_mock_cert_verifier.h" #include "content/public/test/fenced_frame_test_util.h" #include "content/public/test/prerender_test_util.h" #include "content/shell/browser/shell.h" +#include "net/base/features.h" +#include "net/cert/cert_verify_result.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_status_code.h" +#include "net/test/cert_test_util.h" #include "net/test/embedded_test_server/controllable_http_response.h" +#include "net/test/quic_simple_test_server.h" +#include "net/test/test_data_directory.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/frame/frame.mojom-shared.h" #include "url/gurl.h" @@ -47,6 +54,15 @@ class BtmPageVisitObserverBrowserTest : public ContentBrowserTest { public: + BtmPageVisitObserverBrowserTest() { + // Needed to make QuicSimpleTestServer work on Android. + feature_list_.InitWithFeatures( + std::vector<base::test::FeatureRef>{ + net::features::kSplitCacheByNetworkIsolationKey}, + std::vector<base::test::FeatureRef>{ + net::features::kMigrateSessionsOnNetworkChangeV2}); + } + void SetUpOnMainThread() override { host_resolver()->AddRule("*", "127.0.0.1"); embedded_https_test_server().AddDefaultHandlers(GetTestDataFilePath()); @@ -55,6 +71,23 @@ ASSERT_TRUE(embedded_https_test_server().Start()); ukm_recorder_.emplace(); + + // Configure the certificate for the QUIC server. + auto test_cert = + net::ImportCertFromFile(net::GetTestCertsDirectory(), "quic-chain.pem"); + net::CertVerifyResult verify_result; + verify_result.verified_cert = test_cert; + mock_cert_verifier_.mock_cert_verifier()->AddResultForCert( + test_cert, verify_result, net::OK); + mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + ASSERT_TRUE(net::QuicSimpleTestServer::Start()); + command_line->AppendSwitchASCII( + switches::kOriginToForceQuicOn, + net::QuicSimpleTestServer::GetHostPort().ToString()); + mock_cert_verifier_.SetUpCommandLine(command_line); } void PreRunTestOnMainThread() override { @@ -62,12 +95,93 @@ ukm::InitializeSourceUrlRecorderForWebContents(shell()->web_contents()); } + void TearDown() override { + // Needed by net::QuicSimpleTestServer::Shutdown() below. + base::ScopedAllowBaseSyncPrimitivesForTesting allow_wait; + net::QuicSimpleTestServer::Shutdown(); + } + const ukm::TestAutoSetUkmRecorder& ukm_recorder() { return ukm_recorder_.value(); } + void SetUpInProcessBrowserTestFixture() override { + mock_cert_verifier_.SetUpInProcessBrowserTestFixture(); + } + + void TearDownInProcessBrowserTestFixture() override { + mock_cert_verifier_.TearDownInProcessBrowserTestFixture(); + } + protected: + GURL RegisterSubresourceQuicResponseWithCookies() { + constexpr static const char path[] = "/early.css"; + quiche::HttpHeaderBlock response_headers; + response_headers[":path"] = path; + response_headers[":status"] = base::ToString(net::HTTP_OK); + response_headers["content-type"] = "text/css"; + response_headers["cache-control"] = "max-age=3600"; + response_headers["set-cookie"] = "foo=bar;"; + net::QuicSimpleTestServer::AddResponse(path, std::move(response_headers), + "/* empty body */"); + return net::QuicSimpleTestServer::GetFileURL(path); + } + + GURL RegisterPageQuicResponseWithEarlyHints() { + constexpr static const char path[] = "/early_hints.html"; + + quiche::HttpHeaderBlock response_headers; + response_headers[":path"] = path; + response_headers[":status"] = base::ToString(net::HTTP_OK); + response_headers["content-type"] = "text/html"; + + // Early Hint header. + quiche::HttpHeaderBlock early_hint_header; + early_hint_header["link"] = "</early.css>; rel=preload; as=style"; + std::vector<quiche::HttpHeaderBlock> early_hints; + early_hints.push_back(std::move(early_hint_header)); + + net::QuicSimpleTestServer::AddResponseWithEarlyHints( + path, std::move(response_headers), + R"(<link rel="stylesheet" href="/early.css" />)", + std::move(early_hints)); + return net::QuicSimpleTestServer::GetFileURL(path); + } + + GURL RegisterRedirectQuicResponseWithEarlyHints(const GURL& final_url) { + static constexpr const char path[] = "/redirect_with_early_hints.html"; + quiche::HttpHeaderBlock response_headers; + response_headers[":path"] = path; + response_headers[":status"] = base::ToString(net::HTTP_FOUND); + response_headers["location"] = final_url.spec(); + + // Early Hint header. + quiche::HttpHeaderBlock early_hint_header; + early_hint_header["link"] = "</early.css>; rel=preload; as=style"; + std::vector<quiche::HttpHeaderBlock> early_hints; + early_hints.push_back(std::move(early_hint_header)); + + net::QuicSimpleTestServer::AddResponseWithEarlyHints( + path, std::move(response_headers), /*response_body=*/"", + std::move(early_hints)); + return net::QuicSimpleTestServer::GetFileURL(path); + } + + GURL RegisterPageQuicResponse() { + static constexpr const char path[] = "/empty.html"; + quiche::HttpHeaderBlock response_headers; + response_headers[":path"] = path; + response_headers[":status"] = base::ToString(net::HTTP_OK); + response_headers["content-type"] = "text/html"; + + net::QuicSimpleTestServer::AddResponse(path, std::move(response_headers), + /*response_body=*/""); + return net::QuicSimpleTestServer::GetFileURL(path); + } + std::optional<ukm::TestAutoSetUkmRecorder> ukm_recorder_; + base::test::ScopedFeatureList feature_list_; + ContentMockCertVerifier mock_cert_verifier_; }; IN_PROC_BROWSER_TEST_F(BtmPageVisitObserverBrowserTest, SmokeTest) { @@ -918,6 +1032,156 @@ EXPECT_EQ(recorder.visits().size(), 3u); } +IN_PROC_BROWSER_TEST_F(BtmPageVisitObserverBrowserTest, + EarlyHintsWithCookieWrite) { + GURL subresource_url = RegisterSubresourceQuicResponseWithCookies(); + GURL url_with_early_hints = RegisterPageQuicResponseWithEarlyHints(); + + const GURL url2 = + embedded_https_test_server().GetURL("b.test", "/empty.html"); + + WebContents* web_contents = shell()->web_contents(); + BtmPageVisitRecorder recorder(web_contents); + + URLCookieAccessObserver access_observer(web_contents, subresource_url, + CookieOperation::kChange); + ASSERT_TRUE(NavigateToURL(web_contents, url_with_early_hints)); + access_observer.Wait(); + ASSERT_TRUE(NavigateToURL(web_contents, url2)); + ASSERT_TRUE(recorder.WaitForSize(2)); + + const auto& first_visit = recorder.visits()[0]; + EXPECT_THAT(first_visit.navigation.destination, + HasUrlAndMatchingSourceId(url_with_early_hints, &ukm_recorder())); + + const auto& second_visit = recorder.visits()[1]; + EXPECT_THAT(second_visit.navigation.destination, + HasUrlAndMatchingSourceId(url2, &ukm_recorder())); + // Currently cookie accesses by subresources loaded through early hints are + // ignored *if* the notification arrives through the + // OnCookiesAccessed(NavigationHandle*) override, otherwise they are + // attributed to the frame. + // TODO - https://crbug.com/408168195: Uncomment the line when we always + // attribute the access to the correct URL. + // EXPECT_TRUE(second_visit.prev_page.had_active_storage_access); +} + +IN_PROC_BROWSER_TEST_F(BtmPageVisitObserverBrowserTest, + DelayedEarlyHintsWithCookieWrite) { + GURL subresource_url = RegisterSubresourceQuicResponseWithCookies(); + GURL url_with_early_hints = RegisterPageQuicResponseWithEarlyHints(); + + const GURL url2 = + embedded_https_test_server().GetURL("b.test", "/empty.html"); + + WebContents* web_contents = shell()->web_contents(); + BtmPageVisitRecorder recorder(web_contents); + CookieAccessInterceptor interceptor(*web_contents); + + URLCookieAccessObserver access_observer(web_contents, subresource_url, + CookieOperation::kChange); + ASSERT_TRUE(NavigateToURL(web_contents, url_with_early_hints)); + access_observer.Wait(); + ASSERT_TRUE(NavigateToURL(web_contents, url2)); + ASSERT_TRUE(recorder.WaitForSize(2)); + + const auto& first_visit = recorder.visits()[0]; + EXPECT_THAT(first_visit.navigation.destination, + HasUrlAndMatchingSourceId(url_with_early_hints, &ukm_recorder())); + + const auto& second_visit = recorder.visits()[1]; + EXPECT_THAT(second_visit.navigation.destination, + HasUrlAndMatchingSourceId(url2, &ukm_recorder())); + // Delayed cookie accesses by subresources loaded through early hints are + // reported on the frame, so they are attributed to the visit. + EXPECT_TRUE(second_visit.prev_page.had_active_storage_access); +} + +IN_PROC_BROWSER_TEST_F(BtmPageVisitObserverBrowserTest, + RedirectWithEarlyHints) { + const GURL subresource_url = RegisterSubresourceQuicResponseWithCookies(); + const GURL destination_url = RegisterPageQuicResponse(); + const GURL redirect_with_early_hints_url = + RegisterRedirectQuicResponseWithEarlyHints(destination_url); + + const GURL url2 = + embedded_https_test_server().GetURL("b.test", "/empty.html"); + + WebContents* web_contents = shell()->web_contents(); + BtmPageVisitRecorder recorder(web_contents); + + URLCookieAccessObserver access_observer(web_contents, subresource_url, + CookieOperation::kChange); + ASSERT_TRUE(NavigateToURL(web_contents, redirect_with_early_hints_url, + destination_url)); + access_observer.Wait(); + ASSERT_TRUE(NavigateToURL(web_contents, url2)); + ASSERT_TRUE(recorder.WaitForSize(2)); + + const auto& first_visit = recorder.visits()[0]; + EXPECT_THAT(first_visit.navigation.destination, + HasUrlAndMatchingSourceId(destination_url, &ukm_recorder())); + EXPECT_THAT(first_visit.navigation.server_redirects[0], + HasUrlAndMatchingSourceId(redirect_with_early_hints_url, + &ukm_recorder())); + + // Currently cookie accesses by subresources loaded through early hints are + // ignored. + // TODO - https://crbug.com/408168195: Switch to EXPECT_TRUE once we can + // correctly attribute these accesses. + EXPECT_FALSE(first_visit.navigation.server_redirects[0].did_write_cookies); + + const auto& second_visit = recorder.visits()[1]; + EXPECT_THAT(second_visit.navigation.destination, + HasUrlAndMatchingSourceId(url2, &ukm_recorder())); + EXPECT_FALSE(second_visit.prev_page.had_active_storage_access); +} + +IN_PROC_BROWSER_TEST_F(BtmPageVisitObserverBrowserTest, + DelayedRedirectWithEarlyHints) { + const GURL subresource_url = RegisterSubresourceQuicResponseWithCookies(); + const GURL destination_url = RegisterPageQuicResponse(); + const GURL redirect_with_early_hints_url = + RegisterRedirectQuicResponseWithEarlyHints(destination_url); + + const GURL url2 = + embedded_https_test_server().GetURL("b.test", "/empty.html"); + + WebContents* web_contents = shell()->web_contents(); + BtmPageVisitRecorder recorder(web_contents); + CookieAccessInterceptor interceptor(*web_contents); + + URLCookieAccessObserver access_observer(web_contents, subresource_url, + CookieOperation::kChange); + ASSERT_TRUE(NavigateToURL(web_contents, redirect_with_early_hints_url, + destination_url)); + access_observer.Wait(); + ASSERT_TRUE(NavigateToURL(web_contents, url2)); + ASSERT_TRUE(recorder.WaitForSize(2)); + + const auto& first_visit = recorder.visits()[0]; + EXPECT_THAT(first_visit.navigation.destination, + HasUrlAndMatchingSourceId(destination_url, &ukm_recorder())); + EXPECT_THAT(first_visit.navigation.server_redirects[0], + HasUrlAndMatchingSourceId(redirect_with_early_hints_url, + &ukm_recorder())); + // Currently cookie accesses by subresources loaded through early hints are + // ignored. + // TODO - https://crbug.com/408168195: Switch to EXPECT_TRUE once we can + // correctly attribute these accesses. + EXPECT_FALSE(first_visit.navigation.server_redirects[0].did_write_cookies); + + const auto& second_visit = recorder.visits()[1]; + EXPECT_THAT(second_visit.navigation.destination, + HasUrlAndMatchingSourceId(url2, &ukm_recorder())); + // Delayed cookie accesses by subresources loaded through early hints from a + // redirect are incorrectly reported on the frame, so they are attributed to + // the visit. + // TODO - https://crbug.com/408168195: Switch to EXPECT_TRUE once we can + // correctly attribute these accesses. + EXPECT_TRUE(second_visit.prev_page.had_active_storage_access); +} + class BtmPageVisitObserverClientRedirectBrowserTest : public BtmPageVisitObserverBrowserTest, public testing::WithParamInterface<BtmClientRedirectMethod> {
diff --git a/content/browser/interest_group/interest_group_k_anonymity_manager.cc b/content/browser/interest_group/interest_group_k_anonymity_manager.cc index 278d205f..ef502e68 100644 --- a/content/browser/interest_group/interest_group_k_anonymity_manager.cc +++ b/content/browser/interest_group/interest_group_k_anonymity_manager.cc
@@ -50,7 +50,9 @@ k_anonymity_service_callback_(k_anonymity_service_callback), weak_ptr_factory_(this) {} -InterestGroupKAnonymityManager::~InterestGroupKAnonymityManager() = default; +InterestGroupKAnonymityManager::~InterestGroupKAnonymityManager() { + DCHECK(queries_in_progress_.empty()); +} InterestGroupKAnonymityManager::InProgressQueryState::InProgressQueryState( base::Time update_time, @@ -136,8 +138,18 @@ return; } + // If all of the keys we need were fetched from the cache, update k-anonymous + // keys on the interest group and clean up the `InProgressQueryState`. + if (cache_response.ids_to_query_from_server.empty()) { + interest_group_manager_->UpdateKAnonymity( + interest_group_key, cache_response.positive_hashed_keys_from_cache, + update_time, it->second.replace_existing_values); + queries_in_progress_.erase(it); + return; + } + it->second.positive_hashed_keys_from_received_responses = - cache_response.positive_hashed_keys_from_cache; + std::move(cache_response.positive_hashed_keys_from_cache); KAnonymityServiceDelegate* k_anonymity_service = k_anonymity_service_callback_.Run(); @@ -148,8 +160,8 @@ } std::vector<std::string> ids_to_query_in_next_batch; - for (const std::string& key : cache_response.ids_to_query_from_server) { - ids_to_query_in_next_batch.push_back(key); + for (std::string& key : cache_response.ids_to_query_from_server) { + ids_to_query_in_next_batch.emplace_back(std::move(key)); if (ids_to_query_in_next_batch.size() >= kQueryBatchSizeLimit) { it->second.remaining_responses++;
diff --git a/content/browser/interest_group/interest_group_k_anonymity_manager_unittest.cc b/content/browser/interest_group/interest_group_k_anonymity_manager_unittest.cc index 8dd52122..6e0150a 100644 --- a/content/browser/interest_group/interest_group_k_anonymity_manager_unittest.cc +++ b/content/browser/interest_group/interest_group_k_anonymity_manager_unittest.cc
@@ -1063,4 +1063,74 @@ } } +// Same as above, but it ends on a case where all of the keys were retrieved +// from the cache. We specifically handle this special case, otherwise we +// would leak the last `InProgressQueryState` in `queries_in_progress_`. The +// test above doesn't verify this behavior because the final call to +// `JoinInterestGroup` replaces the leaked `InProgressQueryState` -- since they +// both use the same `InterestGroupKey` -- with a new one that doesn't leak +// because some of the keys it tries to fetch aren't in the cache. +TEST_F(InterestGroupKAnonymityManagerTestWithMock, + QuerySetMustNotLeakInProgressQueryState) { + base::test::ScopedFeatureList scoped_feature_to_enable_kanon_cache; + scoped_feature_to_enable_kanon_cache.InitAndEnableFeatureWithParameters( + features::kFledgeCacheKAnonHashedKeys, + {{"CacheKAnonHashedKeysTtl", "4h"}}); + + auto manager = CreateManager(/*has_error=*/false); + const GURL top_frame = GURL("https://www.example.com/foo"); + const url::Origin owner = url::Origin::Create(top_frame); + + blink::InterestGroup group = MakeInterestGroup(owner, "foo"); + blink::InterestGroupKey group_key(group.owner, group.name); + + std::string adKAnonKey = blink::HashedKAnonKeyForAdBid(group, kAdURL); + std::string reportingIdsKAnonKey = + HashedKAnonKeyForAdNameReporting(group, group.ads->at(0), std::nullopt); + + delegate()->ReturnFalseForId(reportingIdsKAnonKey); + + // Rejoin the interest group and wait for the k-anonymity query triggered by + // that join to complete. Nothing is cached yet, so this does go to the k-anon + // service. + { + base::HistogramTester histograms; + manager->JoinInterestGroup(group, top_frame); + task_environment().FastForwardBy(base::Minutes(1)); + EXPECT_THAT(delegate()->TakeQueryIDs(), + testing::ElementsAre(std::vector<std::string>( + {adKAnonKey, reportingIdsKAnonKey}))); + auto maybe_group = GetGroup(manager.get(), group.owner, group.name); + ASSERT_TRUE(maybe_group); + // One for the renderURL k-anon key, and one for the reporting IDs. + EXPECT_THAT(maybe_group.value()->hashed_kanon_keys, + testing::ElementsAre(adKAnonKey)); + histograms.ExpectUniqueSample( + "Storage.InterestGroup.KAnonymityKeysCacheHitRate", 0, 1); + } + + // Long enough has passed where the query interval has passed but not the TTL. + task_environment().FastForwardBy(1.5 * kQueryInterval); + + // Rejoin the interest group and wait for the k-anonymity query triggered by + // that join to complete. This one is cached, so doesn't go to the k-anon + // service. + { + base::HistogramTester histograms; + manager->JoinInterestGroup(group, top_frame); + task_environment().FastForwardBy(base::Minutes(1)); + EXPECT_THAT(delegate()->TakeQueryIDs(), testing::IsEmpty()); + auto maybe_group = GetGroup(manager.get(), group.owner, group.name); + ASSERT_TRUE(maybe_group); + // One for the renderURL k-anon key, and one for the reporting IDs. + EXPECT_THAT(maybe_group.value()->hashed_kanon_keys, + testing::ElementsAre(adKAnonKey)); + histograms.ExpectUniqueSample( + "Storage.InterestGroup.KAnonymityKeysCacheHitRate", 100, 1); + } + + // Long enough has passed where the query interval has passed AND the TTL. + task_environment().FastForwardBy(1.5 * kQueryInterval); +} + } // namespace content
diff --git a/content/browser/loader/keep_alive_url_loader_service.cc b/content/browser/loader/keep_alive_url_loader_service.cc index e22101bf..81b55a7 100644 --- a/content/browser/loader/keep_alive_url_loader_service.cc +++ b/content/browser/loader/keep_alive_url_loader_service.cc
@@ -193,7 +193,7 @@ context->policy_container_host, context->weak_document_ptr, context->ukm_source_id, service_->browser_context_, base::BindRepeating(&KeepAliveURLLoaderFactoriesBase::CreateThrottles, - base::Unretained(this), resource_request), + base::Unretained(this)), base::PassKey<KeepAliveURLLoaderService>(), KeepAliveAttributionRequestHelper::CreateIfNeeded( resource_request.attribution_reporting_eligibility, @@ -221,8 +221,7 @@ } private: - std::vector<std::unique_ptr<blink::URLLoaderThrottle>> CreateThrottles( - const network::ResourceRequest& resource_request) { + std::vector<std::unique_ptr<blink::URLLoaderThrottle>> CreateThrottles() { if (service_->url_loader_throttles_getter_for_testing_) { return service_->url_loader_throttles_getter_for_testing_ .Run(); // IN-TEST @@ -235,13 +234,7 @@ // in https://crrev.com/c/2552723/3 suggests that running them again in // browser is fine. return CreateContentBrowserURLLoaderThrottlesForKeepAlive( - resource_request, service_->browser_context_, - // The renderer might be gone at any point when a throttle is running in - // the KeepAliveURLLoader. - /*wc_getter=*/base::BindRepeating([]() -> WebContents* { - return nullptr; - }), - FrameTreeNodeId()); + service_->browser_context_, FrameTreeNodeId()); } void OnLoaderDisconnected() {
diff --git a/content/browser/loader/url_loader_throttles.cc b/content/browser/loader/url_loader_throttles.cc index 3a14f32..341d0f0 100644 --- a/content/browser/loader/url_loader_throttles.cc +++ b/content/browser/loader/url_loader_throttles.cc
@@ -131,13 +131,11 @@ std::vector<std::unique_ptr<blink::URLLoaderThrottle>> CreateContentBrowserURLLoaderThrottlesForKeepAlive( - const network::ResourceRequest& request, BrowserContext* browser_context, - const base::RepeatingCallback<WebContents*()>& wc_getter, FrameTreeNodeId frame_tree_node_id) { std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles = GetContentClient()->browser()->CreateURLLoaderThrottlesForKeepAlive( - request, browser_context, wc_getter, frame_tree_node_id); + browser_context, frame_tree_node_id); // TODO(crbug.com/40135370): Consider whether we want to use the WebContents // to determine the value for variations::Owner. Alternatively, this is the // browser side, and we might be fine with Owner::kUnknown.
diff --git a/content/browser/media/key_system_support_android.cc b/content/browser/media/key_system_support_android.cc index 9e4b990..a7c427b9 100644 --- a/content/browser/media/key_system_support_android.cc +++ b/content/browser/media/key_system_support_android.cc
@@ -243,6 +243,7 @@ std::move(cdm_capability_cb_) .Run(base::unexpected( media::CdmCapabilityQueryStatus::kNoMediaDrmSupport)); + delete this; return; } @@ -258,9 +259,11 @@ // is not supported. void OnServiceClosed() { DVLOG(1) << "IsKeySystemSupported failed for " << key_system_; - std::move(cdm_capability_cb_) - .Run(base::unexpected( - media::CdmCapabilityQueryStatus::kDisconnectionError)); + if (cdm_capability_cb_) { + std::move(cdm_capability_cb_) + .Run(base::unexpected( + media::CdmCapabilityQueryStatus::kDisconnectionError)); + } delete this; }
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc index e9be07b..192c4371 100644 --- a/content/browser/media/session/media_session_impl.cc +++ b/content/browser/media/session/media_session_impl.cc
@@ -1321,7 +1321,7 @@ media_session::mojom::MediaSessionAction::kEnterPictureInPicture); uma_helper_.RecordEnterPictureInPicture( MediaSessionUmaHelper::EnterPictureInPictureType::kRegisteredAutomatic); - OnAutoPictureInPictureInfoChanged(); + ReportAutoPictureInPictureInfoChanged(); } void MediaSessionImpl::SetAudioSinkId(const std::optional<std::string>& id) { @@ -1431,6 +1431,21 @@ minimum_size_px, desired_size_px, source_icon)); } +void MediaSessionImpl::ReportAutoPictureInPictureInfoChanged() { + ContentClient* content_client = GetContentClient(); + const auto auto_picture_in_picture_info = + media::PictureInPictureEventsInfo::AutoPipInfoToString( + content_client->browser()->GetAutoPipInfo(*web_contents())); + + ForAllPlayers(base::BindRepeating( + [](std::string_view auto_picture_in_picture_info, + const PlayerIdentifier& player) { + player.observer->OnAutoPictureInPictureInfoChanged( + player.player_id, auto_picture_in_picture_info); + }, + auto_picture_in_picture_info)); +} + void MediaSessionImpl::AbandonSystemAudioFocusIfNeeded() { if (audio_focus_state_ == State::INACTIVE || !normal_players_.empty() || !pepper_players_.empty() || !one_shot_players_.empty() || @@ -2162,21 +2177,6 @@ guarding_player_id_.reset(); } -void MediaSessionImpl::OnAutoPictureInPictureInfoChanged() { - ContentClient* content_client = GetContentClient(); - const auto auto_picture_in_picture_reason = - media::PictureInPictureEventsInfo::AutoPipReasonToString( - content_client->browser()->GetAutoPipReason(*web_contents())); - - ForAllPlayers(base::BindRepeating( - [](std::string_view auto_picture_in_picture_reason, - const PlayerIdentifier& player) { - player.observer->OnAutoPictureInPictureInfoChanged( - player.player_id, auto_picture_in_picture_reason); - }, - auto_picture_in_picture_reason)); -} - void MediaSessionImpl::SetShouldThrottleDurationUpdateForTest( bool should_throttle) { should_throttle_duration_update_ = should_throttle;
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h index 8f5390c..f508bb3 100644 --- a/content/browser/media/session/media_session_impl.h +++ b/content/browser/media/session/media_session_impl.h
@@ -319,6 +319,10 @@ int desired_size_px, GetMediaImageBitmapCallback callback) override; + // Called to report to all players that the auto picture in picture + // information changed. + void ReportAutoPictureInPictureInfoChanged() override; + const base::UnguessableToken& audio_focus_group_id() const { return audio_focus_group_id_; } @@ -530,10 +534,6 @@ void ResetDurationUpdateGuard(); - // Called when any of the normal players auto picture in picture information - // changes. - void OnAutoPictureInPictureInfoChanged(); - CONTENT_EXPORT void SetShouldThrottleDurationUpdateForTest( bool should_throttle);
diff --git a/content/browser/renderer_host/render_frame_host_delegate.cc b/content/browser/renderer_host/render_frame_host_delegate.cc index cac24d2..94f051a 100644 --- a/content/browser/renderer_host/render_frame_host_delegate.cc +++ b/content/browser/renderer_host/render_frame_host_delegate.cc
@@ -238,9 +238,9 @@ return gfx::NativeWindow(); } -media::PictureInPictureEventsInfo::AutoPipReason -RenderFrameHostDelegate::GetAutoPipReason() const { - return media::PictureInPictureEventsInfo::AutoPipReason::kUnknown; +media::PictureInPictureEventsInfo::AutoPipInfo +RenderFrameHostDelegate::GetAutoPipInfo() const { + return media::PictureInPictureEventsInfo::AutoPipInfo(); } } // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_delegate.h b/content/browser/renderer_host/render_frame_host_delegate.h index ca5a5eb82..fb913eb 100644 --- a/content/browser/renderer_host/render_frame_host_delegate.h +++ b/content/browser/renderer_host/render_frame_host_delegate.h
@@ -782,9 +782,8 @@ // Returns the top-level native window for the associated WebContents. virtual gfx::NativeWindow GetOwnerNativeWindow(); - // Gets the delegate reason for entering picture in picture automatically. - virtual media::PictureInPictureEventsInfo::AutoPipReason GetAutoPipReason() - const; + // Gets the delegate auto picture in picture information. + virtual media::PictureInPictureEventsInfo::AutoPipInfo GetAutoPipInfo() const; protected: virtual ~RenderFrameHostDelegate() = default;
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 270f3af..40a53cb9 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -18587,7 +18587,7 @@ if (rfh == nullptr) { return media::PictureInPictureEventsInfo::AutoPipReason::kUnknown; } - return rfh->delegate()->GetAutoPipReason(); + return rfh->delegate()->GetAutoPipInfo().auto_pip_reason; }, weak_ptr_factory_.GetWeakPtr()); }
diff --git a/content/browser/tpcd_heuristics/opener_heuristic_browsertest.cc b/content/browser/tpcd_heuristics/opener_heuristic_browsertest.cc index 2ce38c1..d639b799 100644 --- a/content/browser/tpcd_heuristics/opener_heuristic_browsertest.cc +++ b/content/browser/tpcd_heuristics/opener_heuristic_browsertest.cc
@@ -53,6 +53,7 @@ #include "services/network/public/cpp/features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/strings/str_format.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/common/switches.h" @@ -136,26 +137,6 @@ base::RunLoop run_loop_; }; -// Waits for a navigation in the primary main frame to finish. -class NavigationFinishObserver : public WebContentsObserver { - public: - explicit NavigationFinishObserver(WebContents* web_contents) - : WebContentsObserver(web_contents) {} - - void Wait() { run_loop_.Run(); } - - private: - // WebContentsObserver overrides: - void DidFinishNavigation(NavigationHandle* navigation_handle) override { - if (!navigation_handle->IsInPrimaryMainFrame()) { - return; - } - run_loop_.Quit(); - } - - base::RunLoop run_loop_; -}; - } // namespace // SubresourceFilterBrowserTest is necessary to test ad-tagging related @@ -250,8 +231,15 @@ dips->storage()->FlushPostedTasksForTesting(); } - // Open a popup window with the given URL and return its WebContents. + // Open a popup window, navigate it to `url`, and return its WebContents. base::expected<WebContents*, std::string> OpenPopup(const GURL& url) { + return OpenPopup(url, url); + } + + // Open a popup window, start a navigation to `initial_url`, confirm that it + // lands on `final_url`, and return its WebContents. + base::expected<WebContents*, std::string> OpenPopup(const GURL& initial_url, + const GURL& final_url) { auto* web_contents = GetActiveWebContents(); if (web_contents->GetLastCommittedURL().is_empty()) { // We can't call window.open() if we're not on a page. Go to about:blank. @@ -261,13 +249,21 @@ } PopupObserver observer(web_contents); if (!ExecJs(web_contents, - JsReplace("window.open($1, '', 'popup');", url))) { + JsReplace("window.open($1, '', 'popup');", initial_url))) { return base::unexpected("window.open failed"); } observer.Wait(); // Wait for the popup to finish navigating to its initial URL. - NavigationFinishObserver(observer.popup()).Wait(); + if (!WaitForLoadStop(observer.popup())) { + return base::unexpected("popup navigation failed"); + } + + if (observer.popup()->GetLastCommittedURL() != final_url) { + return base::unexpected(absl::StrFormat( + "popup navigated to %s (expected %s)", + observer.popup()->GetLastCommittedURL().spec(), final_url.spec())); + } // Wait for the read of the past interaction from the DIPS DB to complete, // so the PopupPastInteraction UKM event is reported. @@ -780,8 +776,7 @@ GURL final_url = embedded_test_server()->GetURL("c.test", "/title1.html"); RecordUserActivationInteraction(initial_url, clock_.Now() - base::Hours(3)); ASSERT_TRUE(NavigateToURL(GetActiveWebContents(), opener_url)); - ASSERT_OK_AND_ASSIGN(WebContents * popup, OpenPopup(initial_url)); - ASSERT_EQ(popup->GetLastCommittedURL(), final_url); + ASSERT_THAT(OpenPopup(initial_url, final_url), HasValue()); // Expect that cookie access was granted for the Popup With Past Interaction // heuristic, if the feature is enabled. @@ -842,11 +837,12 @@ ukm::TestAutoSetUkmRecorder ukm_recorder; GURL popup_url = embedded_test_server()->GetURL("a.test", "/server-redirect?title1.html"); + GURL final_url = embedded_test_server()->GetURL("a.test", "/title1.html"); RecordUserActivationInteraction(GURL("https://a.test"), clock_.Now() - base::Hours(3)); - ASSERT_THAT(OpenPopup(popup_url), HasValue()); + ASSERT_THAT(OpenPopup(popup_url, final_url), HasValue()); std::vector<ukm::TestAutoSetUkmRecorder::HumanReadableUkmEntry> entries = ukm_recorder.GetEntries("OpenerHeuristic.PopupPastInteraction", @@ -872,13 +868,15 @@ IN_PROC_BROWSER_TEST_F(OpenerHeuristicBrowserTest, MAYBE_PopupPastInteractionIsReported_ClientRedirect) { ukm::TestAutoSetUkmRecorder ukm_recorder; - GURL popup_url = - embedded_test_server()->GetURL("a.test", "/client-redirect?title1.html"); + GURL popup_url = embedded_test_server()->GetURL("a.test", "/title1.html"); + GURL final_url = embedded_test_server()->GetURL("b.test", "/title1.html"); RecordUserActivationInteraction(GURL("https://a.test"), clock_.Now() - base::Hours(3)); - ASSERT_THAT(OpenPopup(popup_url), HasValue()); + ASSERT_OK_AND_ASSIGN(WebContents * popup, OpenPopup(popup_url)); + // Perform a client-side redirect. + ASSERT_TRUE(NavigateToURLFromRendererWithoutUserGesture(popup, final_url)); std::vector<ukm::TestAutoSetUkmRecorder::HumanReadableUkmEntry> entries = ukm_recorder.GetEntries("OpenerHeuristic.PopupPastInteraction", @@ -1115,8 +1113,7 @@ "b.test", "/cross-site/c.test/title1.html"); GURL final_url = embedded_test_server()->GetURL("c.test", "/title1.html"); ASSERT_TRUE(NavigateToURL(GetActiveWebContents(), opener_url)); - ASSERT_OK_AND_ASSIGN(WebContents * popup, OpenPopup(initial_url)); - ASSERT_EQ(popup->GetLastCommittedURL(), final_url); + ASSERT_OK_AND_ASSIGN(WebContents * popup, OpenPopup(initial_url, final_url)); clock_.Advance(base::Minutes(1)); SimulateMouseClick(popup); @@ -1227,7 +1224,7 @@ // TODO(crbug.com/408234441): Re-enable this test // Very flaky on macOS 11 Tests: https://crbug.com/1486448 -#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_MAC) +#if BUILDFLAG(IS_MAC) #define MAYBE_PopupInteraction_IsFollowedByPostPopupCookieAccess \ DISABLED_PopupInteraction_IsFollowedByPostPopupCookieAccess #else @@ -1399,17 +1396,8 @@ /*exclusion=*/{"ExcludeThirdPartyPhaseout"}); } -// TODO(crbug.com/408234441): Re-enable this test -#if BUILDFLAG(IS_FUCHSIA) -#define MAYBE_TopLevelIsReported_PastInteraction_NoSameSiteIframe \ - DISABLED_TopLevelIsReported_PastInteraction_NoSameSiteIframe -#else -#define MAYBE_TopLevelIsReported_PastInteraction_NoSameSiteIframe \ - TopLevelIsReported_PastInteraction_NoSameSiteIframe -#endif -IN_PROC_BROWSER_TEST_F( - OpenerHeuristicBrowserTest, - MAYBE_TopLevelIsReported_PastInteraction_NoSameSiteIframe) { +IN_PROC_BROWSER_TEST_F(OpenerHeuristicBrowserTest, + TopLevelIsReported_PastInteraction_NoSameSiteIframe) { ukm::TestAutoSetUkmRecorder ukm_recorder; GURL toplevel_url = embedded_test_server()->GetURL("a.test", "/title1.html"); GURL popup_url = embedded_test_server()->GetURL("b.test", "/title1.html"); @@ -1438,16 +1426,8 @@ ValueIs(OptionalBool::kFalse)); } -// TODO(crbug.com/408234441): Re-enable this test -#if BUILDFLAG(IS_FUCHSIA) -#define MAYBE_TopLevelIsReported_HasSameSiteIframe \ - DISABLED_TopLevelIsReported_HasSameSiteIframe -#else -#define MAYBE_TopLevelIsReported_HasSameSiteIframe \ - TopLevelIsReported_HasSameSiteIframe -#endif IN_PROC_BROWSER_TEST_F(OpenerHeuristicBrowserTest, - MAYBE_TopLevelIsReported_HasSameSiteIframe) { + TopLevelIsReported_HasSameSiteIframe) { ukm::TestAutoSetUkmRecorder ukm_recorder; GURL toplevel_url = embedded_test_server()->GetURL("a.test", "/page_with_blank_iframe.html"); @@ -1481,14 +1461,7 @@ ValueIs(OptionalBool::kTrue)); } -// TODO(crbug.com/408234441): Re-enable this test -#if BUILDFLAG(IS_FUCHSIA) -#define MAYBE_TopLevel_PopupProvider DISABLED_TopLevel_PopupProvider -#else -#define MAYBE_TopLevel_PopupProvider TopLevel_PopupProvider -#endif -IN_PROC_BROWSER_TEST_F(OpenerHeuristicBrowserTest, - MAYBE_TopLevel_PopupProvider) { +IN_PROC_BROWSER_TEST_F(OpenerHeuristicBrowserTest, TopLevel_PopupProvider) { ukm::TestAutoSetUkmRecorder ukm_recorder; GURL toplevel_url = embedded_test_server()->GetURL("a.test", "/title1.html"); GURL popup_url = embedded_test_server()->GetURL("google.com", "/title1.html"); @@ -1509,13 +1482,7 @@ static_cast<int64_t>(PopupProvider::kGoogle)); } -// TODO(crbug.com/408234441): Re-enable this test -#if BUILDFLAG(IS_FUCHSIA) -#define MAYBE_TopLevel_PopupId DISABLED_TopLevel_PopupId -#else -#define MAYBE_TopLevel_PopupId TopLevel_PopupId -#endif -IN_PROC_BROWSER_TEST_F(OpenerHeuristicBrowserTest, MAYBE_TopLevel_PopupId) { +IN_PROC_BROWSER_TEST_F(OpenerHeuristicBrowserTest, TopLevel_PopupId) { ukm::TestAutoSetUkmRecorder ukm_recorder; GURL toplevel_url = embedded_test_server()->GetURL("a.test", "/title1.html"); GURL popup_url = embedded_test_server()->GetURL("google.com", "/title1.html"); @@ -1636,8 +1603,7 @@ SimulateMouseClick(GetActiveWebContents()); ASSERT_TRUE(NavigateToURL(GetActiveWebContents(), opener_url)); - ASSERT_OK_AND_ASSIGN(WebContents * popup, OpenPopup(initial_url)); - ASSERT_EQ(popup->GetLastCommittedURL(), final_url); + ASSERT_OK_AND_ASSIGN(WebContents * popup, OpenPopup(initial_url, final_url)); clock_.Advance(base::Minutes(1)); SimulateMouseClick(popup); GetDipsService()->storage()->FlushPostedTasksForTesting(); @@ -1709,17 +1675,8 @@ // Test the backfill grants created by OpenerHeuristicService when tracking // protection is onboarded. -// TODO(crbug.com/408234441): Re-enable this test -#if BUILDFLAG(IS_FUCHSIA) -#define MAYBE_TrackingProtectionOnboardingCreatesBackfillGrants \ - DISABLED_TrackingProtectionOnboardingCreatesBackfillGrants -#else -#define MAYBE_TrackingProtectionOnboardingCreatesBackfillGrants \ - TrackingProtectionOnboardingCreatesBackfillGrants -#endif -IN_PROC_BROWSER_TEST_P( - OpenerHeuristicBackfillGrantBrowserTest, - MAYBE_TrackingProtectionOnboardingCreatesBackfillGrants) { +IN_PROC_BROWSER_TEST_P(OpenerHeuristicBackfillGrantBrowserTest, + TrackingProtectionOnboardingCreatesBackfillGrants) { GURL opener_url = embedded_test_server()->GetURL("a.test", "/title1.html"); GURL popup_url_1 = embedded_test_server()->GetURL("b.test", "/title1.html"); GURL popup_url_2 = embedded_test_server()->GetURL("c.test", "/title1.html");
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index b7fc242..a8e0d2d0 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -7254,9 +7254,9 @@ return GetTopLevelNativeWindow(); } -media::PictureInPictureEventsInfo::AutoPipReason -WebContentsImpl::GetAutoPipReason() const { - return GetContentClient()->browser()->GetAutoPipReason(*this); +media::PictureInPictureEventsInfo::AutoPipInfo WebContentsImpl::GetAutoPipInfo() + const { + return GetContentClient()->browser()->GetAutoPipInfo(*this); } void WebContentsImpl::NotifyChangedNavigationState(
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index c6cb37c5..08f0e968 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -948,7 +948,7 @@ void OnFirstContentfulPaintInPrimaryMainFrame() override; gfx::NativeWindow GetOwnerNativeWindow() override; - media::PictureInPictureEventsInfo::AutoPipReason GetAutoPipReason() + media::PictureInPictureEventsInfo::AutoPipInfo GetAutoPipInfo() const override; // RenderViewHostDelegate ----------------------------------------------------
diff --git a/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java index 3624c56..5726050 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java
@@ -279,7 +279,7 @@ } @Override - public void setOrientationDelegate(ScreenOrientationDelegate delegate) { + public void setOrientationDelegate(@Nullable ScreenOrientationDelegate delegate) { mDelegate = delegate; }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationProvider.java b/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationProvider.java index 146ab38c..f3dece0 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationProvider.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationProvider.java
@@ -39,10 +39,11 @@ /** Runs delayed screen orientation requests for the given window. */ void runDelayedOrientationRequests(WindowAndroid window); - void setOrientationDelegate(ScreenOrientationDelegate delegate); + void setOrientationDelegate(@Nullable ScreenOrientationDelegate delegate); /** * Sets a default screen orientation for a given window. + * * @param window Window to lock rotation on. * @param defaultWebOrientation a default screen orientation for the window. */
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 1c873a9..08653c1 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -1069,9 +1069,7 @@ std::vector<std::unique_ptr<blink::URLLoaderThrottle>> ContentBrowserClient::CreateURLLoaderThrottlesForKeepAlive( - const network::ResourceRequest& request, BrowserContext* browser_context, - const base::RepeatingCallback<WebContents*()>& wc_getter, FrameTreeNodeId frame_tree_node_id) { return std::vector<std::unique_ptr<blink::URLLoaderThrottle>>(); } @@ -1354,9 +1352,9 @@ return nullptr; } -media::PictureInPictureEventsInfo::AutoPipReason -ContentBrowserClient::GetAutoPipReason(const WebContents& web_contents) const { - return media::PictureInPictureEventsInfo::AutoPipReason::kUnknown; +media::PictureInPictureEventsInfo::AutoPipInfo +ContentBrowserClient::GetAutoPipInfo(const WebContents& web_contents) const { + return media::PictureInPictureEventsInfo::AutoPipInfo(); } void ContentBrowserClient::RegisterRendererPreferenceWatcher(
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 0f3a638c..0b9ef23b 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -1866,19 +1866,13 @@ // browser-side throttles for keepalive requests: // https://docs.google.com/document/d/1ZzxMMBvpqn8VZBZKnb7Go8TWjnrGcXuLS_USwVVRUvY/edit#heading=h.eu8mlvut479 // - // |wc_getter| returns the WebContents of the context of the |request| when - // available. It can return nullptr for requests for which it there are no - // WebContents (e.g., requests for web workers). - // // |frame_tree_node_id| is also invalid in some cases // (e.g., requests for web workers). // // This is called on the UI thread. virtual std::vector<std::unique_ptr<blink::URLLoaderThrottle>> CreateURLLoaderThrottlesForKeepAlive( - const network::ResourceRequest& request, BrowserContext* browser_context, - const base::RepeatingCallback<WebContents*()>& wc_getter, FrameTreeNodeId frame_tree_node_id); // Allows the embedder to register per-scheme URLLoaderFactory implementations @@ -2483,9 +2477,9 @@ CreateWindowForVideoPictureInPicture( VideoPictureInPictureWindowController* controller); - // Returns the reason for entering picture in picture automatically. This is - // recorded in metrics. - virtual media::PictureInPictureEventsInfo::AutoPipReason GetAutoPipReason( + // Returns information related to auto picture in picture. The auto picture in + // picture reason is recorded in metrics. + virtual media::PictureInPictureEventsInfo::AutoPipInfo GetAutoPipInfo( const WebContents& web_contents) const; // Registers the watcher to observe updates in RendererPreferences.
diff --git a/content/public/browser/media_session.h b/content/public/browser/media_session.h index 90d0093..a2c99f8 100644 --- a/content/public/browser/media_session.h +++ b/content/public/browser/media_session.h
@@ -73,6 +73,10 @@ // service, if the routed service exists, nullptr otherwise. virtual RenderFrameHost* GetRoutedFrame() = 0; + // Report to all players that information related to automatic picture in + // picture has changed. + virtual void ReportAutoPictureInPictureInfoChanged() = 0; + // media_session.mojom.MediaSession overrides ------------------------------- // Suspend the media session.
diff --git a/content/public/browser/url_loader_throttles.h b/content/public/browser/url_loader_throttles.h index 1787b7d..b61ce6e 100644 --- a/content/public/browser/url_loader_throttles.h +++ b/content/public/browser/url_loader_throttles.h
@@ -44,9 +44,7 @@ CONTENT_EXPORT std::vector<std::unique_ptr<blink::URLLoaderThrottle>> CreateContentBrowserURLLoaderThrottlesForKeepAlive( - const network::ResourceRequest& request, BrowserContext* browser_context, - const base::RepeatingCallback<WebContents*()>& wc_getter, FrameTreeNodeId frame_tree_node_id); } // namespace content
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index a10c9e4..9773ba3 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -373,7 +373,7 @@ // Enable drawing under System Bars within DisplayCutout. BASE_FEATURE(kDrawCutoutEdgeToEdge, "DrawCutoutEdgeToEdge", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Enable establishing the GPU channel early in renderer startup. BASE_FEATURE(kEarlyEstablishGpuChannel,
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 49366da..794ceb2a 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -3873,6 +3873,30 @@ if (notification->find("Media.") != std::string::npos) { last_media_notification_ = *notification; + + if (*notification == "Media.playerEventsAdded") { + bool last_auto_pip_event_info_set = false; + const base::Value::List* events = + parsed_message.FindListByDottedPath("params.events"); + if (events) { + for (const base::Value& event : *events) { + const auto* dict = event.GetIfDict(); + if (!dict) { + continue; + } + const std::string* text = dict->FindString("value"); + if ((text != nullptr) && + ((*text).find("auto_picture_in_picture_info") != + std::string::npos)) { + last_auto_picture_in_picture_event_info_ = *text; + last_auto_pip_event_info_set = true; + } + } + } + if (last_auto_pip_event_info_set) { + NotifyLastAutoPipEventInfoSet(); + } + } } } @@ -3895,6 +3919,12 @@ run_loop_disable_log_.Run(); } +void DevToolsInspectorLogWatcher::NotifyLastAutoPipEventInfoSet() { + for (DevToolsInspectorLogWatcherObserver& obs : observers_) { + obs.OnLastAutoPipEventInfoSet(); + } +} + namespace { mojo::Remote<blink::mojom::FileSystemManager> GetFileSystemManager( RenderProcessHost* rph,
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 643d3e5..d20676d 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -21,6 +21,8 @@ #include "base/memory/raw_ptr.h" #include "base/memory/raw_ptr_exclusion.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "base/observer_list_types.h" #include "base/process/process.h" #include "base/run_loop.h" #include "base/scoped_observation.h" @@ -2136,11 +2138,34 @@ std::string last_media_notification() { return last_media_notification_; } void ClearLastMediaNotification() { last_media_notification_.clear(); } + std::string last_auto_picture_in_picture_event_info() { + return last_auto_picture_in_picture_event_info_; + } + void ClearLastAutoPictureInPictureEventInfo() { + last_auto_picture_in_picture_event_info_.clear(); + } + // DevToolsAgentHostClient: void DispatchProtocolMessage(DevToolsAgentHost* host, base::span<const uint8_t> message) override; void AgentHostClosed(DevToolsAgentHost* host) override; + class DevToolsInspectorLogWatcherObserver : public base::CheckedObserver { + public: + virtual void OnLastAutoPipEventInfoSet() = 0; + }; + + void AddObserver(DevToolsInspectorLogWatcherObserver* observer) { + observers_.AddObserver(observer); + } + void RemoveObserver(DevToolsInspectorLogWatcherObserver* observer) { + observers_.RemoveObserver(observer); + } + + // Notifies observers that the last auto picture in picture event information + // was set. + void NotifyLastAutoPipEventInfoSet(); + private: scoped_refptr<DevToolsAgentHost> host_; base::RunLoop run_loop_enable_log_; @@ -2149,6 +2174,8 @@ GURL last_url_; Domain domain_; std::string last_media_notification_; + std::string last_auto_picture_in_picture_event_info_; + base::ObserverList<DevToolsInspectorLogWatcherObserver> observers_; }; // Static methods that simulates Mojo methods as if they were called by a
diff --git a/content/public/test/mock_media_session.h b/content/public/test/mock_media_session.h index 6988439..9e3b304 100644 --- a/content/public/test/mock_media_session.h +++ b/content/public/test/mock_media_session.h
@@ -55,6 +55,7 @@ int desired_size_px, GetMediaImageBitmapCallback callback), (override)); + MOCK_METHOD(void, ReportAutoPictureInPictureInfoChanged, (), (override)); MOCK_METHOD(void, SeekTo, (base::TimeDelta seek_time), (override)); MOCK_METHOD(void, ScrubTo, (base::TimeDelta seek_time), (override)); MOCK_METHOD(void, EnterPictureInPicture, (), (override));
diff --git a/content/test/content_test_bundle_data.filelist b/content/test/content_test_bundle_data.filelist index 05a747160..d8fb6b2 100644 --- a/content/test/content_test_bundle_data.filelist +++ b/content/test/content_test_bundle_data.filelist
@@ -796,6 +796,7 @@ data/accessibility/aria/aria-figure.html data/accessibility/aria/aria-flowto-expected-android-assist-data.txt data/accessibility/aria/aria-flowto-expected-android-external.txt +data/accessibility/aria/aria-flowto-expected-android.txt data/accessibility/aria/aria-flowto-expected-blink.txt data/accessibility/aria/aria-flowto-expected-mac.txt data/accessibility/aria/aria-flowto-expected-win.txt
diff --git a/content/test/data/accessibility/aria/aria-flowto-expected-android.txt b/content/test/data/accessibility/aria/aria-flowto-expected-android.txt new file mode 100644 index 0000000..01ff7080 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-flowto-expected-android.txt
@@ -0,0 +1,3 @@ +android.webkit.WebView focusable focused +++android.view.View role_description='region' interesting container_title='current' +++android.view.View role_description='footer' interesting supplemental_description='next'
diff --git a/device/BUILD.gn b/device/BUILD.gn index 6e121af..468f8a5 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -367,7 +367,6 @@ ldflags = [ "-ObjC" ] frameworks = [ "CoreBluetooth.framework", - "IOKit.framework", "Foundation.framework", ] } @@ -375,6 +374,7 @@ if (is_mac) { frameworks += [ "IOBluetooth.framework", + "IOKit.framework", "Security.framework", "AuthenticationServices.framework", ]
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn index 16407ea..f4dd57a 100644 --- a/device/bluetooth/BUILD.gn +++ b/device/bluetooth/BUILD.gn
@@ -254,7 +254,6 @@ ] frameworks = [ "CoreBluetooth.framework", - "IOKit.framework", "Foundation.framework", ] } @@ -276,7 +275,10 @@ "bluetooth_socket_mac.h", "bluetooth_socket_mac.mm", ] - frameworks += [ "IOBluetooth.framework" ] + frameworks += [ + "IOBluetooth.framework", + "IOKit.framework", + ] } if (is_ios) {
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java index 510d1a92..93b6c0f 100644 --- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java +++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java
@@ -6,6 +6,7 @@ import android.Manifest; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import android.bluetooth.le.ScanFilter; import android.content.BroadcastReceiver; import android.content.Context; @@ -233,8 +234,18 @@ } for (BluetoothDeviceWrapper device : devices) { - populatePairedDevice(device); + populatePairedDevice(device, /* fromBroadcastReceiver= */ false); } + + if (mDeviceBondStateReceiver != null) { + return; + } + mDeviceBondStateReceiver = + mAdapter.createDeviceBondStateReceiver(new BondedStateReceiver()); + ContextUtils.registerProtectedBroadcastReceiver( + mAdapter.getContext(), + mDeviceBondStateReceiver, + new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED)); } // --------------------------------------------------------------------------------------------- @@ -284,13 +295,15 @@ } } - private void populatePairedDevice(BluetoothDeviceWrapper deviceWrapper) { + private void populatePairedDevice( + BluetoothDeviceWrapper deviceWrapper, boolean fromBroadcastReceiver) { ChromeBluetoothAdapterJni.get() .populatePairedDevice( mNativeBluetoothAdapterAndroid, this, deviceWrapper.getAddress(), - deviceWrapper); + deviceWrapper, + fromBroadcastReceiver); } /** @@ -384,6 +397,22 @@ } } + public class BondedStateReceiver implements DeviceBondStateReceiverWrapper.Callback { + @Override + public void onDeviceBondStateChanged(BluetoothDeviceWrapper device, int bondState) { + if (bondState == BluetoothDevice.BOND_BONDED) { + populatePairedDevice(device, /* fromBroadcastReceiver= */ true); + } + if (bondState == BluetoothDevice.BOND_NONE) { + ChromeBluetoothAdapterJni.get() + .onDeviceUnpaired( + mNativeBluetoothAdapterAndroid, + ChromeBluetoothAdapter.this, + device.getAddress()); + } + } + } + @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); @@ -459,7 +488,12 @@ long nativeBluetoothAdapterAndroid, ChromeBluetoothAdapter caller, String address, - BluetoothDeviceWrapper deviceWrapper); + BluetoothDeviceWrapper deviceWrapper, + boolean fromBroadcastReceiver); + + // Binds to BluetoothAdapterAndroid::OnDeviceUnpaired. + void onDeviceUnpaired( + long nativeBluetoothAdapterAndroid, ChromeBluetoothAdapter caller, String address); // Binds to BluetoothAdapterAndroid::nativeOnAdapterStateChanged void onAdapterStateChanged(
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/wrapper/BluetoothAdapterWrapper.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/wrapper/BluetoothAdapterWrapper.java index 5d62f1f..3108ce5 100644 --- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/wrapper/BluetoothAdapterWrapper.java +++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/wrapper/BluetoothAdapterWrapper.java
@@ -173,4 +173,9 @@ return set; } + + public DeviceBondStateReceiverWrapper createDeviceBondStateReceiver( + DeviceBondStateReceiverWrapper.Callback callback) { + return new DeviceBondStateReceiverWrapper(callback); + } }
diff --git a/device/bluetooth/bluetooth_adapter_android.cc b/device/bluetooth/bluetooth_adapter_android.cc index 75cdac4..6b8b72b5 100644 --- a/device/bluetooth/bluetooth_adapter_android.cc +++ b/device/bluetooth/bluetooth_adapter_android.cc
@@ -311,8 +311,8 @@ const base::android::JavaParamRef<jobject>& caller, const base::android::JavaParamRef<jstring>& address, const base::android::JavaParamRef<jobject>& - bluetooth_device_wrapper // Java Type: bluetoothDeviceWrapper -) { + bluetooth_device_wrapper, // Java Type: bluetoothDeviceWrapper + bool from_broadcast_receiver) { std::string device_address = ConvertJavaStringToUTF8(env, address); auto iter = devices_.find(device_address); @@ -324,12 +324,44 @@ std::unique_ptr<BluetoothDeviceAndroid> device_owner = BluetoothDeviceAndroid::Create(this, bluetooth_device_wrapper, ui_task_runner_, socket_thread_); + BluetoothDeviceAndroid* device = device_owner.get(); devices_[device_address] = std::move(device_owner); - // We don't notify observers for populated paired devices because there is no - // current need to monitor device bond states. We always fetch the list of - // paired devices when GetDevices() is called. See crbug.com/387371131 for - // more details. + // We don't notify observers for populated paired devices unless it's from + // bonded state broadcast receiver. See crbug.com/387371131 for more details. + if (!from_broadcast_receiver) { + return; + } + + for (auto& observer : observers_) { + observer.DeviceAdded(this, device); + } +} + +void BluetoothAdapterAndroid::OnDeviceUnpaired( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& caller, + const base::android::JavaParamRef<jstring>& address) { + std::string device_address = ConvertJavaStringToUTF8(env, address); + auto iter = devices_.find(device_address); + if (iter == devices_.end()) { + return; + } + + base::TimeDelta duration_before_expiry = iter->second->GetLastUpdateTime() + + BluetoothAdapter::timeoutSec - + base::Time::NowFromSystemTime(); + if (duration_before_expiry.is_negative() || + duration_before_expiry.is_zero()) { + RemoveTimedOutDevices(); + return; + } + + ui_task_runner_->PostDelayedTask( + FROM_HERE, + base::BindOnce(&BluetoothAdapterAndroid::RemoveTimedOutDevices, + weak_ptr_factory_.GetWeakPtr()), + duration_before_expiry); } BluetoothAdapterAndroid::BluetoothAdapterAndroid() {}
diff --git a/device/bluetooth/bluetooth_adapter_android.h b/device/bluetooth/bluetooth_adapter_android.h index ad6ef80..5290c9b 100644 --- a/device/bluetooth/bluetooth_adapter_android.h +++ b/device/bluetooth/bluetooth_adapter_android.h
@@ -124,8 +124,13 @@ const base::android::JavaParamRef<jobject>& caller, const base::android::JavaParamRef<jstring>& address, const base::android::JavaParamRef<jobject>& - bluetooth_device_wrapper // Java Type: bluetoothDeviceWrapper - ); + bluetooth_device_wrapper, // Java Type: bluetoothDeviceWrapper + bool from_broadcast_receiver); + + // Called when the Android system notifies us that a device is unpaired. + void OnDeviceUnpaired(JNIEnv* env, + const base::android::JavaParamRef<jobject>& caller, + const base::android::JavaParamRef<jstring>& address); protected: BluetoothAdapterAndroid();
diff --git a/device/bluetooth/bluetooth_adapter_android_unittest.cc b/device/bluetooth/bluetooth_adapter_android_unittest.cc index 161469bf..d351ac5 100644 --- a/device/bluetooth/bluetooth_adapter_android_unittest.cc +++ b/device/bluetooth/bluetooth_adapter_android_unittest.cc
@@ -350,16 +350,47 @@ InitWithFakeAdapter(); + TestBluetoothAdapterObserver observer(adapter_.get()); + SimulatePairedClassicDevice(1); SimulatePairedClassicDevice(2); - adapter_->GetDevices(); - BluetoothAdapter::DeviceList list = adapter_->GetDevices(); + std::unordered_set<std::string> addresses; + for (auto* device : list) { + addresses.insert(device->GetAddress()); + } + EXPECT_EQ(addresses.size(), 2u); + EXPECT_NE(addresses.find(kTestDeviceAddress1), addresses.end()); + EXPECT_NE(addresses.find(kTestDeviceAddress2), addresses.end()); + + // We explicitly omit observer notifications for new paired devices found + // during GetDevices. + EXPECT_EQ(observer.device_added_count(), 0); + EXPECT_TRUE(adapter_->GetDevice(kTestDeviceAddress1)); EXPECT_TRUE(adapter_->GetDevice(kTestDeviceAddress2)); } +TEST_F(BluetoothAdapterAndroidTest, NotifyObserversForNewPairedDevices) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kBluetoothRfcommAndroid); + + InitWithFakeAdapter(); + + TestBluetoothAdapterObserver observer(adapter_.get()); + + adapter_->GetDevices(); + + SimulatePairedClassicDevice(1, true); + ASSERT_EQ(observer.device_added_count(), 1); + EXPECT_EQ(observer.last_device()->GetAddress(), kTestDeviceAddress1); + + SimulatePairedClassicDevice(2, true); + ASSERT_EQ(observer.device_added_count(), 2); + EXPECT_EQ(observer.last_device()->GetAddress(), kTestDeviceAddress2); +} + TEST_F(BluetoothAdapterAndroidTest, ExposeUuidFromPairedDevices) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature(features::kBluetoothRfcommAndroid); @@ -383,6 +414,72 @@ "00001101-0000-1000-8000-00805f9b34fb"); } +TEST_F(BluetoothAdapterAndroidTest, RemoveExpiredDevicesOnUnpaired) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kBluetoothRfcommAndroid); + + InitWithFakeAdapter(); + + SimulatePairedClassicDevice(1); + SimulatePairedClassicDevice(2); + + TestBluetoothAdapterObserver observer(adapter_.get()); + + UnpairDevice(kTestDeviceAddress1); + ASSERT_EQ(observer.device_removed_count(), 1); + EXPECT_EQ(observer.last_device_address(), kTestDeviceAddress1); + + EXPECT_FALSE(adapter_->GetDevice(kTestDeviceAddress1)); + EXPECT_TRUE(adapter_->GetDevice(kTestDeviceAddress2)); +} + +TEST_F(BluetoothAdapterAndroidTest, RemoveUnpairedDevicesAfterTimeOut) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kBluetoothRfcommAndroid); + + InitWithFakeAdapter(); + + SimulatePairedClassicDevice(1); + SimulatePairedClassicDevice(2); + + TestBluetoothAdapterObserver observer(adapter_.get()); + + // Simulate situations where these devices were found in scanning as well. + for (BluetoothDevice* device : adapter_->GetDevices()) { + device->UpdateTimestamp(); + } + + UnpairDevice(kTestDeviceAddress1); + EXPECT_EQ(observer.device_removed_count(), 0); + EXPECT_TRUE(adapter_->GetDevice(kTestDeviceAddress1)); + + // RemoveTimedOutDevices uses base::Time::NowFromSystemTime, so we have to + // explicitly set devices to be expired. + for (BluetoothDevice* device : adapter_->GetDevices()) { + device->SetAsExpiredForTesting(); + } + + task_environment_.FastForwardBy(BluetoothAdapter::timeoutSec + + base::Seconds(1)); + + ASSERT_EQ(observer.device_removed_count(), 1); + EXPECT_EQ(observer.last_device_address(), kTestDeviceAddress1); + + EXPECT_FALSE(adapter_->GetDevice(kTestDeviceAddress1)); + EXPECT_TRUE(adapter_->GetDevice(kTestDeviceAddress2)); +} + +TEST_F(BluetoothAdapterAndroidTest, UnknownDeviceUnpaired) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kBluetoothRfcommAndroid); + + InitWithFakeAdapter(); + + adapter_->GetDevices(); + + UnpairDevice(kTestDeviceAddress1); +} + TEST_F(BluetoothAdapterAndroidTest, ScanFailsWithoutLeSupport) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature(features::kBluetoothRfcommAndroid);
diff --git a/device/bluetooth/bluetooth_adapter_mac.h b/device/bluetooth/bluetooth_adapter_mac.h index e9eafad..9d76d1d9 100644 --- a/device/bluetooth/bluetooth_adapter_mac.h +++ b/device/bluetooth/bluetooth_adapter_mac.h
@@ -5,8 +5,6 @@ #ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_MAC_H_ #define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_MAC_H_ -#include <IOKit/IOReturn.h> - #include <memory> #include <optional> #include <string>
diff --git a/device/bluetooth/bluetooth_advertisement_mac.mm b/device/bluetooth/bluetooth_advertisement_mac.mm index 58126f83..c6251c7 100644 --- a/device/bluetooth/bluetooth_advertisement_mac.mm +++ b/device/bluetooth/bluetooth_advertisement_mac.mm
@@ -6,7 +6,8 @@ #include "base/functional/bind.h" #import "base/task/single_thread_task_runner.h" -#include "device/bluetooth/bluetooth_adapter_mac.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_low_energy_advertisement_manager_mac.h" namespace device {
diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h index 5758cf1..db430af 100644 --- a/device/bluetooth/bluetooth_device.h +++ b/device/bluetooth/bluetooth_device.h
@@ -653,6 +653,9 @@ // it hasn't been called yet. virtual base::Time GetLastUpdateTime() const; + // Update last_update_time_ so that the device appears as expired. + void SetAsExpiredForTesting(); + #if BUILDFLAG(IS_APPLE) // Returns true if this device is a Low Energy device. virtual bool IsLowEnergyDevice() = 0; @@ -726,8 +729,6 @@ FRIEND_TEST_ALL_PREFIXES(BluetoothTest, BluetoothGattConnection_DisconnectGatt_Cleanup); FRIEND_TEST_ALL_PREFIXES(BluetoothTest, GetName_NullName); - FRIEND_TEST_ALL_PREFIXES(BluetoothTest, RemoveOutdatedDevices); - FRIEND_TEST_ALL_PREFIXES(BluetoothTest, RemoveOutdatedDeviceGattConnect); FRIEND_TEST_ALL_PREFIXES( BluetoothTestWinrt, @@ -813,9 +814,6 @@ void AddGattConnection(BluetoothGattConnection*); void RemoveGattConnection(BluetoothGattConnection*); - // Update last_update_time_ so that the device appears as expired. - void SetAsExpiredForTesting(); - // Raw pointer to adapter owning this device object. Subclasses use platform // specific pointers via adapter_. // This field is not a raw_ptr<> because problems related to passing to a
diff --git a/device/bluetooth/bluetooth_low_energy_adapter_apple.mm b/device/bluetooth/bluetooth_low_energy_adapter_apple.mm index ee0adc0..21216c8 100644 --- a/device/bluetooth/bluetooth_low_energy_adapter_apple.mm +++ b/device/bluetooth/bluetooth_low_energy_adapter_apple.mm
@@ -24,7 +24,6 @@ #include "base/location.h" #include "base/logging.h" #include "base/mac/mac_util.h" -#include "base/mac/scoped_ioobject.h" #include "base/memory/ptr_util.h" #include "base/numerics/safe_conversions.h" #include "base/strings/string_number_conversions.h"
diff --git a/device/bluetooth/bluetooth_low_energy_device_watcher_mac.mm b/device/bluetooth/bluetooth_low_energy_device_watcher_mac.mm index 9919e52..ae680b2 100644 --- a/device/bluetooth/bluetooth_low_energy_device_watcher_mac.mm +++ b/device/bluetooth/bluetooth_low_energy_device_watcher_mac.mm
@@ -13,7 +13,6 @@ #include "base/strings/sys_string_conversions.h" #import "base/task/sequenced_task_runner.h" #include "base/task/task_traits.h" -#include "device/bluetooth/bluetooth_adapter_mac.h" namespace device {
diff --git a/device/bluetooth/bluetooth_low_energy_discovery_manager_mac.mm b/device/bluetooth/bluetooth_low_energy_discovery_manager_mac.mm index 2e4562d..1fd8590 100644 --- a/device/bluetooth/bluetooth_low_energy_discovery_manager_mac.mm +++ b/device/bluetooth/bluetooth_low_energy_discovery_manager_mac.mm
@@ -9,7 +9,6 @@ #include "base/logging.h" #include "base/mac/mac_util.h" #include "base/strings/sys_string_conversions.h" -#include "device/bluetooth/bluetooth_adapter_mac.h" #include "device/bluetooth/bluetooth_low_energy_device_mac.h" namespace device {
diff --git a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java index eca3b7db..862ef85 100644 --- a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java +++ b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java
@@ -50,6 +50,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -138,7 +139,7 @@ private final FakeBluetoothLeScanner mFakeScanner; private boolean mPowered = true; private int mEnabledDeviceTransport = BluetoothDevice.DEVICE_TYPE_DUAL; - private final ArraySet<BluetoothDeviceWrapper> mFakePairedDevices = new ArraySet(); + final ArraySet<BluetoothDeviceWrapper> mFakePairedDevices = new ArraySet<>(); private DeviceBondStateReceiverWrapper.Callback mDeviceBondStateCallback; final long mNativeBluetoothTestAndroid; @@ -367,7 +368,8 @@ } @CalledByNative("FakeBluetoothAdapter") - public @JniType("std::string") String simulatePairedClassicDevice(int deviceOrdinal) { + public @JniType("std::string") String simulatePairedClassicDevice( + int deviceOrdinal, boolean notifyCallback) { final FakeBluetoothDevice device; switch (deviceOrdinal) { case 0: @@ -402,10 +404,33 @@ } mFakePairedDevices.add(device); + if (notifyCallback && mDeviceBondStateCallback != null) { + mDeviceBondStateCallback.onDeviceBondStateChanged( + device, BluetoothDevice.BOND_BONDED); + } return device.getAddress(); } @CalledByNative("FakeBluetoothAdapter") + public void unpairDevice(@JniType("std::string") String address) { + FakeBluetoothDevice removedDevice = null; + Iterator pairedDeviceIterator = mFakePairedDevices.iterator(); + while (pairedDeviceIterator.hasNext()) { + BluetoothDeviceWrapper device = + (BluetoothDeviceWrapper) pairedDeviceIterator.next(); + if (device.getAddress().equals(address)) { + pairedDeviceIterator.remove(); + removedDevice = (FakeBluetoothDevice) device; + break; + } + } + if (removedDevice != null && mDeviceBondStateCallback != null) { + mDeviceBondStateCallback.onDeviceBondStateChanged( + removedDevice, BluetoothDevice.BOND_NONE); + } + } + + @CalledByNative("FakeBluetoothAdapter") public void forceIllegalStateException() { if (mFakeScanner != null) { mFakeScanner.forceIllegalStateException(); @@ -509,6 +534,13 @@ return mFakePairedDevices; } + + @Override + public DeviceBondStateReceiverWrapper createDeviceBondStateReceiver( + DeviceBondStateReceiverWrapper.Callback callback) { + mDeviceBondStateCallback = callback; + return super.createDeviceBondStateReceiver(callback); + } } /** Fakes android.content.Context by extending MockContext. */ @@ -795,11 +827,10 @@ @Override public int getBondState() { - if (mType == BluetoothDevice.DEVICE_TYPE_LE) { - return BluetoothDevice.BOND_NONE; - } else { + if (mAdapter.mFakePairedDevices.contains(this)) { return BluetoothDevice.BOND_BONDED; } + return BluetoothDevice.BOND_NONE; } @Override
diff --git a/device/bluetooth/test/bluetooth_test_android.cc b/device/bluetooth/test/bluetooth_test_android.cc index 9022708b..442ed907a 100644 --- a/device/bluetooth/test/bluetooth_test_android.cc +++ b/device/bluetooth/test/bluetooth_test_android.cc
@@ -145,15 +145,22 @@ } std::string BluetoothTestAndroid::SimulatePairedClassicDevice( - int device_ordinal) { + int device_ordinal, + bool notify_callback) { std::string address = Java_FakeBluetoothAdapter_simulatePairedClassicDevice( - AttachCurrentThread(), j_fake_bluetooth_adapter_, device_ordinal); + AttachCurrentThread(), j_fake_bluetooth_adapter_, device_ordinal, + notify_callback); // BluetoothAdapterAndroid only pulls bonded devices from the system when // GetDevices() is called. adapter_->GetDevices(); return address; } +void BluetoothTestAndroid::UnpairDevice(std::string address) { + Java_FakeBluetoothAdapter_unpairDevice(AttachCurrentThread(), + j_fake_bluetooth_adapter_, address); +} + void BluetoothTestAndroid::RememberDeviceForSubsequentAction( BluetoothDevice* device) { BluetoothDeviceAndroid* device_android =
diff --git a/device/bluetooth/test/bluetooth_test_android.h b/device/bluetooth/test/bluetooth_test_android.h index 8d6504e..c54b9cc 100644 --- a/device/bluetooth/test/bluetooth_test_android.h +++ b/device/bluetooth/test/bluetooth_test_android.h
@@ -123,7 +123,12 @@ // Address: kTestDeviceAddress2 // UUID: kTestUUIDSerial // Returns the address of the simulated device. - std::string SimulatePairedClassicDevice(int device_ordinal); + // Notify DeviceBondStateReceiver.Callback if |notify_callback| is true. + std::string SimulatePairedClassicDevice(int device_ordinal, + bool notify_callback = false); + + // Simulates having unpaired a device of |address|. + void UnpairDevice(std::string address); // Instruct the fake adapter to claim that location services are off for the // device.
diff --git a/device/gamepad/BUILD.gn b/device/gamepad/BUILD.gn index 70f91bc..f23ad5e8 100644 --- a/device/gamepad/BUILD.gn +++ b/device/gamepad/BUILD.gn
@@ -140,7 +140,6 @@ "CoreFoundation.framework", "Foundation.framework", "GameController.framework", - "IOKit.framework", ] if (is_mac) { @@ -156,7 +155,10 @@ "xbox_data_fetcher_mac.cc", "xbox_data_fetcher_mac.h", ] - frameworks += [ "ForceFeedback.framework" ] + frameworks += [ + "ForceFeedback.framework", + "IOKit.framework", + ] } }
diff --git a/docs/updater/protocol_4.md b/docs/updater/protocol_4.md index 94fbbbe..20dbcf0 100644 --- a/docs/updater/protocol_4.md +++ b/docs/updater/protocol_4.md
@@ -833,7 +833,7 @@ * 4: An uninstall session. * 14: A `download` operation. * 60: An `xz` operation. - * 61: A `zucchini` patch application operation. + * 61: A `zucc` patch application operation. * 62: A `puffin` patch application operation. * 63: A `crx3` package installation operation. * 41: An app command completion event.
diff --git a/extensions/components/native_app_window/native_app_window_views.cc b/extensions/components/native_app_window/native_app_window_views.cc index 832b2eb6..ca77f401 100644 --- a/extensions/components/native_app_window/native_app_window_views.cc +++ b/extensions/components/native_app_window/native_app_window_views.cc
@@ -46,11 +46,7 @@ create_params.GetContentMaximumSize(gfx::Insets())); Observe(app_window_->web_contents()); - // TODO(pbos): See if this can retain SetOwnedByWidget(true) and get deleted - // through WidgetDelegate::DeleteDelegate(). It's not clear to me how this - // ends up destructed, but the below preserves a previous DialogDelegate - // override that did not end with a direct `delete this;`. - SetOwnedByWidget(false); + // TODO(pbos): It's not clear to me how this ends up destructed. RegisterDeleteDelegateCallback(RegisterDeleteCallbackPassKey(), base::BindOnce( [](NativeAppWindowViews* dialog) {
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index dc25384..f30f2c2 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -1110,10 +1110,8 @@ DoEndRasterCHROMIUM(); } - if (have_context) { - if (use_gpu_raster_) { - transfer_cache()->DeleteAllEntriesForDecoder(raster_decoder_id_); - } + if (have_context && use_gpu_raster_ && transfer_cache()) { + transfer_cache()->DeleteAllEntriesForDecoder(raster_decoder_id_); } if (query_manager_) {
diff --git a/gpu/command_buffer/service/scheduler.cc b/gpu/command_buffer/service/scheduler.cc index 0f28b7d..1a3935b 100644 --- a/gpu/command_buffer/service/scheduler.cc +++ b/gpu/command_buffer/service/scheduler.cc
@@ -26,8 +26,8 @@ // Xor with a mask to reduce likelihood of flow id collision with non-surface // tasks. First 64-bits of SHA256 hash of "SurfaceControl::Transaction", // interpreted as a big-endian integer. Python snippet: - // hashlib.sha256(b'gpu::Scheduler').hexdigest()[:8] - static constexpr uint64_t kMask = 0x03af6247; + // hashlib.sha256(b'gpu::Scheduler').hexdigest()[:16] + static constexpr uint64_t kMask = 0x03af62470b040902; return kMask ^ (sequence_id) ^ (uint64_t{order_num} << 32); } } // namespace
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm index 226a31b..cdd2b77e 100644 --- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm +++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
@@ -56,12 +56,12 @@ struct ScopedIOSurfaceLock { ScopedIOSurfaceLock(IOSurfaceRef iosurface, IOSurfaceLockOptions options) : io_surface_(iosurface) { - IOReturn r = IOSurfaceLock(io_surface_, options, nullptr); - CHECK_EQ(kIOReturnSuccess, r); + kern_return_t r = IOSurfaceLock(io_surface_, options, nullptr); + CHECK_EQ(KERN_SUCCESS, r); } ~ScopedIOSurfaceLock() { - IOReturn r = IOSurfaceUnlock(io_surface_, 0, nullptr); - CHECK_EQ(kIOReturnSuccess, r); + kern_return_t r = IOSurfaceUnlock(io_surface_, 0, nullptr); + CHECK_EQ(KERN_SUCCESS, r); } ScopedIOSurfaceLock(const ScopedIOSurfaceLock&) = delete;
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc b/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc index 84e31e1..a64ff86 100644 --- a/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc +++ b/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc
@@ -114,8 +114,8 @@ if (map_count_++) return true; - IOReturn status = IOSurfaceLock(io_surface_.get(), lock_flags_, nullptr); - DCHECK_NE(status, kIOReturnCannotLock) << " lock_flags_: " << lock_flags_; + kern_return_t status = IOSurfaceLock(io_surface_.get(), lock_flags_, nullptr); + DCHECK_EQ(status, KERN_SUCCESS) << " lock_flags_: " << lock_flags_; return true; }
diff --git a/infra/config/generated/builder-owners/~unowned.txt b/infra/config/generated/builder-owners/~unowned.txt index d65e2d6a..40a58b62 100644 --- a/infra/config/generated/builder-owners/~unowned.txt +++ b/infra/config/generated/builder-owners/~unowned.txt
@@ -154,7 +154,6 @@ try/android-12-x64-dbg try/android-12l-x64-dbg try/android-arm-compile-dbg -try/android-arm64-all-targets-dbg try/android-arm64-rel try/android-arm64-rel-compilator try/android-bfcache-rel
diff --git "a/infra/config/generated/builders/ci/Android arm64 Builder All Targets \050dbg\051/properties.json" "b/infra/config/generated/builders/ci/Android arm64 Builder All Targets \050dbg\051/properties.json" index c5e341a..5f0a8157 100644 --- "a/infra/config/generated/builders/ci/Android arm64 Builder All Targets \050dbg\051/properties.json" +++ "b/infra/config/generated/builders/ci/Android arm64 Builder All Targets \050dbg\051/properties.json"
@@ -49,10 +49,6 @@ ], "mirroring_builder_group_and_names": [ { - "builder": "android-arm64-all-targets-dbg", - "group": "tryserver.chromium.android" - }, - { "builder": "android_compile_dbg", "group": "tryserver.chromium.android" }
diff --git a/infra/config/generated/builders/ci/mac-lsan-fyi-rel/gn-args.json b/infra/config/generated/builders/ci/mac-lsan-fyi-rel/gn-args.json index 793ea89d..2fac4786 100644 --- a/infra/config/generated/builders/ci/mac-lsan-fyi-rel/gn-args.json +++ b/infra/config/generated/builders/ci/mac-lsan-fyi-rel/gn-args.json
@@ -5,7 +5,7 @@ "is_component_build": false, "is_debug": false, "is_lsan": true, - "target_cpu": "x64", + "target_cpu": "arm64", "target_os": "mac", "use_reclient": false, "use_remoteexec": true,
diff --git a/infra/config/generated/builders/ci/mac-lsan-fyi-rel/targets/chromium.memory.fyi.json b/infra/config/generated/builders/ci/mac-lsan-fyi-rel/targets/chromium.memory.fyi.json index 68a6b4c..863c959 100644 --- a/infra/config/generated/builders/ci/mac-lsan-fyi-rel/targets/chromium.memory.fyi.json +++ b/infra/config/generated/builders/ci/mac-lsan-fyi-rel/targets/chromium.memory.fyi.json
@@ -11,7 +11,7 @@ "name": "absl_hardening_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -29,7 +29,7 @@ "name": "accessibility_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -47,7 +47,7 @@ "name": "app_shell_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -65,7 +65,7 @@ "name": "base_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -83,7 +83,7 @@ "name": "blink_heap_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -107,7 +107,7 @@ ], "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -125,7 +125,7 @@ "name": "blink_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -143,7 +143,7 @@ "name": "cc_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -161,7 +161,7 @@ "name": "components_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -179,7 +179,7 @@ "name": "content_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -197,7 +197,7 @@ "name": "crashpad_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -215,7 +215,7 @@ "name": "cronet_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -233,7 +233,7 @@ "name": "device_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -251,7 +251,7 @@ "name": "net_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/generated/builders/ci/mac-ubsan-fyi-rel/gn-args.json b/infra/config/generated/builders/ci/mac-ubsan-fyi-rel/gn-args.json index d41fee8..0034980 100644 --- a/infra/config/generated/builders/ci/mac-ubsan-fyi-rel/gn-args.json +++ b/infra/config/generated/builders/ci/mac-ubsan-fyi-rel/gn-args.json
@@ -5,7 +5,7 @@ "is_debug": false, "is_ubsan": true, "is_ubsan_no_recover": true, - "target_cpu": "x64", + "target_cpu": "arm64", "target_os": "mac", "use_reclient": false, "use_remoteexec": true,
diff --git a/infra/config/generated/builders/ci/mac-ubsan-fyi-rel/targets/chromium.memory.fyi.json b/infra/config/generated/builders/ci/mac-ubsan-fyi-rel/targets/chromium.memory.fyi.json index f7daab7..2a5ea0e 100644 --- a/infra/config/generated/builders/ci/mac-ubsan-fyi-rel/targets/chromium.memory.fyi.json +++ b/infra/config/generated/builders/ci/mac-ubsan-fyi-rel/targets/chromium.memory.fyi.json
@@ -11,7 +11,7 @@ "name": "absl_hardening_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -29,7 +29,7 @@ "name": "accessibility_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -47,7 +47,7 @@ "name": "angle_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -66,7 +66,7 @@ "name": "app_shell_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -84,7 +84,7 @@ "name": "base_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -102,7 +102,7 @@ "name": "blink_common_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -120,7 +120,7 @@ "name": "blink_fuzzer_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -138,7 +138,7 @@ "name": "blink_heap_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -162,7 +162,7 @@ ], "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -180,7 +180,7 @@ "name": "boringssl_crypto_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -198,7 +198,7 @@ "name": "boringssl_ssl_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -216,7 +216,7 @@ "name": "browser_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -236,7 +236,7 @@ "name": "capture_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -254,7 +254,7 @@ "name": "cast_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -272,7 +272,7 @@ "name": "cc_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -290,7 +290,7 @@ "name": "chrome_app_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -308,7 +308,7 @@ "name": "chromedriver_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -326,7 +326,7 @@ "name": "components_browsertests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -344,7 +344,7 @@ "name": "components_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -363,7 +363,7 @@ "name": "content_browsertests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -382,7 +382,7 @@ "name": "content_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -400,7 +400,7 @@ "name": "crashpad_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -418,7 +418,7 @@ "name": "cronet_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -436,7 +436,7 @@ "name": "cronet_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -454,7 +454,7 @@ "name": "crypto_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -472,7 +472,7 @@ "name": "device_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -490,7 +490,7 @@ "name": "display_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -509,7 +509,7 @@ "name": "env_chromium_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -527,7 +527,7 @@ "name": "events_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -545,7 +545,7 @@ "name": "extensions_browsertests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -563,7 +563,7 @@ "name": "extensions_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -581,7 +581,7 @@ "name": "filesystem_service_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -599,7 +599,7 @@ "name": "fuzzing_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -617,7 +617,7 @@ "name": "gcm_unit_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -635,7 +635,7 @@ "name": "gfx_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -653,7 +653,7 @@ "name": "gin_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -671,7 +671,7 @@ "name": "google_apis_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -689,7 +689,7 @@ "name": "gpu_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -707,7 +707,7 @@ "name": "gwp_asan_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -725,7 +725,7 @@ "name": "headless_browsertests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -743,7 +743,7 @@ "name": "headless_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -761,7 +761,7 @@ "name": "interactive_ui_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -780,7 +780,7 @@ "name": "ipc_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -798,7 +798,7 @@ "name": "latency_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -817,7 +817,7 @@ "name": "leveldb_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -835,7 +835,7 @@ "name": "libjingle_xmpp_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -853,7 +853,7 @@ "name": "liburlpattern_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -871,7 +871,7 @@ "name": "media_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -889,7 +889,7 @@ "name": "message_center_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -907,7 +907,7 @@ "name": "midi_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -925,7 +925,7 @@ "name": "mojo_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -943,7 +943,7 @@ "name": "native_theme_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -961,7 +961,7 @@ "name": "net_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -979,7 +979,7 @@ "name": "openscreen_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -997,7 +997,7 @@ "name": "pdf_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1015,7 +1015,7 @@ "name": "perfetto_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1033,7 +1033,7 @@ "name": "power_sampler_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1051,7 +1051,7 @@ "name": "printing_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1069,7 +1069,7 @@ "name": "remoting_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1087,7 +1087,7 @@ "name": "sandbox_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1105,7 +1105,7 @@ "name": "services_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1123,7 +1123,7 @@ "name": "shell_dialogs_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1141,7 +1141,7 @@ "name": "skia_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1159,7 +1159,7 @@ "name": "snapshot_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1177,7 +1177,7 @@ "name": "sql_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1195,7 +1195,7 @@ "name": "storage_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1213,7 +1213,7 @@ "name": "sync_integration_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -1232,7 +1232,7 @@ "name": "ui_base_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1250,7 +1250,7 @@ "name": "ui_touch_selection_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1268,7 +1268,7 @@ "name": "ui_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1286,7 +1286,7 @@ "name": "unit_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1304,7 +1304,7 @@ "name": "updater_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1322,7 +1322,7 @@ "name": "url_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1340,7 +1340,7 @@ "name": "views_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1358,7 +1358,7 @@ "name": "viz_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1376,7 +1376,7 @@ "name": "webkit_unit_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1394,7 +1394,7 @@ "name": "wtf_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1412,7 +1412,7 @@ "name": "xr_browser_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1430,7 +1430,7 @@ "name": "zlib_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/generated/builders/gn_args_locations.json b/infra/config/generated/builders/gn_args_locations.json index 4e6f3b8..ae6b92b 100644 --- a/infra/config/generated/builders/gn_args_locations.json +++ b/infra/config/generated/builders/gn_args_locations.json
@@ -582,7 +582,6 @@ "android-15-x64-rel": "try/android-15-x64-rel/gn-args.json", "android-16-x64-fyi-rel": "try/android-16-x64-fyi-rel/gn-args.json", "android-arm-compile-dbg": "try/android-arm-compile-dbg/gn-args.json", - "android-arm64-all-targets-dbg": "try/android-arm64-all-targets-dbg/gn-args.json", "android-arm64-rel": "try/android-arm64-rel/gn-args.json", "android-bfcache-rel": "try/android-bfcache-rel/gn-args.json", "android-binary-size": "try/android-binary-size/gn-args.json",
diff --git a/infra/config/generated/builders/try/android-arm64-all-targets-dbg/gn-args.json b/infra/config/generated/builders/try/android-arm64-all-targets-dbg/gn-args.json deleted file mode 100644 index 86b9302..0000000 --- a/infra/config/generated/builders/try/android-arm64-all-targets-dbg/gn-args.json +++ /dev/null
@@ -1,17 +0,0 @@ -{ - "gn_args": { - "android_static_analysis": "off", - "debuggable_apks": false, - "enable_android_secondary_abi": true, - "ffmpeg_branding": "Chrome", - "is_component_build": true, - "is_debug": true, - "proprietary_codecs": true, - "symbol_level": 0, - "target_cpu": "arm64", - "target_os": "android", - "use_reclient": false, - "use_remoteexec": true, - "use_siso": true - } -} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/android-arm64-all-targets-dbg/properties.json b/infra/config/generated/builders/try/android-arm64-all-targets-dbg/properties.json deleted file mode 100644 index 3aac1c8..0000000 --- a/infra/config/generated/builders/try/android-arm64-all-targets-dbg/properties.json +++ /dev/null
@@ -1,76 +0,0 @@ -{ - "$build/chromium_tests_builder_config": { - "builder_config": { - "additional_exclusions": [ - "infra/config/generated/builders/try/android-arm64-all-targets-dbg/gn-args.json" - ], - "builder_db": { - "entries": [ - { - "builder_id": { - "bucket": "ci", - "builder": "Android arm64 Builder All Targets (dbg)", - "project": "chromium" - }, - "builder_spec": { - "build_gs_bucket": "chromium-android-archive", - "builder_group": "chromium.android", - "execution_mode": "COMPILE_AND_TEST", - "legacy_android_config": { - "config": "base_config" - }, - "legacy_chromium_config": { - "apply_configs": [ - "mb", - "download_xr_test_apks" - ], - "build_config": "Debug", - "config": "main_builder", - "target_arch": "arm", - "target_bits": 64, - "target_platform": "android" - }, - "legacy_gclient_config": { - "apply_configs": [ - "android" - ], - "config": "chromium" - } - } - } - ] - }, - "builder_ids": [ - { - "bucket": "ci", - "builder": "Android arm64 Builder All Targets (dbg)", - "project": "chromium" - } - ], - "targets_spec_directory": "src/infra/config/generated/builders/try/android-arm64-all-targets-dbg/targets" - } - }, - "$build/siso": { - "configs": [ - "builder", - "remote-link" - ], - "enable_cloud_monitoring": true, - "enable_cloud_profiler": true, - "enable_cloud_trace": true, - "experiments": [], - "metrics_project": "chromium-reclient-metrics", - "output_local_strategy": "greedy", - "project": "rbe-chromium-untrusted", - "remote_jobs": -1 - }, - "$recipe_engine/resultdb/test_presentation": { - "column_keys": [], - "grouping_keys": [ - "status", - "v.test_suite" - ] - }, - "builder_group": "tryserver.chromium.android", - "recipe": "chromium_trybot" -} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/android-arm64-all-targets-dbg/targets/chromium.android.json b/infra/config/generated/builders/try/android-arm64-all-targets-dbg/targets/chromium.android.json deleted file mode 100644 index afd7d01c..0000000 --- a/infra/config/generated/builders/try/android-arm64-all-targets-dbg/targets/chromium.android.json +++ /dev/null
@@ -1,7 +0,0 @@ -{ - "Android arm64 Builder All Targets (dbg)": { - "additional_compile_targets": [ - "all" - ] - } -} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/mac-lsan-fyi-rel/gn-args.json b/infra/config/generated/builders/try/mac-lsan-fyi-rel/gn-args.json index 793ea89d..2fac4786 100644 --- a/infra/config/generated/builders/try/mac-lsan-fyi-rel/gn-args.json +++ b/infra/config/generated/builders/try/mac-lsan-fyi-rel/gn-args.json
@@ -5,7 +5,7 @@ "is_component_build": false, "is_debug": false, "is_lsan": true, - "target_cpu": "x64", + "target_cpu": "arm64", "target_os": "mac", "use_reclient": false, "use_remoteexec": true,
diff --git a/infra/config/generated/builders/try/mac-lsan-fyi-rel/targets/chromium.memory.fyi.json b/infra/config/generated/builders/try/mac-lsan-fyi-rel/targets/chromium.memory.fyi.json index 68a6b4c..863c959 100644 --- a/infra/config/generated/builders/try/mac-lsan-fyi-rel/targets/chromium.memory.fyi.json +++ b/infra/config/generated/builders/try/mac-lsan-fyi-rel/targets/chromium.memory.fyi.json
@@ -11,7 +11,7 @@ "name": "absl_hardening_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -29,7 +29,7 @@ "name": "accessibility_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -47,7 +47,7 @@ "name": "app_shell_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -65,7 +65,7 @@ "name": "base_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -83,7 +83,7 @@ "name": "blink_heap_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -107,7 +107,7 @@ ], "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -125,7 +125,7 @@ "name": "blink_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -143,7 +143,7 @@ "name": "cc_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -161,7 +161,7 @@ "name": "components_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -179,7 +179,7 @@ "name": "content_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -197,7 +197,7 @@ "name": "crashpad_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -215,7 +215,7 @@ "name": "cronet_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -233,7 +233,7 @@ "name": "device_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -251,7 +251,7 @@ "name": "net_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/generated/builders/try/mac-ubsan-fyi-rel/gn-args.json b/infra/config/generated/builders/try/mac-ubsan-fyi-rel/gn-args.json index d41fee8..0034980 100644 --- a/infra/config/generated/builders/try/mac-ubsan-fyi-rel/gn-args.json +++ b/infra/config/generated/builders/try/mac-ubsan-fyi-rel/gn-args.json
@@ -5,7 +5,7 @@ "is_debug": false, "is_ubsan": true, "is_ubsan_no_recover": true, - "target_cpu": "x64", + "target_cpu": "arm64", "target_os": "mac", "use_reclient": false, "use_remoteexec": true,
diff --git a/infra/config/generated/builders/try/mac-ubsan-fyi-rel/targets/chromium.memory.fyi.json b/infra/config/generated/builders/try/mac-ubsan-fyi-rel/targets/chromium.memory.fyi.json index f7daab7..2a5ea0e 100644 --- a/infra/config/generated/builders/try/mac-ubsan-fyi-rel/targets/chromium.memory.fyi.json +++ b/infra/config/generated/builders/try/mac-ubsan-fyi-rel/targets/chromium.memory.fyi.json
@@ -11,7 +11,7 @@ "name": "absl_hardening_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -29,7 +29,7 @@ "name": "accessibility_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -47,7 +47,7 @@ "name": "angle_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -66,7 +66,7 @@ "name": "app_shell_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -84,7 +84,7 @@ "name": "base_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -102,7 +102,7 @@ "name": "blink_common_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -120,7 +120,7 @@ "name": "blink_fuzzer_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -138,7 +138,7 @@ "name": "blink_heap_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -162,7 +162,7 @@ ], "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -180,7 +180,7 @@ "name": "boringssl_crypto_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -198,7 +198,7 @@ "name": "boringssl_ssl_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -216,7 +216,7 @@ "name": "browser_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -236,7 +236,7 @@ "name": "capture_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -254,7 +254,7 @@ "name": "cast_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -272,7 +272,7 @@ "name": "cc_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -290,7 +290,7 @@ "name": "chrome_app_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -308,7 +308,7 @@ "name": "chromedriver_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -326,7 +326,7 @@ "name": "components_browsertests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -344,7 +344,7 @@ "name": "components_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -363,7 +363,7 @@ "name": "content_browsertests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -382,7 +382,7 @@ "name": "content_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -400,7 +400,7 @@ "name": "crashpad_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -418,7 +418,7 @@ "name": "cronet_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -436,7 +436,7 @@ "name": "cronet_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -454,7 +454,7 @@ "name": "crypto_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -472,7 +472,7 @@ "name": "device_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -490,7 +490,7 @@ "name": "display_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -509,7 +509,7 @@ "name": "env_chromium_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -527,7 +527,7 @@ "name": "events_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -545,7 +545,7 @@ "name": "extensions_browsertests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -563,7 +563,7 @@ "name": "extensions_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -581,7 +581,7 @@ "name": "filesystem_service_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -599,7 +599,7 @@ "name": "fuzzing_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -617,7 +617,7 @@ "name": "gcm_unit_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -635,7 +635,7 @@ "name": "gfx_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -653,7 +653,7 @@ "name": "gin_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -671,7 +671,7 @@ "name": "google_apis_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -689,7 +689,7 @@ "name": "gpu_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -707,7 +707,7 @@ "name": "gwp_asan_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -725,7 +725,7 @@ "name": "headless_browsertests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -743,7 +743,7 @@ "name": "headless_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -761,7 +761,7 @@ "name": "interactive_ui_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -780,7 +780,7 @@ "name": "ipc_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -798,7 +798,7 @@ "name": "latency_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -817,7 +817,7 @@ "name": "leveldb_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -835,7 +835,7 @@ "name": "libjingle_xmpp_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -853,7 +853,7 @@ "name": "liburlpattern_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -871,7 +871,7 @@ "name": "media_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -889,7 +889,7 @@ "name": "message_center_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -907,7 +907,7 @@ "name": "midi_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -925,7 +925,7 @@ "name": "mojo_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -943,7 +943,7 @@ "name": "native_theme_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -961,7 +961,7 @@ "name": "net_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -979,7 +979,7 @@ "name": "openscreen_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -997,7 +997,7 @@ "name": "pdf_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1015,7 +1015,7 @@ "name": "perfetto_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1033,7 +1033,7 @@ "name": "power_sampler_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1051,7 +1051,7 @@ "name": "printing_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1069,7 +1069,7 @@ "name": "remoting_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1087,7 +1087,7 @@ "name": "sandbox_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1105,7 +1105,7 @@ "name": "services_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1123,7 +1123,7 @@ "name": "shell_dialogs_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1141,7 +1141,7 @@ "name": "skia_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1159,7 +1159,7 @@ "name": "snapshot_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1177,7 +1177,7 @@ "name": "sql_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1195,7 +1195,7 @@ "name": "storage_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1213,7 +1213,7 @@ "name": "sync_integration_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -1232,7 +1232,7 @@ "name": "ui_base_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1250,7 +1250,7 @@ "name": "ui_touch_selection_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1268,7 +1268,7 @@ "name": "ui_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1286,7 +1286,7 @@ "name": "unit_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1304,7 +1304,7 @@ "name": "updater_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1322,7 +1322,7 @@ "name": "url_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1340,7 +1340,7 @@ "name": "views_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1358,7 +1358,7 @@ "name": "viz_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1376,7 +1376,7 @@ "name": "webkit_unit_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1394,7 +1394,7 @@ "name": "wtf_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1412,7 +1412,7 @@ "name": "xr_browser_tests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -1430,7 +1430,7 @@ "name": "zlib_unittests", "swarming": { "dimensions": { - "cpu": "x86-64", + "cpu": "arm64", "os": "Mac-14" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/generated/cq-usage/mega_cq_bots.txt b/infra/config/generated/cq-usage/mega_cq_bots.txt index a08d46f..fbc32209 100644 --- a/infra/config/generated/cq-usage/mega_cq_bots.txt +++ b/infra/config/generated/cq-usage/mega_cq_bots.txt
@@ -10,7 +10,6 @@ chromium/try/android-14-tablet-landscape-arm64-rel chromium/try/android-15-x64-rel chromium/try/android-arm-compile-dbg -chromium/try/android-arm64-all-targets-dbg chromium/try/android-arm64-rel chromium/try/android-bfcache-rel chromium/try/android-cast-arm-dbg
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 6ed18c7..14ae6e7 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -943,11 +943,6 @@ disable_reuse_footers: "Include-Ci-Only-Tests" } builders { - name: "chromium/try/android-arm64-all-targets-dbg" - includable_only: true - disable_reuse_footers: "Include-Ci-Only-Tests" - } - builders { name: "chromium/try/android-arm64-rel" disable_reuse_footers: "Include-Ci-Only-Tests" location_filters {
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 30b76ca..265e68b 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -4612,7 +4612,7 @@ use_invocation_timestamp: true } } - description_html: "This builder is mirrored by any of the following try builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/try/android-arm64-all-targets-dbg\">android-arm64-all-targets-dbg</a></li><li><a href=\"https://ci.chromium.org/p/chromium/builders/try/android_compile_dbg\">android_compile_dbg</a></li></ul><br/>Builder owner: <a href=mailto:clank-engprod@google.com>clank-engprod@google.com</a>" + description_html: "This builder is mirrored by any of the following try builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/try/android_compile_dbg\">android_compile_dbg</a></li></ul><br/>Builder owner: <a href=mailto:clank-engprod@google.com>clank-engprod@google.com</a>" shadow_builder_adjustments { service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" pool: "luci.chromium.try" @@ -82686,117 +82686,6 @@ } } builders { - name: "android-arm64-all-targets-dbg" - swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "free_space:standard" - dimensions: "os:Ubuntu-22.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/chromium/bootstrapper/${platform}" - cipd_version: "latest" - cmd: "bootstrapper" - } - properties: - '{' - ' "$bootstrap/exe": {' - ' "exe": {' - ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' - ' "cipd_version": "refs/heads/main",' - ' "cmd": [' - ' "luciexe"' - ' ]' - ' }' - ' },' - ' "$bootstrap/properties": {' - ' "properties_file": "infra/config/generated/builders/try/android-arm64-all-targets-dbg/properties.json",' - ' "top_level_project": {' - ' "ref": "refs/heads/main",' - ' "repo": {' - ' "host": "chromium.googlesource.com",' - ' "project": "chromium/src"' - ' }' - ' }' - ' },' - ' "builder_group": "tryserver.chromium.android",' - ' "led_builder_is_bootstrapped": true,' - ' "recipe": "chromium_trybot"' - '}' - execution_timeout_secs: 28800 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.use_per_builder_build_dir_name" - value: 100 - } - experiments { - key: "luci.buildbucket.canary_software" - value: 5 - } - experiments { - key: "luci.recipes.use_python3" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome|content)/test:telemetry_gpu_integration_test[^/]*/.+" - } - } - } - bq_exports { - project: "chrome-luci-data" - dataset: "chromium" - table: "blink_web_tests_try_test_results" - test_results { - predicate { - test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)|(ninja://[^/]*headless_shell_wpt/.+)" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - description_html: "This builder mirrors the following CI builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/ci/Android arm64 Builder All Targets (dbg)\">Android arm64 Builder All Targets (dbg)</a></li></ul>" - custom_metric_definitions { - name: "/chrome/infra/browser/builds/cached_count" - predicates: "has(build.output.properties.is_cached)" - predicates: "string(build.output.properties.is_cached) == \"true\"" - } - custom_metric_definitions { - name: "/chrome/infra/browser/builds/ran_tests_retry_shard_count" - predicates: "has(build.output.properties.ran_tests_retry_shard)" - } - custom_metric_definitions { - name: "/chrome/infra/browser/builds/ran_tests_without_patch_count" - predicates: "has(build.output.properties.ran_tests_without_patch)" - } - custom_metric_definitions { - name: "/chrome/infra/browser/builds/uncached_count" - predicates: "has(build.output.properties.is_cached)" - predicates: "string(build.output.properties.is_cached) == \"false\"" - } - } - builders { name: "android-arm64-rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:android-arm64-rel"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index 9260468..bb21158 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -26177,9 +26177,6 @@ name: "buildbucket/luci.chromium.try/android-arm-compile-dbg" } builders { - name: "buildbucket/luci.chromium.try/android-arm64-all-targets-dbg" - } - builders { name: "buildbucket/luci.chromium.try/android-arm64-rel" } builders { @@ -27709,9 +27706,6 @@ name: "buildbucket/luci.chromium.try/android-arm-compile-dbg" } builders { - name: "buildbucket/luci.chromium.try/android-arm64-all-targets-dbg" - } - builders { name: "buildbucket/luci.chromium.try/android-arm64-rel" } builders {
diff --git a/infra/config/lib/builder_exemptions.star b/infra/config/lib/builder_exemptions.star index 1460439..4758807 100644 --- a/infra/config/lib/builder_exemptions.star +++ b/infra/config/lib/builder_exemptions.star
@@ -375,7 +375,6 @@ "android-12l-x64-dbg", "android-angle-chromium-try", "android-arm-compile-dbg", - "android-arm64-all-targets-dbg", "android-arm64-rel-compilator", "android-bfcache-rel", "android-binary-size", @@ -815,7 +814,6 @@ "android-12-x64-rel-compilator", "android-12l-x64-dbg", "android-arm-compile-dbg", - "android-arm64-all-targets-dbg", "android-arm64-rel", "android-arm64-rel-compilator", "android-bfcache-rel",
diff --git a/infra/config/subprojects/chromium/ci/chromium.memory.fyi.star b/infra/config/subprojects/chromium/ci/chromium.memory.fyi.star index 4d9ef24..bf859c58 100644 --- a/infra/config/subprojects/chromium/ci/chromium.memory.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.memory.fyi.star
@@ -66,7 +66,7 @@ "release_builder", "remoteexec", "mac", - "x64", + "arm64", ], ), targets = targets.bundle( @@ -79,7 +79,7 @@ "--test-launcher-print-test-stdio=always", ], ), - "mac_default_x64", + "mac_default_arm64", ], ), builderless = 1, @@ -122,7 +122,7 @@ "release_builder", "remoteexec", "mac", - "x64", + "arm64", ], ), targets = targets.bundle( @@ -135,7 +135,7 @@ "--test-launcher-print-test-stdio=always", ], ), - "mac_default_x64", + "mac_default_arm64", ], ), builderless = 1,
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star index 136566a..776ffee 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -1271,25 +1271,6 @@ ) try_.builder( - name = "android-arm64-all-targets-dbg", - mirrors = [ - "ci/Android arm64 Builder All Targets (dbg)", - ], - gn_args = gn_args.config( - configs = [ - "android_builder", - "debug_try_builder", - "enable_android_secondary_abi", - "remoteexec", - "compile_only", - "arm64", - "android_fastbuild", - ], - ), - execution_timeout = 8 * time.hour, -) - -try_.builder( name = "android_blink_rel", builder_spec = builder_config.builder_spec( gclient_config = builder_config.gclient_config(
diff --git a/internal b/internal index ebf59a9..3f05162 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit ebf59a967121173a07b14a2c2b415983f7267b85 +Subproject commit 3f05162719c305d3e7dcf93800c67fa5b4a295ee
diff --git a/ios/chrome/browser/browser_container/ui_bundled/BUILD.gn b/ios/chrome/browser/browser_container/ui_bundled/BUILD.gn index b7e1e10..9c36d2b 100644 --- a/ios/chrome/browser/browser_container/ui_bundled/BUILD.gn +++ b/ios/chrome/browser/browser_container/ui_bundled/BUILD.gn
@@ -37,6 +37,7 @@ "//ios/chrome/browser/shared/model/web_state_list", "//ios/chrome/browser/shared/public/commands", "//ios/chrome/browser/shared/public/features", + "//ios/chrome/browser/signin/model", "//ios/web/public", "//ui/base", "//ui/strings:ui_strings_grit",
diff --git a/ios/chrome/browser/browser_container/ui_bundled/DEPS b/ios/chrome/browser/browser_container/ui_bundled/DEPS index a0f54e2..16b4c551 100644 --- a/ios/chrome/browser/browser_container/ui_bundled/DEPS +++ b/ios/chrome/browser/browser_container/ui_bundled/DEPS
@@ -10,5 +10,6 @@ "+ios/chrome/browser/screen_time/model", "+ios/chrome/browser/screen_time/ui_bundled/screen_time_coordinator.h", "+ios/chrome/browser/search_engines/model/template_url_service_factory.h", - "+ios/chrome/browser/intelligence/features/features.h" + "+ios/chrome/browser/intelligence/features/features.h", + "+ios/chrome/browser/signin/model/identity_manager_factory.h" ]
diff --git a/ios/chrome/browser/browser_container/ui_bundled/browser_container_coordinator.mm b/ios/chrome/browser/browser_container/ui_bundled/browser_container_coordinator.mm index 8062f4b1..54e7883 100644 --- a/ios/chrome/browser/browser_container/ui_bundled/browser_container_coordinator.mm +++ b/ios/chrome/browser/browser_container/ui_bundled/browser_container_coordinator.mm
@@ -32,6 +32,7 @@ #import "ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" #import "ios/chrome/browser/shared/public/features/features.h" +#import "ios/chrome/browser/signin/model/identity_manager_factory.h" #import "url/gurl.h" #if BUILDFLAG(IOS_SCREEN_TIME_ENABLED) @@ -135,8 +136,9 @@ if (ExplainGeminiEditMenuPosition() != PositionForExplainGeminiEditMenu::kDisabled && !incognito) { - _explainWithGeminiMediator = - [[ExplainWithGeminiMediator alloc] initWithWebStateList:webStateList]; + _explainWithGeminiMediator = [[ExplainWithGeminiMediator alloc] + initWithWebStateList:webStateList + identityManager:IdentityManagerFactory::GetForProfile(profile)]; _explainWithGeminiMediator.applicationCommandHandler = applicationCommandsHandler;
diff --git a/ios/chrome/browser/explain_with_gemini/coordinator/explain_with_gemini_mediator.h b/ios/chrome/browser/explain_with_gemini/coordinator/explain_with_gemini_mediator.h index 5810a5d..07ae415b 100644 --- a/ios/chrome/browser/explain_with_gemini/coordinator/explain_with_gemini_mediator.h +++ b/ios/chrome/browser/explain_with_gemini/coordinator/explain_with_gemini_mediator.h
@@ -7,6 +7,7 @@ #import <UIKit/UIKit.h> +#import "components/signin/public/identity_manager/identity_manager.h" #import "ios/chrome/browser/explain_with_gemini/coordinator/explain_with_gemini_delegate.h" @protocol ApplicationCommands; @@ -23,6 +24,7 @@ // Initializer for a mediator. `webStateList` is the WebStateList for the // BrowserContainer that owns this mediator. - (instancetype)initWithWebStateList:(WebStateList*)webStateList + identityManager:(signin::IdentityManager*)identityManager NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/explain_with_gemini/coordinator/explain_with_gemini_mediator.mm b/ios/chrome/browser/explain_with_gemini/coordinator/explain_with_gemini_mediator.mm index 8f3d6c4..02a4f42 100644 --- a/ios/chrome/browser/explain_with_gemini/coordinator/explain_with_gemini_mediator.mm +++ b/ios/chrome/browser/explain_with_gemini/coordinator/explain_with_gemini_mediator.mm
@@ -10,6 +10,7 @@ #import "base/memory/weak_ptr.h" #import "base/metrics/histogram_functions.h" #import "base/strings/sys_string_conversions.h" +#import "components/signin/public/identity_manager/identity_manager.h" #import "ios/chrome/browser/browser_container/ui_bundled/browser_edit_menu_utils.h" #import "ios/chrome/browser/explain_with_gemini/coordinator/explain_with_gemini_constants.h" #import "ios/chrome/browser/intelligence/features/features.h" @@ -31,12 +32,15 @@ @implementation ExplainWithGeminiMediator { // The Browser's WebStateList. base::WeakPtr<WebStateList> _webStateList; + raw_ptr<signin::IdentityManager> _identityManager; } -- (instancetype)initWithWebStateList:(WebStateList*)webStateList { +- (instancetype)initWithWebStateList:(WebStateList*)webStateList + identityManager:(signin::IdentityManager*)identityManager { if ((self = [super init])) { CHECK(webStateList); _webStateList = webStateList->AsWeakPtr(); + _identityManager = identityManager; } return self; } @@ -57,6 +61,9 @@ // Checks if Explain With Gemini can be performed. - (BOOL)canPerformExplainWithGemini { // TODO(crbug.com/408000561): Only show for some users. + if (![self checkAgeCondition]) { + return NO; + }; CHECK(ExplainGeminiEditMenuPosition() != PositionForExplainGeminiEditMenu::kDisabled); WebSelectionTabHelper* tabHelper = [self webSelectionTabHelper]; @@ -64,6 +71,22 @@ self.applicationCommandHandler; } +// Checks if the user is signIn and is 18+ years old. +- (BOOL)checkAgeCondition { + if (!_identityManager) { + return NO; + } + + AccountCapabilities capabilities = + _identityManager + ->FindExtendedAccountInfo(_identityManager->GetPrimaryAccountInfo( + signin::ConsentLevel::kSignin)) + .capabilities; + + return capabilities.can_use_model_execution_features() == + signin::Tribool::kTrue; +} + // Returns the title of button Explain With Gemini. - (NSString*)buttonTitle { return [NSString
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn index b8a9afc..cb89a4f 100644 --- a/ios/chrome/browser/flags/BUILD.gn +++ b/ios/chrome/browser/flags/BUILD.gn
@@ -26,6 +26,7 @@ "//components/dom_distiller/core", "//components/download/public/background_service:public", "//components/enterprise", + "//components/enterprise/connectors/core", "//components/feature_engagement/public", "//components/feed:feature_list", "//components/history/core/browser",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 272fdbb2..f27cd9c4 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -36,6 +36,7 @@ #import "components/dom_distiller/core/dom_distiller_switches.h" #import "components/download/public/background_service/features.h" #import "components/enterprise/browser/enterprise_switches.h" +#import "components/enterprise/connectors/core/features.h" #import "components/feature_engagement/public/feature_constants.h" #import "components/feature_engagement/public/feature_list.h" #import "components/feed/feed_feature_list.h" @@ -1709,6 +1710,12 @@ {"enable-feed-ablation", flag_descriptions::kEnableFeedAblationName, flag_descriptions::kEnableFeedAblationDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kEnableFeedAblation)}, + {"enterprise-realtime-event-reporting-on-ios", + flag_descriptions::kEnterpriseRealtimeEventReportingOnIOSName, + flag_descriptions::kEnterpriseRealtimeEventReportingOnIOSDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE( + enterprise_connectors::kEnterpriseRealtimeEventReportingOnIOS)}, {"content-suggestions-magic-stack", flag_descriptions::kMagicStackName, flag_descriptions::kMagicStackDescription, flags_ui::kOsIos, FEATURE_WITH_PARAMS_VALUE_TYPE(kMagicStack,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 63249f32b..85f777bf 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -480,6 +480,11 @@ "When enabled, the Enhanced Safe Browsing inline and infobar promos are " "displayed given certain preconditions are met."; +const char kEnterpriseRealtimeEventReportingOnIOSName[] = + "Enable realtime event reporting for Enterprise on iOS"; +const char kEnterpriseRealtimeEventReportingOnIOSDescription[] = + "When enabled, realtime events will be reported to the user's organization"; + const char kFeedBackgroundRefreshName[] = "Enable feed background refresh"; const char kFeedBackgroundRefreshDescription[] = "Schedules a feed background refresh after some minimum period of time has " @@ -576,6 +581,12 @@ extern const char kIOSEnableDeleteAllSavedCredentialsDescription[] = "When enabled, the delete all data button in PWM will be presented."; +extern const char kIOSEnableRealtimeEventReportingName[] = + "Enable realtime event reporting on iOS"; +extern const char kIOSEnableRealtimeEventReportingDescription[] = + "When enabled, realtime events will be reported to the user's " + "organization."; + const char kIOSKeyboardAccessoryUpgradeName[] = "Enable the keyboard accessory upgrade on iOS"; const char kIOSKeyboardAccessoryUpgradeDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index beb0737b..029a632 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -276,6 +276,9 @@ extern const char kEnhancedSafeBrowsingPromoName[]; extern const char kEnhancedSafeBrowsingPromoDescription[]; +extern const char kEnterpriseRealtimeEventReportingOnIOSName[]; +extern const char kEnterpriseRealtimeEventReportingOnIOSDescription[]; + extern const char kFeedBackgroundRefreshName[]; extern const char kFeedBackgroundRefreshDescription[]; @@ -333,6 +336,9 @@ extern const char kIOSEnableDeleteAllSavedCredentialsName[]; extern const char kIOSEnableDeleteAllSavedCredentialsDescription[]; +extern const char kIOSEnableRealtimeEventReportingName[]; +extern const char kIOSEnableRealtimeEventReportingDescription[]; + extern const char kIOSKeyboardAccessoryUpgradeName[]; extern const char kIOSKeyboardAccessoryUpgradeDescription[];
diff --git a/ios/chrome/browser/passwords/model/BUILD.gn b/ios/chrome/browser/passwords/model/BUILD.gn index f2e4efd..1b4990f 100644 --- a/ios/chrome/browser/passwords/model/BUILD.gn +++ b/ios/chrome/browser/passwords/model/BUILD.gn
@@ -56,6 +56,7 @@ "//components/autofill/ios/browser:util", "//components/autofill/ios/form_util", "//components/browser_sync", + "//components/enterprise/connectors/core", "//components/image_fetcher/core", "//components/image_fetcher/ios", "//components/password_manager/core/browser", @@ -82,6 +83,7 @@ "//ios/chrome/browser/affiliations/model", "//ios/chrome/browser/autofill/model:model_shared", "//ios/chrome/browser/autofill/model/bottom_sheet", + "//ios/chrome/browser/enterprise/connectors/reporting", "//ios/chrome/browser/infobars/model", "//ios/chrome/browser/infobars/model:public", "//ios/chrome/browser/infobars/ui_bundled/coordinators",
diff --git a/ios/chrome/browser/passwords/model/DEPS b/ios/chrome/browser/passwords/model/DEPS index 78077298..4b510c4 100644 --- a/ios/chrome/browser/passwords/model/DEPS +++ b/ios/chrome/browser/passwords/model/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "+ios/chrome/browser/affiliations/model", "+ios/chrome/browser/autofill/model", + "+ios/chrome/browser/enterprise/connectors/reporting", "+ios/chrome/browser/infobars/model", "+ios/chrome/browser/optimization_guide/model", "+ios/chrome/browser/safe_browsing/model",
diff --git a/ios/chrome/browser/passwords/model/ios_chrome_password_manager_client.h b/ios/chrome/browser/passwords/model/ios_chrome_password_manager_client.h index 1b1e32db..694267a 100644 --- a/ios/chrome/browser/passwords/model/ios_chrome_password_manager_client.h +++ b/ios/chrome/browser/passwords/model/ios_chrome_password_manager_client.h
@@ -120,6 +120,9 @@ std::unique_ptr<password_manager::PasswordFormManagerForUI> submitted_manager) override; bool IsPasswordChangeOngoing() override; + void MaybeReportEnterprisePasswordBreachEvent( + const std::vector<std::pair<GURL, std::u16string>>& identities) + const override; void NotifyStorePasswordCalled() override; void NotifyUserCredentialsWereLeaked( password_manager::LeakedPasswordDetails details) override;
diff --git a/ios/chrome/browser/passwords/model/ios_chrome_password_manager_client.mm b/ios/chrome/browser/passwords/model/ios_chrome_password_manager_client.mm index 14d07d2..d931cd8 100644 --- a/ios/chrome/browser/passwords/model/ios_chrome_password_manager_client.mm +++ b/ios/chrome/browser/passwords/model/ios_chrome_password_manager_client.mm
@@ -16,6 +16,8 @@ #import "components/autofill/core/browser/logging/log_manager.h" #import "components/autofill/core/browser/logging/log_router.h" #import "components/autofill/ios/browser/autofill_client_ios.h" +#import "components/enterprise/connectors/core/features.h" +#import "components/enterprise/connectors/core/reporting_event_router.h" #import "components/keyed_service/core/service_access_type.h" #import "components/password_manager/core/browser/password_form.h" #import "components/password_manager/core/browser/password_form_manager_for_ui.h" @@ -29,6 +31,7 @@ #import "components/sync/service/sync_service.h" #import "components/translate/core/browser/translate_manager.h" #import "components/ukm/ios/ukm_url_recorder.h" +#import "ios/chrome/browser/enterprise/connectors/reporting/ios_reporting_event_router_factory.h" #import "ios/chrome/browser/passwords/model/features.h" #import "ios/chrome/browser/passwords/model/ios_chrome_account_password_store_factory.h" #import "ios/chrome/browser/passwords/model/ios_chrome_password_reuse_manager_factory.h" @@ -57,6 +60,13 @@ using password_manager::PasswordStoreInterface; using password_manager::metrics_util::PasswordType; +namespace { + +// The check was triggered by the user entering a password on a webpage. +inline constexpr char kPasswordBreachEntryTrigger[] = "PASSWORD_ENTRY"; + +} // namespace + IOSChromePasswordManagerClient::IOSChromePasswordManagerClient( id<IOSChromePasswordManagerClientBridge> bridge) : bridge_(bridge), @@ -222,6 +232,27 @@ return false; } +// TODO(crbug.com/409047852): Add unit test to confirm the event trigger. +void IOSChromePasswordManagerClient::MaybeReportEnterprisePasswordBreachEvent( + const std::vector<std::pair<GURL, std::u16string>>& identities) const { + // Guard the realtime event reporting feature on iOS behind the feature flag. + if (!base::FeatureList::IsEnabled( + enterprise_connectors::kEnterpriseRealtimeEventReportingOnIOS)) { + return; + } + + enterprise_connectors::ReportingEventRouter* router = + enterprise_connectors::IOSReportingEventRouterFactory::GetForProfile( + bridge_.profile); + if (!router) { + return; + } + + // The router is responsible for checking if the reporting of this event type + // is enabled by the admin. + router->OnPasswordBreach(kPasswordBreachEntryTrigger, identities); +} + void IOSChromePasswordManagerClient::NotifyStorePasswordCalled() { helper_.NotifyStorePasswordCalled(); }
diff --git a/ios/chrome/browser/policy/model/reporting/report_scheduler_ios.h b/ios/chrome/browser/policy/model/reporting/report_scheduler_ios.h index e1ecc30b..5ab8ada 100644 --- a/ios/chrome/browser/policy/model/reporting/report_scheduler_ios.h +++ b/ios/chrome/browser/policy/model/reporting/report_scheduler_ios.h
@@ -20,10 +20,14 @@ // ReportScheduler::Delegate implementation. PrefService* GetPrefService() override; + void OnInitializationCompleted() override; void StartWatchingUpdatesIfNeeded(base::Time last_upload, base::TimeDelta upload_interval) override; void StopWatchingUpdates() override; void OnBrowserVersionUploaded() override; + bool AreSecurityReportsEnabled() override; + bool UseCookiesInUploads() override; + void OnSecuritySignalsUploaded() override; policy::DMToken GetProfileDMToken() override; std::string GetProfileClientId() override; };
diff --git a/ios/chrome/browser/policy/model/reporting/report_scheduler_ios.mm b/ios/chrome/browser/policy/model/reporting/report_scheduler_ios.mm index 840a86f..a1215e3 100644 --- a/ios/chrome/browser/policy/model/reporting/report_scheduler_ios.mm +++ b/ios/chrome/browser/policy/model/reporting/report_scheduler_ios.mm
@@ -16,6 +16,10 @@ return GetApplicationContext()->GetLocalState(); } +void ReportSchedulerIOS::OnInitializationCompleted() { + // No-op. +} + void ReportSchedulerIOS::StartWatchingUpdatesIfNeeded( base::Time last_upload, base::TimeDelta upload_interval) { @@ -30,6 +34,20 @@ // Not used on iOS because there is no in-app auto-update. } +bool ReportSchedulerIOS::AreSecurityReportsEnabled() { + // Not supported. + return false; +} + +bool ReportSchedulerIOS::UseCookiesInUploads() { + // Not supported. + return false; +} + +void ReportSchedulerIOS::OnSecuritySignalsUploaded() { + // No-op because signals reporting is not supported on Android. +} + policy::DMToken ReportSchedulerIOS::GetProfileDMToken() { // Profile reporting is not supported. return policy::DMToken::CreateEmptyToken();
diff --git a/ios/chrome/browser/policy/model/user_policy_egtest.mm b/ios/chrome/browser/policy/model/user_policy_egtest.mm index c50b4d6..120ea0e 100644 --- a/ios/chrome/browser/policy/model/user_policy_egtest.mm +++ b/ios/chrome/browser/policy/model/user_policy_egtest.mm
@@ -558,6 +558,23 @@ [SigninEarlGrey verifySignedInWithFakeIdentity:fakeManagedIdentity]; } +// Tests the chrome://policy page when there are user level policies. +- (void)testPolicyPageManagedWithUserPolicy { + // Sign in with a managed account. + FakeSystemIdentity* fakeManagedIdentity = [FakeSystemIdentity + identityWithEmail:base::SysUTF8ToNSString(GetTestEmail())]; + [SigninEarlGreyUI signinWithFakeIdentity:fakeManagedIdentity]; + VerifyThatPoliciesAreSet(); + + // Open the policy page and check if there is a user management status box. + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyURL)]; + [ChromeEarlGrey waitForWebStateContainingText:l10n_util::GetStringUTF8( + IDS_POLICY_STATUS_USER)]; + [ChromeEarlGrey waitForWebStateContainingText:l10n_util::GetStringUTF8( + IDS_POLICY_LABEL_USERNAME)]; + [ChromeEarlGrey waitForWebStateContainingText:GetTestEmail()]; +} + #pragma mark - Private // Starts the sign-in flow up to the point where it may ask for the confirmation
diff --git a/ios/chrome/browser/shared/model/url/chrome_url_constants.cc b/ios/chrome/browser/shared/model/url/chrome_url_constants.cc index d2ce289..93d94dbb 100644 --- a/ios/chrome/browser/shared/model/url/chrome_url_constants.cc +++ b/ios/chrome/browser/shared/model/url/chrome_url_constants.cc
@@ -27,6 +27,8 @@ const char kChromeUIOnDeviceLlmInternalsURL[] = "chrome://on-device-llm-internals/"; const char kChromeUIPolicyURL[] = "chrome://policy/"; +const char kChromeUIPolicyLogsURL[] = "chrome://policy/logs"; +const char kChromeUIPolicyTestURL[] = "chrome://policy/test"; const char kChromeUISettingsURL[] = "chrome://settings/"; const char kChromeUITermsURL[] = "chrome://terms/"; const char kChromeUIVersionURL[] = "chrome://version/";
diff --git a/ios/chrome/browser/shared/model/url/chrome_url_constants.h b/ios/chrome/browser/shared/model/url/chrome_url_constants.h index f89905f..afe0cd48 100644 --- a/ios/chrome/browser/shared/model/url/chrome_url_constants.h +++ b/ios/chrome/browser/shared/model/url/chrome_url_constants.h
@@ -24,6 +24,8 @@ extern const char kChromeUINewTabURL[]; extern const char kChromeUINTPTilesInternalsURL[]; extern const char kChromeUIOfflineURL[]; +extern const char kChromeUIPolicyLogsURL[]; +extern const char kChromeUIPolicyTestURL[]; extern const char kChromeUIPolicyURL[]; extern const char kChromeUIPopularSitesInternalsURL[]; extern const char kChromeUISettingsURL[];
diff --git a/ios/chrome/browser/shared/public/features/features.mm b/ios/chrome/browser/shared/public/features/features.mm index a68fe480..1e6c1bf 100644 --- a/ios/chrome/browser/shared/public/features/features.mm +++ b/ios/chrome/browser/shared/public/features/features.mm
@@ -41,7 +41,7 @@ } BASE_FEATURE(kIOSKeyboardAccessoryUpgradeForIPad, - "kIOSKeyboardAccessoryUpgradeForIPad", + "IOSKeyboardAccessoryUpgradeForIPad", base::FEATURE_DISABLED_BY_DEFAULT); BASE_FEATURE(kIOSKeyboardAccessoryUpgradeShortManualFillMenu,
diff --git a/ios/chrome/browser/webui/ui_bundled/BUILD.gn b/ios/chrome/browser/webui/ui_bundled/BUILD.gn index c8d325b..8c015f9c 100644 --- a/ios/chrome/browser/webui/ui_bundled/BUILD.gn +++ b/ios/chrome/browser/webui/ui_bundled/BUILD.gn
@@ -193,20 +193,30 @@ testonly = true sources = [ "inspect/inspect_ui_egtest.mm", + "policy/policy_egtest.mm", "web_ui_egtest.mm", ] deps = [ ":eg_test_support+eg2", "//base", "//base/test:test_support", + "//components/enterprise:enterprise", + "//components/policy/core/common:test_support", + "//components/policy/resources/webui:resources", + "//components/policy/test_support", "//components/strings", "//components/version_info", "//ios/chrome/app/strings", + "//ios/chrome/browser/authentication/ui_bundled:eg_test_support+eg2", + "//ios/chrome/browser/policy/model:eg_test_support+eg2", "//ios/chrome/browser/shared/model/url:constants", + "//ios/chrome/browser/signin/model:fake_system_identity", "//ios/chrome/common", "//ios/chrome/test/earl_grey:eg_test_support+eg2", + "//ios/chrome/test/earl_grey:switches", "//ios/components/webui:url_constants", "//ios/testing/earl_grey:eg_test_support+eg2", + "//ios/testing/earl_grey:launch_configuration", "//ios/web/public/test:element_selector", "//net:test_support", "//ui/base",
diff --git a/ios/chrome/browser/webui/ui_bundled/DEPS b/ios/chrome/browser/webui/ui_bundled/DEPS index 61d148d1..c7ba301 100644 --- a/ios/chrome/browser/webui/ui_bundled/DEPS +++ b/ios/chrome/browser/webui/ui_bundled/DEPS
@@ -33,3 +33,9 @@ "+ios/chrome/browser/policy/ui_bundled/user_policy_util.h", "+ios/chrome/browser/web/model/java_script_console", ] + +specific_include_rules = { + "^policy_egtest.mm": [ + "+components/policy/test_support", + ], +}
diff --git a/ios/chrome/browser/webui/ui_bundled/policy/policy_egtest.mm b/ios/chrome/browser/webui/ui_bundled/policy/policy_egtest.mm new file mode 100644 index 0000000..272a4c7 --- /dev/null +++ b/ios/chrome/browser/webui/ui_bundled/policy/policy_egtest.mm
@@ -0,0 +1,322 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <Foundation/Foundation.h> +#import <XCTest/XCTest.h> + +#import "base/json/json_reader.h" +#import "base/strings/stringprintf.h" +#import "base/strings/sys_string_conversions.h" +#import "base/strings/utf_string_conversions.cc" +#import "base/system/sys_info.h" +#import "base/test/ios/wait_util.h" +#import "base/version_info/version_info.h" +#import "components/enterprise/browser/enterprise_switches.h" +#import "components/grit/policy_resources.h" +#import "components/grit/policy_resources_map.h" +#import "components/policy/test_support/embedded_policy_test_server.h" +#import "components/strings/grit/components_branded_strings.h" +#import "components/strings/grit/components_strings.h" +#import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey.h" +#import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_ui_test_util.h" +#import "ios/chrome/browser/policy/model/policy_earl_grey_utils.h" +#import "ios/chrome/browser/shared/model/url/chrome_url_constants.h" +#import "ios/chrome/browser/signin/model/fake_system_identity.h" +#import "ios/chrome/grit/ios_strings.h" +#import "ios/chrome/test/earl_grey/chrome_actions.h" +#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/testing/earl_grey/app_launch_configuration.h" +#import "ios/testing/earl_grey/app_launch_manager.h" +#import "ios/testing/earl_grey/earl_grey_test.h" +#import "ios/web/public/test/element_selector.h" +#import "ui/base/l10n/l10n_util.h" + +namespace { +// Ids of elements in chrome://policy +NSString* const kReloadPoliciesButton = @"reload-policies"; +NSString* const kExportPoliciesButton = @"export-policies"; +NSString* const kViewLogsButton = @"view-logs"; +NSString* const kMoreActionsButton = @"more-actions-button"; + +// Ids of elements in chrome://policy/logs +NSString* const kRefreshLogsButton = @"logs-refresh"; +NSString* const kExportLogsButton = @"logs-dump"; + +// Ids of elements in chrome://policy/test +NSString* const kApplyPoliciesButton = @"apply-policies"; + +std::vector<std::string> PopulateExpectedPolicy(const std::string& name, + const std::string& value) { + std::vector<std::string> expected_policy; + + // Populate expected policy column and row fields. + expected_policy.push_back(name); + expected_policy.push_back(value); + expected_policy.push_back("Platform"); + expected_policy.push_back("Machine"); + expected_policy.push_back("Mandatory"); + expected_policy.push_back("OK"); + + return expected_policy; +} + +void VerifyPolicies( + const std::vector<std::vector<std::string>>& expected_policies) { + // Retrieve the text contents of the policy table cells for all policies. + NSString* javascript = @"var entries = getAllPolicyTables();" + "var policies = [];" + "for (var i = 0; i < entries.length; ++i) {" + " var items = getAllPolicyRows(entries[i]);" + " for (var j = 0; j < items.length; ++j) {" + " var children = getAllPolicyRowDivs(items[j]);" + " var values = [];" + " for(var k = 0; k < children.length - 1; ++k) {" + " values.push(children[k].textContent.trim());" + " }" + " policies.push(values);" + " }" + "}" + "JSON.stringify(policies);"; + + base::Value policies = [ChromeEarlGrey evaluateJavaScript:javascript]; + std::optional<base::Value> value_ptr = + base::JSONReader::Read(policies.GetString()); + GREYAssertTrue(value_ptr, @"Expected policies, but there weren't any."); + GREYAssertTrue(value_ptr->is_list(), @"Value is not a list."); + const base::Value::List& actual_policies = value_ptr->GetList(); + + // Verify that the cells contain the expected strings for all policies. + for (size_t i = 0; i < expected_policies.size(); ++i) { + const std::vector<std::string> expected_policy = expected_policies[i]; + const base::Value::List& actual_policy = actual_policies[i].GetList(); + GREYAssertEqual(expected_policy.size(), actual_policy.size(), + @"Number of fields in the actual and expected policy row " + @"did not match."); + for (size_t j = 0; j < expected_policy.size(); ++j) { + const std::string* value = actual_policy[j].GetIfString(); + GREYAssertTrue(value, [NSString stringWithUTF8String:value->c_str()]); + if (expected_policy[j] != *value) { + GREYAssertEqual(expected_policy[j], *value, + [NSString stringWithUTF8String:value->c_str()]); + } + } + } +} + +ElementSelector* ReloadPoliciesButton() { + return [ElementSelector + selectorWithElementID:base::SysNSStringToUTF8(kReloadPoliciesButton)]; +} + +ElementSelector* RefreshLogsButton() { + return [ElementSelector + selectorWithElementID:base::SysNSStringToUTF8(kRefreshLogsButton)]; +} + +ElementSelector* ApplyPoliciesButton() { + return [ElementSelector + selectorWithElementID:base::SysNSStringToUTF8(kApplyPoliciesButton)]; +} + +// Matcher for "Download" button on Download Manager UI. +id<GREYMatcher> DownloadButton() { + return grey_accessibilityID( + @"kDownloadManagerDownloadAccessibilityIdentifier"); +} + +// Waits until Download button is shown. +[[nodiscard]] bool WaitForDownloadButton() { + return base::test::ios::WaitUntilConditionOrTimeout( + base::test::ios::kWaitForPageLoadTimeout, ^{ + NSError* error = nil; + [[EarlGrey selectElementWithMatcher:DownloadButton()] + assertWithMatcher:grey_interactable() + error:&error]; + return (error == nil); + }); +} + +// Waits until Open in... button is shown on file download. +[[nodiscard]] bool WaitForOpenInButton() { + // These downloads usually take longer and need a longer timeout. + constexpr base::TimeDelta kLongDownloadTimeout = base::Minutes(1); + return base::test::ios::WaitUntilConditionOrTimeout(kLongDownloadTimeout, ^{ + NSError* error = nil; + [[EarlGrey selectElementWithMatcher:chrome_test_util::OpenInButton()] + assertWithMatcher:grey_interactable() + error:&error]; + return (error == nil); + }); +} + +} // namespace + +// Test case for chrome://policy WebUI pages. +@interface PolicyUITestCase : ChromeTestCase +@end + +@implementation PolicyUITestCase + +- (void)setUp { + [super setUp]; + GREYAssertTrue(self.testServer->Start(), @"Server did not start."); +} + +- (AppLaunchConfiguration)appConfigurationForTestCase { + AppLaunchConfiguration config; + if ([self isRunningTest:@selector(testPolicyTestPageLoadsCorrectly)]) { + // Assign the test environment to be on the Canary channel. This ensures + // the test does not run in a stable channel because chrome://policy/test + // can only be accessed in non-stable channels. + config.additional_args = {"--fake-variations-channel=canary"}; + } + return config; +} + +// ----------------------------------------------------------------------------- +// Policy Pages Load +// ----------------------------------------------------------------------------- + +// Tests that chrome://policy loads correctly in both regular and incognito tabs +- (void)testPolicyPageLoadsCorrectly { + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyURL)]; + [ChromeEarlGrey waitForWebStateContainingElement:ReloadPoliciesButton()]; + [ChromeEarlGrey tapWebStateElementWithID:kReloadPoliciesButton]; + + // Open in new incognito tab. + [ChromeEarlGrey openNewIncognitoTab]; + [ChromeEarlGrey waitForIncognitoTabCount:1]; + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyURL)]; + [ChromeEarlGrey waitForWebStateContainingElement:ReloadPoliciesButton()]; +} + +// Tests that chrome://policy/logs in both regular and incognito tabs +- (void)testPolicyLogsPageLoadsCorrectly { + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyLogsURL)]; + [ChromeEarlGrey waitForWebStateContainingElement:RefreshLogsButton()]; + [ChromeEarlGrey tapWebStateElementWithID:kRefreshLogsButton]; + + // Open in new incognito tab. + [ChromeEarlGrey openNewIncognitoTab]; + [ChromeEarlGrey waitForIncognitoTabCount:1]; + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyLogsURL)]; + [ChromeEarlGrey waitForWebStateContainingElement:RefreshLogsButton()]; +} + +// Tests that chrome://policy/test +- (void)testPolicyTestPageLoadsCorrectly { + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyTestURL)]; + [ChromeEarlGrey waitForWebStateContainingElement:ApplyPoliciesButton()]; + [ChromeEarlGrey tapWebStateElementWithID:kApplyPoliciesButton]; + + // Open in new incognito tab. + [ChromeEarlGrey openNewIncognitoTab]; + [ChromeEarlGrey waitForIncognitoTabCount:1]; + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyTestURL)]; + [ChromeEarlGrey waitForWebStateContainingElement:ApplyPoliciesButton()]; +} + +// ----------------------------------------------------------------------------- +// Tests for chrome://policy page +// ----------------------------------------------------------------------------- + +// Tests the chrome://policy page when no policies are set. +- (void)testPolicyPageUnmanaged { + // Open the policy page and check if the content is expected. + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyURL)]; + [ChromeEarlGrey + waitForWebStateContainingText:l10n_util::GetStringUTF8( + IDS_POLICY_NO_POLICIES_SET)]; +} + +// Tests the chrome://policy page when there are machine level policies. +- (void)testPolicyPageManagedWithCBCM { + // Fake browser enrollment with an enrollment token that will start chrome + // browser cloud management without making network calls. + AppLaunchConfiguration config; + config.additional_args.push_back( + base::StrCat({"--", switches::kEnableChromeBrowserCloudManagement})); + config.additional_args.push_back("-com.apple.configuration.managed"); + + config.additional_args.push_back( + base::StrCat({"<dict><key>CloudManagementEnrollmentToken</key><string>", + policy::kInvalidEnrollmentToken, "</string></dict>"})); + [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config]; + + // Open the policy page and check that the enrollment token is shown. + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyURL)]; + [ChromeEarlGrey waitForWebStateContainingText:l10n_util::GetStringUTF8( + IDS_POLICY_STATUS_DEVICE)]; + [ChromeEarlGrey + waitForWebStateContainingText: + l10n_util::GetStringUTF8(IDS_POLICY_LABEL_MACHINE_ENROLLMENT_TOKEN)]; +} + +// Tests the chrome://policy page when there are policies set. +- (void)testPoliciesShowOnPage { + // Set policies + policy_test_utils::MergePolicy(false, "AutofillCreditCardEnabled"); + policy_test_utils::MergePolicy(1, "IncognitoModeAvailability"); + + // Navigate to chrome://policy. + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyURL)]; + + // Verify that the policy set is shown on the page. + std::vector<std::vector<std::string>> expected_policies; + expected_policies.push_back( + PopulateExpectedPolicy("AutofillCreditCardEnabled", "false")); + expected_policies.push_back( + PopulateExpectedPolicy("IncognitoModeAvailability", "1")); + VerifyPolicies(expected_policies); +} + +// Tests that the "View Logs" button successfully redirects to +// chrome://policy/logs. +- (void)testViewLogsRedirectsToLogsPage { + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyURL)]; + // Click the dropdown and wait until the button shows. + [ChromeEarlGrey tapWebStateElementWithID:kMoreActionsButton]; + // Click "View Logs" + [ChromeEarlGrey tapWebStateElementWithID:kViewLogsButton]; + // Verify that the logs page is opened. + [ChromeEarlGrey waitForWebStateContainingElement:RefreshLogsButton()]; +} + +// ----------------------------------------------------------------------------- +// Tests for chrome://policy/logs page +// ----------------------------------------------------------------------------- + +// Tests that the export button successfully downloads a file. +- (void)testExportLogsToJson { + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyLogsURL)]; + // Click "Export Logs to JSON" button + [ChromeEarlGrey tapWebStateElementWithID:kExportLogsButton]; + // Verify the download button at the bottom shows. + GREYAssert(WaitForDownloadButton(), @"Download button did not show up"); + [[EarlGrey selectElementWithMatcher:DownloadButton()] + performAction:grey_tap()]; + GREYAssert(WaitForOpenInButton(), @"Open in... button did not show up"); +} + +// Tests that the version information displayed is correct. +- (void)testVersionInformationIsCorrect { + [ChromeEarlGrey loadURL:GURL(kChromeUIPolicyLogsURL)]; + // Verify that app versionis present on the page. + const std::string version(version_info::GetVersionNumber()); + const std::string last_change(version_info::GetLastChange()); + + [ChromeEarlGrey waitForWebStateContainingText:version]; + [ChromeEarlGrey waitForWebStateContainingText:last_change]; + [ChromeEarlGrey waitForWebStateContainingText:"iOS"]; +} + +// ----------------------------------------------------------------------------- +// Tests for chrome://policy/test +// ----------------------------------------------------------------------------- +// TODO(crbug.com/346527212: Test chrome://policy/test buttons. + +@end
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 index cecf25da..db6f747 100644 --- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -2c84f015f1f9e1ce578c57fb3180e651838f73d9 \ No newline at end of file +1df063c53d3657a2b2110684183e56d02b6c7d98 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 index 70537abce..9038751 100644 --- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -56d4b6a8c52306acdae3ce4b0223fb0ee797d962 \ No newline at end of file +fb621f01cdac9baa453e10c944bca56ebf853484 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 index 5b8e531..5cae885 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -09b3174936cac067341caa49117fe018216f4e94 \ No newline at end of file +4fe9a6ac3079ccd871fa953f6de5e2827ed83fa8 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 index 2e0d97b..29c7d0ba 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -dd79cf3251e8d0f0b06f7f2568f28535d490e6e5 \ No newline at end of file +3470de930665aa2293303d43c3253190084f4c9e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 index 6864b4f..3501a5e 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -06467b011eaa3b70be6c3cab9e09e86097d06a10 \ No newline at end of file +cb5575edbf8de51802df05abe3ec3aa2b3fc6e91 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 index c00e7d0..f3892cc 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -ec1ae3b83c8b09ef9fceff7c0b6a351c59ebe892 \ No newline at end of file +d02a2324ec4fc3dc20ec655731fa8a04b83c1803 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 index f6aae60c..01f0eca 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -57eddce020e3f4dbd37a5cefc1696b61350998ee \ No newline at end of file +d63d051e7a8b85e885216106f9c5ba051772fb12 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 index 870756b..01b2e65 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -f778adc5feef0cda7aec007b7e9eb8b70b625604 \ No newline at end of file +12232483b1bf4e73c55ed5a2aac1504a512f3f07 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 index 742553bd..0c07710 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -9b8e28a90f9050ef2dc3f69449a6e71195828cf7 \ No newline at end of file +ff1ce51492661a565cb81bc5c72a8a3aa8201a0f \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 555847ec..cc53a7a 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -aa8e822013558facc4d19f1c273da892153ebb39 \ No newline at end of file +8d26142a10f353114b976581a93f5d9d06294fc3 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index e49c9d6..63386ec4 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -d6c16051a833e72f7f3b85238b9a295ce7280b19 \ No newline at end of file +d1a398ad8954fa0c9c3bee83a477789a2fab9e4c \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 index d3f5d507..73426ab 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -4a8ccd0262c92a598cb0ef846da2381235af52fa \ No newline at end of file +2a4153c6c053256dc022f2ffe433e945579e226a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index d816fd6d..c68380ea 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -2ae0ad0d4cc75e7af2c3637b61339579c569d81f \ No newline at end of file +905826404b3379f6c0a2264a2ecc57500c17a673 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 index e53b638..285b9a4 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -ffa62dd036f8be49731e952ff2b5d136dc693444 \ No newline at end of file +07038458237b28c7f438b57ff7375b4aeb560b5b \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index 05e43d9..3dfc283a 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -4580d325dd47794891658f68d18fc771fef83910 \ No newline at end of file +746b413cf414a304cc96cad8e59418967e79b0a1 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 index 7ff7c2f6..0784a44 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -376030d36d6af35bffe878529d8d0822c6a87472 \ No newline at end of file +20d723a8f8b0d33675bac4aca7ea886dcd926a3a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index 9682205e5..cebbbfc 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -c4359bb2fa330b0d0ba878be71ef60bc397cb3fb \ No newline at end of file +fcd383cf7ee754cd40afb3abf2aed48550956944 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 910d35e..9147bedf 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -353005a8cb47d87a240c8de6105e1c25e55023fe \ No newline at end of file +40617e0b7668cd8c71da8a8c9abb4aaa15530ba1 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 index 66c9614f..212cd4b 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -b426add7367dec7a5df6f1517e96a01cb2c21da4 \ No newline at end of file +e2a4847fc02afa2f4454b91391adce20a4d1572a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 index 7e4af87..4dbb828 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -8c61c48675b46c13d6e11fc803d874c582827b37 \ No newline at end of file +34cf7d6b3a97e04eec001876eade1a7a88d43306 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index ab4bb52..360df5dc 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -bf63c69ccec0508d526e122971e23b7db64cff04 \ No newline at end of file +93880b3afa88424d550c4805f246d5ecbc4f2009 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 index 56d5639..e9af87c 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -b29e57433cc763a35544d89d1b484d479800bf97 \ No newline at end of file +fab65e366af2801c14e3e9d25ab911c675d217ac \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index d8cc171..b847e7b 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -98beae0353806d3a8070565ddee92111e1d1193f \ No newline at end of file +e109a219cc4a82e9546ac6041b39d121f7646df6 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 5478281..acc042e 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -5e49e9449f0bdccf43d5b7427639b8837d76d952 \ No newline at end of file +0d6ff97799443044f0f7bf3e3c3067a6aae93ae0 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index ee03756..27083a65 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -5b42163976d7e162956ac5f4bb337c3701c61f00 \ No newline at end of file +f14ae25985b551ac7c9e2253caed0d99da11a20d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 index 2563d255..9b10657 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -dbc59599ca2f9a3654148c3660a0a2bcfad74687 \ No newline at end of file +35b8fcd2f9f2ac5b660729b6e1995189ba4ea96e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index a02e142..7e682a89 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -dedacc71a576f7d7d684dec94564bf9d41baf08f \ No newline at end of file +4574007793a1f677d1d9f6bd1a8cad92943320cd \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 index a989f61..a3861a9b 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -95eab5f9382d4ba74f30f8d786b5039db8be20db \ No newline at end of file +6b710694f1c7eb0aade5a8a482bb81d6ca0e3d2f \ No newline at end of file
diff --git a/ios_internal b/ios_internal index ff8ce0b..04489da 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit ff8ce0b2995198b6076b1a6fc0ac27d0d4bc5d6f +Subproject commit 04489da71ef10228a79347ccfd484cfed4f613d3
diff --git a/media/base/picture_in_picture_events_info.cc b/media/base/picture_in_picture_events_info.cc index 4922bfb..a0bcc79 100644 --- a/media/base/picture_in_picture_events_info.cc +++ b/media/base/picture_in_picture_events_info.cc
@@ -7,6 +7,7 @@ #include <string> #include "base/notreached.h" +#include "base/strings/stringprintf.h" namespace media { @@ -30,4 +31,20 @@ << static_cast<int>(auto_pip_reason); } +// static +std::string PictureInPictureEventsInfo::AutoPipInfoToString( + AutoPipInfo auto_pip_info) { + return base::StringPrintf( + "{Reason: %s, has audio focus: %s, is_playing: %s, was recently audible: " + "%s, has safe url: %s, meets media engagement conditions: %s, blocked " + "due to content setting: %s}", + AutoPipReasonToString(auto_pip_info.auto_pip_reason), + auto_pip_info.has_audio_focus ? "true" : "false", + auto_pip_info.is_playing ? "true" : "false", + auto_pip_info.was_recently_audible ? "true" : "false", + auto_pip_info.has_safe_url ? "true" : "false", + auto_pip_info.meets_media_engagement_conditions ? "true" : "false", + auto_pip_info.blocked_due_to_content_setting ? "true" : "false"); +} + } // namespace media
diff --git a/media/base/picture_in_picture_events_info.h b/media/base/picture_in_picture_events_info.h index 5cb534dd..dc4e5ffa 100644 --- a/media/base/picture_in_picture_events_info.h +++ b/media/base/picture_in_picture_events_info.h
@@ -35,9 +35,20 @@ kMaxValue = kMediaPlayback, }; + struct MEDIA_EXPORT AutoPipInfo { + AutoPipReason auto_pip_reason = AutoPipReason::kUnknown; + bool has_audio_focus = false; + bool is_playing = false; + bool was_recently_audible = false; + bool has_safe_url = false; + bool meets_media_engagement_conditions = false; + bool blocked_due_to_content_setting = false; + }; + using AutoPipReasonCallback = base::RepeatingCallback<AutoPipReason(void)>; static std::string AutoPipReasonToString(AutoPipReason auto_pip_reason); + static std::string AutoPipInfoToString(AutoPipInfo auto_pip_info); }; } // namespace media
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index c424431..c50826a 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc
@@ -1003,7 +1003,7 @@ // add a destruction callback to unlock the IOSurface. kern_return_t lock_result = IOSurfaceLock(io_surface.get(), kIOSurfaceLockReadOnly, nullptr); - if (lock_result != kIOReturnSuccess) { + if (lock_result != KERN_SUCCESS) { DLOG(ERROR) << "Failed to lock IOSurface."; return nullptr; }
diff --git a/mojo/public/cpp/bindings/direct_receiver.h b/mojo/public/cpp/bindings/direct_receiver.h index 54364bd8..179b148b 100644 --- a/mojo/public/cpp/bindings/direct_receiver.h +++ b/mojo/public/cpp/bindings/direct_receiver.h
@@ -153,7 +153,9 @@ // Binds this object to `receiver` to receive IPC directly on the calling // thread. void Bind(PendingReceiver<T> receiver) { - receiver_.Bind(PendingReceiver<T>{node_->AdoptPipe(receiver.PassPipe())}); + receiver_.Bind(receiver.is_valid() ? PendingReceiver<T>(node_->AdoptPipe( + receiver.PassPipe())) + : std::move(receiver)); } internal::ThreadLocalNode& node_for_testing() { return *node_; }
diff --git a/mojo/public/cpp/bindings/tests/direct_receiver_unittest.cc b/mojo/public/cpp/bindings/tests/direct_receiver_unittest.cc index bdd2447..0e067a7 100644 --- a/mojo/public/cpp/bindings/tests/direct_receiver_unittest.cc +++ b/mojo/public/cpp/bindings/tests/direct_receiver_unittest.cc
@@ -396,4 +396,17 @@ }); } +TEST_F(DirectReceiverTest, BindInvalidPendingReceiver) { + base::Thread io_thread("Test IO thread 1"); + io_thread.StartWithOptions( + base::Thread::Options{base::MessagePumpType::IO, 0}); + + RunOn(io_thread, [&] { + EXPECT_FALSE(internal::ThreadLocalNode::CurrentThreadHasInstance()); + auto impl = std::make_unique<ServiceImpl>(io_thread.task_runner()); + impl->receiver().Bind(NullReceiver()); + EXPECT_FALSE(impl->receiver().receiver_for_testing().is_bound()); + }); +} + } // namespace mojo::test::direct_receiver_unittest
diff --git a/mojo/public/cpp/platform/platform_handle.cc b/mojo/public/cpp/platform/platform_handle.cc index 7a09722..7e2cf43 100644 --- a/mojo/public/cpp/platform/platform_handle.cc +++ b/mojo/public/cpp/platform/platform_handle.cc
@@ -42,26 +42,24 @@ #if BUILDFLAG(IS_WIN) base::win::ScopedHandle CloneHandle(const base::win::ScopedHandle& handle) { - DCHECK(handle.IsValid()); + DCHECK(handle.is_valid()); - HANDLE dupe; - BOOL result = FALSE; - - // INVALID_HANDLE_VALUE and the process pseudo-handle are both represented as - // the value -1. This means that if a caller does not correctly check the - // handle returned by file and pipe creation APIs, then it would pass an - // INVALID_HANDLE_VALUE to the code below, which would result in the - // destination process getting full control over the calling process (see - // http://crbug.com/243339 for an example of this vulnerability). So, we just - // explicitly check for INVALID_HANDLE_VALUE, since there's no valid scenario - // in which it would be passed as the source handle here. - if (handle.Get() != INVALID_HANDLE_VALUE) { - result = ::DuplicateHandle(::GetCurrentProcess(), handle.Get(), - ::GetCurrentProcess(), &dupe, 0, FALSE, - DUPLICATE_SAME_ACCESS); - } - if (!result) + // If a caller does not correctly check the handle returned by file and pipe + // creation APIs, or directly provides a pseudo handle value like + // ::GetCurrentThread(), then it would result in the destination process + // getting full control over the calling process (see http://crbug.com/243339 + // for an example of this vulnerability). HandleTraits for Windows rejects + // pseudo handle values, but check again here for defense-in-depth. + if (!handle.is_valid()) { return base::win::ScopedHandle(); + } + + HANDLE dupe = nullptr; + if (!::DuplicateHandle(::GetCurrentProcess(), handle.Get(), + ::GetCurrentProcess(), &dupe, 0, FALSE, + DUPLICATE_SAME_ACCESS)) { + return base::win::ScopedHandle(); + } DCHECK_NE(dupe, INVALID_HANDLE_VALUE); return base::win::ScopedHandle(dupe); }
diff --git a/mojo/public/cpp/platform/tests/platform_handle_unittest.cc b/mojo/public/cpp/platform/tests/platform_handle_unittest.cc index 351ecbe..daca632 100644 --- a/mojo/public/cpp/platform/tests/platform_handle_unittest.cc +++ b/mojo/public/cpp/platform/tests/platform_handle_unittest.cc
@@ -26,6 +26,8 @@ #endif #if BUILDFLAG(IS_WIN) +#include <windows.h> + #include "base/win/scoped_handle.h" #else #include "base/files/scoped_file.h" @@ -250,6 +252,21 @@ EXPECT_EQ(kTestData, GetObjectContents(handle)); } +#if BUILDFLAG(IS_WIN) && !DCHECK_IS_ON() +// In DCHECK builds these explode but we include defense-in-depth measures as +// third party code can cause unexpected values to manifest in handles. +TEST_P(PlatformHandleTest, InvalidHandles) { + // Validate the security assumption that a pseudo handle cannot be adopted as + // a PlatformHandle and that it cannot be cloned to a valid handle. + PlatformHandle invalid((base::win::ScopedHandle(::GetCurrentThread()))); + EXPECT_FALSE(invalid.is_valid()); + PlatformHandle cloned = invalid.Clone(); + EXPECT_FALSE(cloned.is_valid()); + EXPECT_EQ(invalid.ReleaseHandle(), nullptr); + EXPECT_EQ(cloned.ReleaseHandle(), nullptr); +} +#endif // BUILDFLAG(IS_WIN) && !DCHECK_IS_ON() + #if BUILDFLAG(IS_ANDROID) DEFINE_BINDER_CLASS(IncrementerInterface); class Incrementer : public base::android::SupportsBinder<IncrementerInterface> {
diff --git a/sandbox/win/src/policy_target_test.cc b/sandbox/win/src/policy_target_test.cc index 92622f5b..c0dc607 100644 --- a/sandbox/win/src/policy_target_test.cc +++ b/sandbox/win/src/policy_target_test.cc
@@ -594,4 +594,10 @@ } } +TEST(PolicyTargetDeathTest, SharePseudoHandle) { + TestRunner runner; + auto* policy = runner.GetPolicy(); + EXPECT_DEATH(policy->AddHandleToShare(::GetCurrentThread()), ""); +} + } // namespace sandbox
diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc index 0ac0811..84a68bb 100644 --- a/sandbox/win/src/sandbox_policy_base.cc +++ b/sandbox/win/src/sandbox_policy_base.cc
@@ -13,10 +13,10 @@ #include <stdint.h> #include <memory> +#include <optional> #include <utility> #include <vector> -#include <optional> #include "base/containers/span.h" #include "base/functional/callback.h" #include "base/logging.h" @@ -24,6 +24,7 @@ #include "base/win/access_token.h" #include "base/win/sid.h" #include "base/win/win_util.h" +#include "base/win/windows_handle_util.h" #include "base/win/windows_version.h" #include "sandbox/features.h" #include "sandbox/win/src/acl.h" @@ -73,10 +74,12 @@ } bool IsInheritableHandle(HANDLE handle) { - if (!handle) + if (!handle) { return false; - if (handle == INVALID_HANDLE_VALUE) + } + if (base::win::IsPseudoHandle(handle)) { return false; + } // File handles (FILE_TYPE_DISK) and pipe handles are known to be // inheritable. Console handles (FILE_TYPE_CHAR) are not // inheritable via PROC_THREAD_ATTRIBUTE_HANDLE_LIST. @@ -469,8 +472,8 @@ : tag_(tag), config_(), config_ptr_(nullptr), - stdout_handle_(INVALID_HANDLE_VALUE), - stderr_handle_(INVALID_HANDLE_VALUE), + stdout_handle_(nullptr), + stderr_handle_(nullptr), delegate_data_(nullptr), dispatcher_(nullptr), job_() {} @@ -528,7 +531,7 @@ void PolicyBase::AddHandleToShare(HANDLE handle) { CHECK(handle); - CHECK_NE(handle, INVALID_HANDLE_VALUE); + CHECK(!base::win::IsPseudoHandle(handle)); // Ensure the handle can be inherited. bool result =
diff --git a/sandbox/win/src/sandbox_policy_diagnostic.cc b/sandbox/win/src/sandbox_policy_diagnostic.cc index 5e7771a2..3316305c 100644 --- a/sandbox/win/src/sandbox_policy_diagnostic.cc +++ b/sandbox/win/src/sandbox_policy_diagnostic.cc
@@ -474,8 +474,7 @@ dict.Set(kZeroAppShim, zero_appshim_); dict.Set(kHandlesToClose, GetHandlesToClose(handles_to_close_)); - std::optional<std::string> json_string = - base::WriteJson(base::Value(std::move(dict))); + std::optional<std::string> json_string = base::WriteJson(dict); CHECK(json_string); json_string_ = std::move(json_string); return *json_string_;
diff --git a/sandbox/win/src/startup_information_helper.cc b/sandbox/win/src/startup_information_helper.cc index 8e897bc5..b81562676 100644 --- a/sandbox/win/src/startup_information_helper.cc +++ b/sandbox/win/src/startup_information_helper.cc
@@ -17,6 +17,7 @@ #include "base/check.h" #include "base/memory/scoped_refptr.h" #include "base/win/startup_information.h" +#include "base/win/windows_handle_util.h" #include "base/win/windows_version.h" #include "sandbox/win/src/app_container.h" #include "sandbox/win/src/nt_internals.h" @@ -64,7 +65,11 @@ } void StartupInformationHelper::AddInheritedHandle(HANDLE handle) { - if (handle != INVALID_HANDLE_VALUE) { + // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute + // "These handles must be created as inheritable handles and must not include + // pseudo handles such as those returned by the GetCurrentProcess or + // GetCurrentThread function." + if (handle && !base::win::IsPseudoHandle(handle)) { auto it = std::ranges::find(inherited_handle_list_, handle); if (it == inherited_handle_list_.end()) inherited_handle_list_.push_back(handle); @@ -161,7 +166,7 @@ return false; } startup_info_.startup_info()->dwFlags |= STARTF_USESTDHANDLES; - startup_info_.startup_info()->hStdInput = INVALID_HANDLE_VALUE; + startup_info_.startup_info()->hStdInput = nullptr; startup_info_.startup_info()->hStdOutput = stdout_handle_; startup_info_.startup_info()->hStdError = stderr_handle_; // Allowing inheritance of handles is only secure now that we
diff --git a/sandbox/win/src/startup_information_helper.h b/sandbox/win/src/startup_information_helper.h index b92cee4..9369bb7 100644 --- a/sandbox/win/src/startup_information_helper.h +++ b/sandbox/win/src/startup_information_helper.h
@@ -78,8 +78,8 @@ // This can only be true if security_capabilities_ is also initialized. bool enable_low_privilege_app_container_ = false; bool restrict_child_process_creation_ = false; - HANDLE stdout_handle_ = INVALID_HANDLE_VALUE; - HANDLE stderr_handle_ = INVALID_HANDLE_VALUE; + HANDLE stdout_handle_ = nullptr; + HANDLE stderr_handle_ = nullptr; bool inherit_handles_ = false; bool filter_environment_ = false; size_t mitigations_size_ = 0;
diff --git a/services/network/public/cpp/permissions_policy/permissions_policy_features.json5 b/services/network/public/cpp/permissions_policy/permissions_policy_features.json5 index cad93ee..8c049ec 100644 --- a/services/network/public/cpp/permissions_policy/permissions_policy_features.json5 +++ b/services/network/public/cpp/permissions_policy/permissions_policy_features.json5
@@ -275,6 +275,11 @@ depends_on: ["FetchLaterAPI"], }, { + name: "DeviceAttributes", + permissions_policy_name: "device-attributes", + depends_on: ["DeviceAttributes"], + }, + { name: "DigitalCredentialsGet", permissions_policy_name: "digital-credentials-get", depends_on: ["WebIdentityDigitalCredentials"],
diff --git a/services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom b/services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom index 78118be..aa2d19e 100644 --- a/services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom +++ b/services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom
@@ -317,6 +317,11 @@ // See https://github.com/webmachinelearning/translation-api kLanguageDetector = 134, + // "device-attributes" is a permissions policy that controls whether + // the Device Attributes API can be called. + // See https://wicg.github.io/WebApiDevice/device_attributes + kDeviceAttributes = 135, + // Don't change assigned numbers of any item, and don't reuse removed slots. // Add new features at the end of the enum. // Also, run update_permissions_policy_enum.py in
diff --git a/services/preferences/tracked/pref_hash_calculator.cc b/services/preferences/tracked/pref_hash_calculator.cc index ef55462c..f5b3b47 100644 --- a/services/preferences/tracked/pref_hash_calculator.cc +++ b/services/preferences/tracked/pref_hash_calculator.cc
@@ -107,7 +107,7 @@ base::Value::Dict dict = value->Clone(); RemoveEmptyValueDictEntries(dict); - return base::WriteJson(base::Value(std::move(dict))).value_or(std::string()); + return base::WriteJson(dict).value_or(std::string()); } std::string ValueAsString(const base::Value* value) {
diff --git a/testing/buildbot/filters/android.emulator_15_tablet.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_15_tablet.chrome_public_test_apk.filter index 786807c..8bb7337 100644 --- a/testing/buildbot/filters/android.emulator_15_tablet.chrome_public_test_apk.filter +++ b/testing/buildbot/filters/android.emulator_15_tablet.chrome_public_test_apk.filter
@@ -34,4 +34,19 @@ -org.chromium.chrome.browser.compositor.overlays.strip.TabStripGroupContextMenuTest.* # crbug.com/393388366 --org.chromium.chrome.browser.desktop_windowing.AppHeaderCoordinatorBrowserTest.testKeyboardInDesktopWindow_RootViewPadded \ No newline at end of file +-org.chromium.chrome.browser.desktop_windowing.AppHeaderCoordinatorBrowserTest.testKeyboardInDesktopWindow_RootViewPadded + +# crbug.com/408282366 +-org.chromium.chrome.browser.download.DownloadTest.testUrlEscaping +-org.chromium.chrome.browser.download.DownloadTest.testHttpPostDownload +-org.chromium.chrome.browser.download.DownloadTest.testHttpGetDownload + +# crbug.com/401292006 +-org.chromium.chrome.browser.contextmenu.ContextMenuTest.testCopyImage + +# crbug.com/401272905 +-org.chromium.chrome.browser.keyboard_accessory.PasswordGenerationIntegrationTest.testManualGenerationCancel + +# crbug.com/401287512 +-org.chromium.chrome.browser.contextualsearch.ContextualSearchInstrumentationTest.testNonResolveGesture +-org.chromium.chrome.browser.contextualsearch.ContextualSearchInstrumentationTest.testResolveGesture \ No newline at end of file
diff --git a/testing/buildbot/filters/android.emulator_15_tablet_landscape.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_15_tablet_landscape.chrome_public_test_apk.filter index 9e56e744..7a69227 100644 --- a/testing/buildbot/filters/android.emulator_15_tablet_landscape.chrome_public_test_apk.filter +++ b/testing/buildbot/filters/android.emulator_15_tablet_landscape.chrome_public_test_apk.filter
@@ -45,3 +45,11 @@ -org.chromium.chrome.browser.contextualsearch.ContextualSearchManagerTest.testUnacceptedPrivacy -org.chromium.chrome.browser.contextualsearch.ContextualSearchManagerTest.testAllInternalStatesVisitedResolvingTap -org.chromium.chrome.browser.contextualsearch.ContextualSearchManagerTest.testResolveGestureSelects + +# crbug.com/401321001 +-org.chromium.chrome.browser.safety_hub.SafetyHubTest.testSafeBrowsingLearnMoreLink_OpensInCct + +# crbug.com/408282366 +-org.chromium.chrome.browser.download.DownloadTest.testUrlEscaping +-org.chromium.chrome.browser.download.DownloadTest.testHttpPostDownload +-org.chromium.chrome.browser.download.DownloadTest.testHttpGetDownload \ No newline at end of file
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index fb692da..58ae1d3b 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1402,6 +1402,57 @@ ] } ], + "AttributionReportDeliveryOnNewNavigation": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_2m", + "params": { + "navigation_window": "2m" + }, + "enable_features": [ + "AttributionReportDeliveryOnNewNavigation" + ] + }, + { + "name": "Enabled_1m", + "params": { + "navigation_window": "1m" + }, + "enable_features": [ + "AttributionReportDeliveryOnNewNavigation" + ] + }, + { + "name": "Enabled_3m", + "params": { + "navigation_window": "3m" + }, + "enable_features": [ + "AttributionReportDeliveryOnNewNavigation" + ] + }, + { + "name": "Enabled_5m", + "params": { + "navigation_window": "5m" + }, + "enable_features": [ + "AttributionReportDeliveryOnNewNavigation" + ] + } + ] + } + ], "AttributionReportingInBrowserMigration": [ { "platforms": [ @@ -3310,6 +3361,21 @@ ] } ], + "BlingDiscoFeed": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableDiscoFeedEndpoint" + ] + } + ] + } + ], "BlockAcceptClientHints": [ { "platforms": [ @@ -8828,51 +8894,6 @@ ] } ], - "EdgeToEdgeAndroid": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled_133", - "params": { - "disable_bottom_controls_stacker_y_offset": "false", - "e2e_field_trial_oem_list": "oppo,xiaomi", - "e2e_field_trial_oem_min_versions": "34,34", - "scrollable_when_stacking": "true" - }, - "enable_features": [ - "BottomBrowserControlsRefactor", - "DrawCutoutEdgeToEdge", - "DrawKeyNativeEdgeToEdge", - "DynamicSafeAreaInsets", - "DynamicSafeAreaInsetsOnScroll", - "EdgeToEdgeBottomChin", - "EdgeToEdgeSafeAreaConstraint", - "EdgeToEdgeWebOptIn" - ] - }, - { - "name": "Enabled_WebOptInAndKeyNativePages_131", - "params": { - "disable_bottom_controls_stacker_y_offset": "false", - "e2e_field_trial_oem_list": "oppo,xiaomi", - "e2e_field_trial_oem_min_versions": "34,34" - }, - "enable_features": [ - "BottomBrowserControlsRefactor", - "DrawCutoutEdgeToEdge", - "DrawKeyNativeEdgeToEdge", - "DynamicSafeAreaInsets", - "DynamicSafeAreaInsetsOnScroll", - "EdgeToEdgeBottomChin", - "EdgeToEdgeWebOptIn" - ] - } - ] - } - ], "EdgeToEdgeEverywhere": [ { "platforms": [ @@ -12385,6 +12406,21 @@ ] } ], + "IOSKeyboardAccessoryUpgradeForIPad": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IOSKeyboardAccessoryUpgradeForIPad" + ] + } + ] + } + ], "IOSLogApplicationStorageSizeMetrics": [ { "platforms": [ @@ -26539,6 +26575,21 @@ ] } ], + "WebRtcUseAbsCapTimeForG2gMetric": [ + { + "platforms": [ + "linux", + "windows", + "mac", + "chromeos" + ], + "experiments": [ + { + "name": "Enabled,_20250408" + } + ] + } + ], "WebUIBundledCodeCache": [ { "platforms": [
diff --git a/third_party/angle b/third_party/angle index 1b92a97..0e28c030 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 1b92a973484c95f26bba5e2e4e2511ed03ab6c66 +Subproject commit 0e28c030a2625e3022a9adeec9746519af4217a2
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index 4c6a7c3..358e1af2 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -8453,6 +8453,7 @@ cross-origin-isolated deferred-fetch deferred-fetch-minimal + device-attributes digital-credentials-get direct-sockets direct-sockets-private
diff --git a/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc index 83078303..713a79e 100644 --- a/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc
@@ -18,7 +18,7 @@ InterpolationValue CSSAngleInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value); if (!primitive_value || !primitive_value->IsAngle()) {
diff --git a/third_party/blink/renderer/core/animation/css_angle_interpolation_type.h b/third_party/blink/renderer/core/animation/css_angle_interpolation_type.h index cbe6d3f..862f861 100644 --- a/third_party/blink/renderer/core/animation/css_angle_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_angle_interpolation_type.h
@@ -22,7 +22,7 @@ InterpolationValue MaybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; const CSSValue* CreateCSSValue(const InterpolableValue&,
diff --git a/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.cc index 4280dc3a..cd918d0 100644 --- a/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.cc
@@ -132,10 +132,10 @@ InterpolationValue CSSAspectRatioInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { StyleAspectRatio ratio = - StyleBuilderConverter::ConvertAspectRatio(*state, value); + StyleBuilderConverter::ConvertAspectRatio(state, value); return InterpolationValue( CreateInterpolableAspectRatio(ratio), MakeGarbageCollected<CSSAspectRatioNonInterpolableValue>(
diff --git a/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.h b/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.h index fd15c26..e78913e9 100644 --- a/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_aspect_ratio_interpolation_type.h
@@ -45,7 +45,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc index eb0ae20..054dbf8 100644 --- a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc
@@ -162,7 +162,7 @@ InterpolationValue CSSBasicShapeInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { if (!value.IsBaseValueList()) { return basic_shape_interpolation_functions::MaybeConvertCSSValue(
diff --git a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.h b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.h index 3262e54..b3a7411 100644 --- a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.h
@@ -35,7 +35,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc index 083f1da..ac7d09d 100644 --- a/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc
@@ -305,7 +305,7 @@ InterpolationValue CSSBorderImageLengthBoxInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { const auto* quad = DynamicTo<CSSQuadValue>(value); if (!quad)
diff --git a/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.h b/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.h index df41271..e7189ef 100644 --- a/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.h
@@ -35,7 +35,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc index 27823655..03f3060 100644 --- a/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc
@@ -216,7 +216,7 @@ InterpolationValue CSSClipInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { const auto* quad = DynamicTo<CSSQuadValue>(value); if (!quad)
diff --git a/third_party/blink/renderer/core/animation/css_clip_interpolation_type.h b/third_party/blink/renderer/core/animation/css_clip_interpolation_type.h index b472552..d284ce3e 100644 --- a/third_party/blink/renderer/core/animation/css_clip_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_clip_interpolation_type.h
@@ -38,7 +38,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc index d31f7601..2f2eb63 100644 --- a/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
@@ -277,19 +277,18 @@ InterpolationValue CSSColorInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { if (CssProperty().PropertyID() == CSSPropertyID::kColor) { auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (identifier_value && identifier_value->GetValueID() == CSSValueID::kCurrentcolor) { - DCHECK(state); - return MaybeConvertInherit(*state, conversion_checkers); + return MaybeConvertInherit(state, conversion_checkers); } } InterpolableColor* interpolable_color = - MaybeCreateInterpolableColor(value, state); + MaybeCreateInterpolableColor(value, &state); if (!interpolable_color) { return nullptr; }
diff --git a/third_party/blink/renderer/core/animation/css_color_interpolation_type.h b/third_party/blink/renderer/core/animation/css_color_interpolation_type.h index 9ea8cc8..72fe3dd 100644 --- a/third_party/blink/renderer/core/animation/css_color_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_color_interpolation_type.h
@@ -83,7 +83,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; static InterpolationValue ConvertStyleColorPair( const OptionalStyleColor&,
diff --git a/third_party/blink/renderer/core/animation/css_content_visibility_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_content_visibility_interpolation_type.cc index 9158ba9..83d6e976 100644 --- a/third_party/blink/renderer/core/animation/css_content_visibility_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_content_visibility_interpolation_type.cc
@@ -152,7 +152,7 @@ InterpolationValue CSSContentVisibilityInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers& conversion_checkers) const { const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (!identifier_value) {
diff --git a/third_party/blink/renderer/core/animation/css_content_visibility_interpolation_type.h b/third_party/blink/renderer/core/animation/css_content_visibility_interpolation_type.h index d68334a..4bf194a4 100644 --- a/third_party/blink/renderer/core/animation/css_content_visibility_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_content_visibility_interpolation_type.h
@@ -41,7 +41,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_custom_length_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_custom_length_interpolation_type.cc index ccc0dde..7e650b3 100644 --- a/third_party/blink/renderer/core/animation/css_custom_length_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_custom_length_interpolation_type.cc
@@ -17,7 +17,7 @@ InterpolationValue CSSCustomLengthInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { InterpolableLength* maybe_length = InterpolableLength::MaybeConvertCSSValue(value);
diff --git a/third_party/blink/renderer/core/animation/css_custom_length_interpolation_type.h b/third_party/blink/renderer/core/animation/css_custom_length_interpolation_type.h index d23f2b9..91f2b60 100644 --- a/third_party/blink/renderer/core/animation/css_custom_length_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_custom_length_interpolation_type.h
@@ -21,7 +21,7 @@ InterpolationValue MaybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; const CSSValue* CreateCSSValue(const InterpolableValue&,
diff --git a/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc index a9befb10..d4ec374 100644 --- a/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc
@@ -37,16 +37,17 @@ InterpolationValue CSSCustomListInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { const auto* list = DynamicTo<CSSValueList>(value); - if (!list) + if (!list) { return nullptr; + } ConversionCheckers null_checkers; return ListInterpolationFunctions::CreateList( - list->length(), [this, list, state, &null_checkers](wtf_size_t index) { + list->length(), [this, list, &state, &null_checkers](wtf_size_t index) { return inner_interpolation_type_->MaybeConvertValue( list->Item(index), state, null_checkers); });
diff --git a/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.h b/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.h index df4629ec..d24b5a2 100644 --- a/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.h
@@ -30,7 +30,7 @@ InterpolationValue MaybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue PreInterpolationCompositeIfNeeded( InterpolationValue value,
diff --git a/third_party/blink/renderer/core/animation/css_custom_transform_function_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_custom_transform_function_interpolation_type.cc index 2d195bc..60a76419 100644 --- a/third_party/blink/renderer/core/animation/css_custom_transform_function_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_custom_transform_function_interpolation_type.cc
@@ -38,11 +38,10 @@ InterpolationValue CSSCustomTransformFunctionInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { - CHECK(state); return MaybeConvertTransformFunction(value, - state->CssToLengthConversionData()); + state.CssToLengthConversionData()); } const CSSValue* CSSCustomTransformFunctionInterpolationType::CreateCSSValue(
diff --git a/third_party/blink/renderer/core/animation/css_custom_transform_function_interpolation_type.h b/third_party/blink/renderer/core/animation/css_custom_transform_function_interpolation_type.h index e5f9ebb..42bae013 100644 --- a/third_party/blink/renderer/core/animation/css_custom_transform_function_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_custom_transform_function_interpolation_type.h
@@ -26,7 +26,7 @@ InterpolationValue MaybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; const CSSValue* CreateCSSValue(const InterpolableValue&,
diff --git a/third_party/blink/renderer/core/animation/css_custom_transform_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_custom_transform_interpolation_type.cc index 35d3305..767f2ad6 100644 --- a/third_party/blink/renderer/core/animation/css_custom_transform_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_custom_transform_interpolation_type.cc
@@ -42,10 +42,9 @@ InterpolationValue CSSCustomTransformInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { - CHECK(state); - return MaybeConvertTransformList(value, state->CssToLengthConversionData()); + return MaybeConvertTransformList(value, state.CssToLengthConversionData()); } const CSSValue* CSSCustomTransformInterpolationType::CreateCSSValue(
diff --git a/third_party/blink/renderer/core/animation/css_custom_transform_interpolation_type.h b/third_party/blink/renderer/core/animation/css_custom_transform_interpolation_type.h index 4494651..cd290ac 100644 --- a/third_party/blink/renderer/core/animation/css_custom_transform_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_custom_transform_interpolation_type.h
@@ -24,7 +24,7 @@ InterpolationValue MaybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; const CSSValue* CreateCSSValue(const InterpolableValue&,
diff --git a/third_party/blink/renderer/core/animation/css_display_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_display_interpolation_type.cc index 5fcb444..b0cb314c9 100644 --- a/third_party/blink/renderer/core/animation/css_display_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_display_interpolation_type.cc
@@ -137,7 +137,7 @@ InterpolationValue CSSDisplayInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers& conversion_checkers) const { const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (!identifier_value) {
diff --git a/third_party/blink/renderer/core/animation/css_display_interpolation_type.h b/third_party/blink/renderer/core/animation/css_display_interpolation_type.h index 7d1f78b..73f3a5b 100644 --- a/third_party/blink/renderer/core/animation/css_display_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_display_interpolation_type.h
@@ -41,7 +41,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type.cc index 185adba..f047a75 100644 --- a/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type.cc
@@ -59,7 +59,7 @@ InterpolationValue CSSDynamicRangeLimitInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState&, ConversionCheckers& conversion_checkers) const { return ConvertDynamicRangeLimit( StyleBuilderConverterBase::ConvertDynamicRangeLimit(value));
diff --git a/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type.h b/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type.h index 4de8716c..4ebb0dc 100644 --- a/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type.h
@@ -25,7 +25,7 @@ StyleResolverState&) const final; static InterpolationValue ConvertDynamicRangeLimit(DynamicRangeLimit limit); InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; private:
diff --git a/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type_test.cc b/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type_test.cc index ccdfe2f..a4f22ad 100644 --- a/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type_test.cc +++ b/third_party/blink/renderer/core/animation/css_dynamic_range_limit_interpolation_type_test.cc
@@ -75,9 +75,12 @@ CSSValue* value = MakeGarbageCollected<CSSIdentifierValue>(CSSValueID::kStandard); + StyleResolverState dummy_state(GetDocument(), + *GetDocument().documentElement()); + InterpolationValue result = dynamic_range_limit_interpolation_type->MaybeConvertValue( - *value, nullptr, conversion_checkers); + *value, dummy_state, conversion_checkers); const InterpolableDynamicRangeLimit* interpolable_limit = To<InterpolableDynamicRangeLimit>(result.interpolable_value.Get());
diff --git a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc index f8f2cf2..2012bfb 100644 --- a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc
@@ -181,7 +181,7 @@ InterpolationValue CSSFilterListInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (identifier_value && identifier_value->GetValueID() == CSSValueID::kNone) {
diff --git a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.h b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.h index d21a50f..9e51449 100644 --- a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.h
@@ -40,7 +40,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; // Helper methods to perform either additive or accumulative composition, as
diff --git a/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type.cc index ead572b..543f6ee9 100644 --- a/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type.cc
@@ -67,14 +67,12 @@ InterpolationValue CSSFontPaletteInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { // TODO(40946458): Don't resolve anything here, rewrite to // interpolate unresolved palettes. return ConvertFontPalette(StyleBuilderConverterBase::ConvertFontPalette( - state ? state->CssToLengthConversionData() - : CSSToLengthConversionData(/*element=*/nullptr), - value)); + state.CssToLengthConversionData(), value)); } InterpolationValue
diff --git a/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type.h b/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type.h index 6ed4c75..088b373 100644 --- a/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type.h
@@ -26,7 +26,7 @@ static InterpolationValue ConvertFontPalette( scoped_refptr<const FontPalette> font_palette); InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; private:
diff --git a/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type_test.cc b/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type_test.cc index 892419fb..22a4ce6 100644 --- a/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type_test.cc +++ b/third_party/blink/renderer/core/animation/css_font_palette_interpolation_type_test.cc
@@ -74,8 +74,10 @@ CSSValue* value = MakeGarbageCollected<CSSCustomIdentValue>(AtomicString("--palette")); + StyleResolverState dummy_state(GetDocument(), + *GetDocument().documentElement()); InterpolationValue result = - font_palette_interpolation_type->MaybeConvertValue(*value, nullptr, + font_palette_interpolation_type->MaybeConvertValue(*value, dummy_state, conversion_checkers); const InterpolableFontPalette* interpolable_font_palette =
diff --git a/third_party/blink/renderer/core/animation/css_font_size_adjust_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_size_adjust_interpolation_type.cc index a97d535..77c035a 100644 --- a/third_party/blink/renderer/core/animation/css_font_size_adjust_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_size_adjust_interpolation_type.cc
@@ -114,7 +114,7 @@ InterpolationValue CSSFontSizeAdjustInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (identifier_value && identifier_value->GetValueID() == CSSValueID::kNone) {
diff --git a/third_party/blink/renderer/core/animation/css_font_size_adjust_interpolation_type.h b/third_party/blink/renderer/core/animation/css_font_size_adjust_interpolation_type.h index 29ab40c..9054423 100644 --- a/third_party/blink/renderer/core/animation/css_font_size_adjust_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_font_size_adjust_interpolation_type.h
@@ -34,7 +34,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; PairwiseInterpolationValue MaybeMergeSingles(
diff --git a/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc index 5ab560c..e925cec 100644 --- a/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc
@@ -108,21 +108,21 @@ InterpolationValue CSSFontSizeInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { - DCHECK(state); - InterpolableValue* result = InterpolableLength::MaybeConvertCSSValue(value); if (result) return InterpolationValue(result); - if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { - return MaybeConvertKeyword(identifier_value->GetValueID(), *state, + if (const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { + return MaybeConvertKeyword(identifier_value->GetValueID(), state, conversion_checkers); } - if (auto* system_font = DynamicTo<cssvalue::CSSPendingSystemFontValue>(value)) - return ConvertFontSize(system_font->ResolveFontSize(&state->GetDocument())); + if (const auto* system_font = + DynamicTo<cssvalue::CSSPendingSystemFontValue>(value)) { + return ConvertFontSize(system_font->ResolveFontSize(&state.GetDocument())); + } return nullptr; }
diff --git a/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.h b/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.h index b36b466..3f95dbfe 100644 --- a/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.h
@@ -31,7 +31,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc index 93098de..5998040 100644 --- a/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.cc
@@ -65,7 +65,7 @@ InterpolationValue CSSFontStretchInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { if (const auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value)) { if (primitive_value->IsPercentage()) {
diff --git a/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.h b/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.h index bf5f4f10..3211453 100644 --- a/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_font_stretch_interpolation_type.h
@@ -32,7 +32,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.cc index caaedb6..55de9b56 100644 --- a/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.cc
@@ -59,18 +59,16 @@ InterpolationValue CSSFontStyleInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { - auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); + const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (identifier_value && identifier_value->GetValueID() == CSSValueID::kItalic) { return nullptr; } // TODO(40946458): Don't resolve angle here, use unresolved version instead. return CreateFontStyleValue(StyleBuilderConverterBase::ConvertFontStyle( - state ? state->CssToLengthConversionData() - : CSSToLengthConversionData(/*element=*/nullptr), - value)); + state.CssToLengthConversionData(), value)); } InterpolationValue
diff --git a/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.h b/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.h index 6fd62696..f928003 100644 --- a/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_font_style_interpolation_type.h
@@ -41,7 +41,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc index e6cb8fc1..0a9d491 100644 --- a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
@@ -142,10 +142,10 @@ InterpolationValue CSSFontVariationSettingsInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { scoped_refptr<FontVariationSettings> settings = - StyleBuilderConverter::ConvertFontVariationSettings(*state, value); + StyleBuilderConverter::ConvertFontVariationSettings(state, value); return ConvertFontVariationSettings(settings.get()); }
diff --git a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.h b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.h index 28e90af..5f88fb2a 100644 --- a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.h
@@ -39,7 +39,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc index 59b131f..34b7468 100644 --- a/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc
@@ -61,12 +61,11 @@ InterpolationValue CSSFontWeightInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { - DCHECK(state); FontSelectionValue inherited_font_weight = - state->ParentStyle()->GetFontWeight(); - if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { + state.ParentStyle()->GetFontWeight(); + if (const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { CSSValueID keyword = identifier_value->GetValueID(); if (keyword == CSSValueID::kBolder || keyword == CSSValueID::kLighter) { conversion_checkers.push_back( @@ -77,9 +76,7 @@ // TODO(40946458): Should do a proper interpolation here instead of converting // relative units first. return CreateFontWeightValue(StyleBuilderConverterBase::ConvertFontWeight( - state ? state->CssToLengthConversionData() - : CSSToLengthConversionData(/*element=*/nullptr), - value, inherited_font_weight)); + state.CssToLengthConversionData(), value, inherited_font_weight)); } InterpolationValue
diff --git a/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.h b/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.h index af3e1567..b0d7c97f 100644 --- a/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.h
@@ -32,7 +32,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_grid_template_property_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_grid_template_property_interpolation_type.cc index 529809eb..b93446e 100644 --- a/third_party/blink/renderer/core/animation/css_grid_template_property_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_grid_template_property_interpolation_type.cc
@@ -245,20 +245,20 @@ InterpolationValue CSSGridTemplatePropertyInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { - if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { + if (const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { DCHECK_EQ(identifier_value->GetValueID(), CSSValueID::kNone); return InterpolationValue(nullptr); } ComputedGridTrackList computed_grid_track_list; StyleBuilderConverter::ConvertGridTrackList( - value, computed_grid_track_list, *const_cast<StyleResolverState*>(state)); + value, computed_grid_track_list, const_cast<StyleResolverState&>(state)); return InterpolationValue( CreateInterpolableGridTrackList(computed_grid_track_list.track_list, CssProperty(), - state->StyleBuilder().EffectiveZoom()), + state.StyleBuilder().EffectiveZoom()), MakeGarbageCollected<CSSGridTrackListNonInterpolableValue>( computed_grid_track_list.named_grid_lines, computed_grid_track_list.ordered_named_grid_lines));
diff --git a/third_party/blink/renderer/core/animation/css_grid_template_property_interpolation_type.h b/third_party/blink/renderer/core/animation/css_grid_template_property_interpolation_type.h index 69eab73f..630d926 100644 --- a/third_party/blink/renderer/core/animation/css_grid_template_property_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_grid_template_property_interpolation_type.h
@@ -46,7 +46,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; CSSPropertyID property_id_;
diff --git a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc index 1d0e9da..9048ab7 100644 --- a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
@@ -264,7 +264,7 @@ InterpolationValue CSSImageInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { return MaybeConvertCSSValue(value, true); }
diff --git a/third_party/blink/renderer/core/animation/css_image_interpolation_type.h b/third_party/blink/renderer/core/animation/css_image_interpolation_type.h index 6a32b72..6c53908 100644 --- a/third_party/blink/renderer/core/animation/css_image_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_image_interpolation_type.h
@@ -54,7 +54,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; PairwiseInterpolationValue MaybeMergeSingles(
diff --git a/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc index a7b2ec0..16589b2d 100644 --- a/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc
@@ -114,7 +114,7 @@ InterpolationValue CSSImageListInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (identifier_value && identifier_value->GetValueID() == CSSValueID::kNone)
diff --git a/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.h b/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.h index 137734a..257b8544 100644 --- a/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.h
@@ -35,7 +35,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; PairwiseInterpolationValue MaybeMergeSingles(
diff --git a/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc index f8f9d321..78ebbd1 100644 --- a/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc
@@ -203,7 +203,7 @@ InterpolationValue CSSImageSliceInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { if (!IsA<cssvalue::CSSBorderImageSliceValue>(value)) return nullptr;
diff --git a/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.h b/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.h index 205a34b..f6f69b0 100644 --- a/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.h
@@ -35,7 +35,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_interpolation_type.cc index 29ec8a4..3b1f37a 100644 --- a/third_party/blink/renderer/core/animation/css_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_interpolation_type.cc
@@ -301,7 +301,7 @@ return MaybeConvertInherit(state, conversion_checkers); } - return MaybeConvertValue(*value, &state, conversion_checkers); + return MaybeConvertValue(*value, state, conversion_checkers); } InterpolationValue CSSInterpolationType::MaybeConvertCustomPropertyDeclaration( @@ -375,7 +375,7 @@ } DCHECK(value); - return MaybeConvertValue(*value, &state, conversion_checkers); + return MaybeConvertValue(*value, state, conversion_checkers); } InterpolationValue CSSInterpolationType::MaybeConvertUnderlyingValue(
diff --git a/third_party/blink/renderer/core/animation/css_interpolation_type.h b/third_party/blink/renderer/core/animation/css_interpolation_type.h index a478dc1..daa31d7 100644 --- a/third_party/blink/renderer/core/animation/css_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_interpolation_type.h
@@ -38,7 +38,7 @@ virtual InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const = 0; virtual InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const = 0; virtual const CSSValue* CreateCSSValue(const InterpolableValue&, const NonInterpolableValue*,
diff --git a/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.cc index 5a7b05d..3d2321b 100644 --- a/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.cc
@@ -185,10 +185,10 @@ InterpolationValue CSSIntrinsicLengthInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { const StyleIntrinsicLength& dimension = - StyleBuilderConverter::ConvertIntrinsicDimension(*state, value); + StyleBuilderConverter::ConvertIntrinsicDimension(state, value); return InterpolationValue( CreateInterpolableIntrinsicDimension(dimension), CSSIntrinsicLengthNonInterpolableValue::Create(dimension));
diff --git a/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.h b/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.h index 337c36f..bb227da 100644 --- a/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_intrinsic_length_interpolation_type.h
@@ -52,7 +52,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc index db7fd86f..61c0849 100644 --- a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
@@ -93,7 +93,7 @@ InterpolationValue CSSLengthInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { CSSValueID value_id = identifier_value->GetValueID(); @@ -101,8 +101,7 @@ if (LengthPropertyFunctions::CanAnimateKeyword(CssProperty(), value_id)) { return InterpolationValue(MakeGarbageCollected<InterpolableLength>( value_id, - state ? std::make_optional(state->StyleBuilder().InterpolateSize()) - : std::nullopt)); + std::make_optional(state.StyleBuilder().InterpolateSize()))); } double pixels;
diff --git a/third_party/blink/renderer/core/animation/css_length_interpolation_type.h b/third_party/blink/renderer/core/animation/css_length_interpolation_type.h index c72373f..16d0050 100644 --- a/third_party/blink/renderer/core/animation/css_length_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_length_interpolation_type.h
@@ -42,7 +42,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue PreInterpolationCompositeIfNeeded(
diff --git a/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc index 099e01fc..a6ff34c 100644 --- a/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc
@@ -107,7 +107,7 @@ InterpolationValue CSSLengthListInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { if (!value.IsBaseValueList()) return nullptr;
diff --git a/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.h b/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.h index e4eb2da..a736324 100644 --- a/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.h
@@ -33,7 +33,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const override; PairwiseInterpolationValue MaybeMergeSingles(
diff --git a/third_party/blink/renderer/core/animation/css_length_pair_interpolation_type.h b/third_party/blink/renderer/core/animation/css_length_pair_interpolation_type.h index 1225d7b..423d7cd 100644 --- a/third_party/blink/renderer/core/animation/css_length_pair_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_length_pair_interpolation_type.h
@@ -19,7 +19,7 @@ private: InterpolationValue MaybeConvertValue(const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final { const auto* pair = DynamicTo<CSSValuePair>(value); if (!pair)
diff --git a/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc index 8a37bd2..b4fd1e3f 100644 --- a/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc
@@ -85,7 +85,7 @@ InterpolationValue CSSNumberInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value); if (!primitive_value || !primitive_value->IsNumber()) {
diff --git a/third_party/blink/renderer/core/animation/css_number_interpolation_type.h b/third_party/blink/renderer/core/animation/css_number_interpolation_type.h index c6fef95..b922b436 100644 --- a/third_party/blink/renderer/core/animation/css_number_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_number_interpolation_type.h
@@ -43,7 +43,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; CSSPrimitiveValue::UnitType UnitType() const {
diff --git a/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc index 2f66c161..f6f13a4 100644 --- a/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc
@@ -123,7 +123,7 @@ InterpolationValue CSSOffsetRotateInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { if (auto* identifier = DynamicTo<CSSIdentifierValue>(value)) { DCHECK_EQ(identifier->GetValueID(), CSSValueID::kAuto);
diff --git a/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.h b/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.h index e9304acc..04d3323 100644 --- a/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.h
@@ -34,7 +34,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; PairwiseInterpolationValue MaybeMergeSingles( InterpolationValue&& start,
diff --git a/third_party/blink/renderer/core/animation/css_overlay_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_overlay_interpolation_type.cc index 5c3354f5..c360d73 100644 --- a/third_party/blink/renderer/core/animation/css_overlay_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_overlay_interpolation_type.cc
@@ -138,7 +138,7 @@ InterpolationValue CSSOverlayInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers& conversion_checkers) const { const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (!identifier_value) {
diff --git a/third_party/blink/renderer/core/animation/css_overlay_interpolation_type.h b/third_party/blink/renderer/core/animation/css_overlay_interpolation_type.h index 2c1debb..2a64464 100644 --- a/third_party/blink/renderer/core/animation/css_overlay_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_overlay_interpolation_type.h
@@ -41,7 +41,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_paint_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_paint_interpolation_type.cc index 19178f46..1f3de30 100644 --- a/third_party/blink/renderer/core/animation/css_paint_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_paint_interpolation_type.cc
@@ -131,10 +131,10 @@ InterpolationValue CSSPaintInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { InterpolableValue* interpolable_color = - CSSColorInterpolationType::MaybeCreateInterpolableColor(value, state); + CSSColorInterpolationType::MaybeCreateInterpolableColor(value, &state); if (!interpolable_color) return nullptr; return InterpolationValue(interpolable_color);
diff --git a/third_party/blink/renderer/core/animation/css_paint_interpolation_type.h b/third_party/blink/renderer/core/animation/css_paint_interpolation_type.h index 4a9d5b5d..7d48edf0 100644 --- a/third_party/blink/renderer/core/animation/css_paint_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_paint_interpolation_type.h
@@ -34,7 +34,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc index 7b62f36..17aa6c9 100644 --- a/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_path_interpolation_type.cc
@@ -138,7 +138,7 @@ InterpolationValue CSSPathInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { const cssvalue::CSSPathValue* path_value = nullptr; if (const auto* list = DynamicTo<CSSValueList>(value)) {
diff --git a/third_party/blink/renderer/core/animation/css_path_interpolation_type.h b/third_party/blink/renderer/core/animation/css_path_interpolation_type.h index c92b1c1f..9f3cc399 100644 --- a/third_party/blink/renderer/core/animation/css_path_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_path_interpolation_type.h
@@ -30,7 +30,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertStandardPropertyUnderlyingValue( const ComputedStyle&) const final;
diff --git a/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.cc index b9670c9..b0f6565 100644 --- a/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.cc
@@ -83,7 +83,7 @@ InterpolationValue CSSPercentageInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { const auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value); if (!primitive_value || !primitive_value->IsPercentage()) {
diff --git a/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.h b/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.h index 65aeea4f..aa6a2e1 100644 --- a/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.h
@@ -38,7 +38,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.cc index 1c103f9..9470e22 100644 --- a/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.cc
@@ -49,7 +49,7 @@ InterpolationValue CSSPositionAxisListInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { if (!value.IsBaseValueList()) { return ListInterpolationFunctions::CreateList(
diff --git a/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.h b/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.h index 60e43e01..1cfb84f 100644 --- a/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.h
@@ -19,7 +19,7 @@ private: InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_position_interpolation_type.h b/third_party/blink/renderer/core/animation/css_position_interpolation_type.h index a3b97185c..a942d15 100644 --- a/third_party/blink/renderer/core/animation/css_position_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_position_interpolation_type.h
@@ -21,7 +21,7 @@ private: InterpolationValue MaybeConvertValue(const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final { const auto* pair = DynamicTo<CSSValuePair>(value); if (!pair) {
diff --git a/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc index 76cb5e5..fe49138 100644 --- a/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc
@@ -285,8 +285,9 @@ InterpolationValue CSSRayInterpolationType::MaybeConvertInherit( const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { - if (!state.ParentStyle()) + if (!state.ParentStyle()) { return nullptr; + } const auto& [inherited_ray, coord_box] = GetRay(*state.ParentStyle()); if (!inherited_ray) @@ -325,9 +326,8 @@ InterpolationValue CSSRayInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { - DCHECK(state); BasicShape* shape = nullptr; CoordBox coord_box = CoordBox::kBorderBox; const CSSPrimitiveValue* angle = nullptr; @@ -335,20 +335,20 @@ if (const auto* list = DynamicTo<CSSValueList>(value)) { if (list->First().IsRayValue()) { angle = &To<cssvalue::CSSRayValue>(list->First()).Angle(); - shape = BasicShapeForValue(*state, list->First()); + shape = BasicShapeForValue(state, list->First()); if (list->length() == 2) { coord_box = To<CSSIdentifierValue>(list->Last()).ConvertTo<CoordBox>(); } } } else if (value.IsRayValue()) { angle = &To<cssvalue::CSSRayValue>(value).Angle(); - shape = BasicShapeForValue(*state, value); + shape = BasicShapeForValue(state, value); } if (!shape) { return nullptr; } return CreateValue(*angle, To<StyleRay>(*shape), coord_box, CssProperty(), - state->ParentStyle()->EffectiveZoom()); + state.ParentStyle()->EffectiveZoom()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_ray_interpolation_type.h b/third_party/blink/renderer/core/animation/css_ray_interpolation_type.h index d1a7323..94c95751 100644 --- a/third_party/blink/renderer/core/animation/css_ray_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_ray_interpolation_type.h
@@ -32,7 +32,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertStandardPropertyUnderlyingValue( const ComputedStyle&) const final;
diff --git a/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc index e7b93a5..2da4a05 100644 --- a/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc
@@ -28,10 +28,9 @@ InterpolationValue CSSResolutionInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { - CHECK(state); - return MaybeConvertResolution(value, state->CssToLengthConversionData()); + return MaybeConvertResolution(value, state.CssToLengthConversionData()); } const CSSValue* CSSResolutionInterpolationType::CreateCSSValue(
diff --git a/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.h b/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.h index 4f50195..3a85ce1 100644 --- a/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.h
@@ -22,7 +22,7 @@ InterpolationValue MaybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; const CSSValue* CreateCSSValue(const InterpolableValue&,
diff --git a/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.cc index add918d..3a6559a 100644 --- a/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.cc
@@ -207,7 +207,7 @@ InterpolationValue CSSRotateInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { if (!value.IsBaseValueList()) { return ConvertRotation(OptionalRotation()); @@ -224,7 +224,7 @@ // rewriting Quaternion and Rotation to have unresolved versions. return ConvertRotation( OptionalRotation(StyleBuilderConverter::ConvertRotation( - CSSToLengthConversionData(&state->GetElement()), value))); + CSSToLengthConversionData(&state.GetElement()), value))); } InterpolationValue
diff --git a/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.h b/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.h index 58ce168..675706f 100644 --- a/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.h
@@ -38,7 +38,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue PreInterpolationCompositeIfNeeded( InterpolationValue value,
diff --git a/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc index f1f300a55..a4ed5454 100644 --- a/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc
@@ -190,7 +190,7 @@ InterpolationValue CSSScaleInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { if (!value.IsBaseValueList()) return CreateInterpolationValue(); @@ -198,9 +198,7 @@ const auto& list = To<CSSValueList>(value); DCHECK(list.length() >= 1 && list.length() <= 3); - CSSToLengthConversionData conversion_data = - state ? state->CssToLengthConversionData() - : CSSToLengthConversionData(/*element=*/nullptr); + CSSToLengthConversionData conversion_data = state.CssToLengthConversionData(); if (list.length() == 1) { InterpolableNumber* scale = CSSValueToInterpolableNumber(list.Item(0), conversion_data);
diff --git a/third_party/blink/renderer/core/animation/css_scale_interpolation_type.h b/third_party/blink/renderer/core/animation/css_scale_interpolation_type.h index ce3464f..5bffab9d 100644 --- a/third_party/blink/renderer/core/animation/css_scale_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_scale_interpolation_type.h
@@ -35,7 +35,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue PreInterpolationCompositeIfNeeded( InterpolationValue value,
diff --git a/third_party/blink/renderer/core/animation/css_scrollbar_color_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_scrollbar_color_interpolation_type.cc index e13bbbc..0f0f295 100644 --- a/third_party/blink/renderer/core/animation/css_scrollbar_color_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_scrollbar_color_interpolation_type.cc
@@ -147,7 +147,7 @@ InterpolationValue CSSScrollbarColorInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { // https://drafts.csswg.org/css-scrollbars/#scrollbar-color // scrollbar-color: auto | <color>{2}
diff --git a/third_party/blink/renderer/core/animation/css_scrollbar_color_interpolation_type.h b/third_party/blink/renderer/core/animation/css_scrollbar_color_interpolation_type.h index 989326e..900ab9b 100644 --- a/third_party/blink/renderer/core/animation/css_scrollbar_color_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_scrollbar_color_interpolation_type.h
@@ -45,7 +45,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc index b9ea63f..a3413a2 100644 --- a/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc
@@ -125,7 +125,7 @@ InterpolationValue CSSShadowListInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (identifier_value && identifier_value->GetValueID() == CSSValueID::kNone) @@ -136,7 +136,7 @@ const auto& value_list = To<CSSValueList>(value); return ListInterpolationFunctions::CreateList( - value_list.length(), [&value_list, state](wtf_size_t index) { + value_list.length(), [&value_list, &state](wtf_size_t index) { return InterpolationValue(InterpolableShadow::MaybeConvertCSSValue( value_list.Item(index), state)); });
diff --git a/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.h b/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.h index 34a1c96..32a4ed7 100644 --- a/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.h
@@ -41,7 +41,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; PairwiseInterpolationValue MaybeMergeSingles( InterpolationValue&& start,
diff --git a/third_party/blink/renderer/core/animation/css_shape_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_shape_interpolation_type.cc index 1aea2b97..dd82713 100644 --- a/third_party/blink/renderer/core/animation/css_shape_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_shape_interpolation_type.cc
@@ -667,7 +667,7 @@ InterpolationValue CSSShapeInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { const CSSValue* first_value = &value; if (const auto* list = DynamicTo<CSSValueList>(value)) {
diff --git a/third_party/blink/renderer/core/animation/css_shape_interpolation_type.h b/third_party/blink/renderer/core/animation/css_shape_interpolation_type.h index a211452b..e75504b 100644 --- a/third_party/blink/renderer/core/animation/css_shape_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_shape_interpolation_type.h
@@ -34,7 +34,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertStandardPropertyUnderlyingValue( const ComputedStyle&) const final;
diff --git a/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc index 97ef2296..d8f2c03 100644 --- a/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc
@@ -145,7 +145,7 @@ InterpolationValue CSSSizeListInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { return MaybeConvertCSSSizeList(value); }
diff --git a/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.h b/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.h index cf9c92c..51292d4d 100644 --- a/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.h
@@ -32,7 +32,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; PairwiseInterpolationValue MaybeMergeSingles(
diff --git a/third_party/blink/renderer/core/animation/css_superellipse_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_superellipse_interpolation_type.cc index a97d4c7b..4516ec5 100644 --- a/third_party/blink/renderer/core/animation/css_superellipse_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_superellipse_interpolation_type.cc
@@ -191,10 +191,10 @@ InterpolationValue CSSSuperellipseInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { return CreateNumberValue( - StyleBuilderConverter::ConvertCornerShape(*state, value)); + StyleBuilderConverter::ConvertCornerShape(state, value)); } InterpolationValue
diff --git a/third_party/blink/renderer/core/animation/css_superellipse_interpolation_type.h b/third_party/blink/renderer/core/animation/css_superellipse_interpolation_type.h index 19c0d5e..9e18334 100644 --- a/third_party/blink/renderer/core/animation/css_superellipse_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_superellipse_interpolation_type.h
@@ -38,7 +38,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc index d05dfb62..6f46cef5 100644 --- a/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc
@@ -104,7 +104,7 @@ InterpolationValue CSSTextIndentInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { InterpolationValue length = nullptr;
diff --git a/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.h b/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.h index ba665ac0f..fdecc670 100644 --- a/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.h
@@ -38,7 +38,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc index 3648e73..9b876a7 100644 --- a/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc
@@ -31,10 +31,9 @@ InterpolationValue CSSTimeInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers&) const { - CHECK(state); - return MaybeConvertTime(value, state->CssToLengthConversionData()); + return MaybeConvertTime(value, state.CssToLengthConversionData()); } const CSSValue* CSSTimeInterpolationType::CreateCSSValue(
diff --git a/third_party/blink/renderer/core/animation/css_time_interpolation_type.h b/third_party/blink/renderer/core/animation/css_time_interpolation_type.h index 6d90623f..e002a70 100644 --- a/third_party/blink/renderer/core/animation/css_time_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_time_interpolation_type.h
@@ -20,7 +20,7 @@ InterpolationValue MaybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; const CSSValue* CreateCSSValue(const InterpolableValue&,
diff --git a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc index 9a564e9..468d80f 100644 --- a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc
@@ -86,9 +86,8 @@ InterpolationValue CSSTransformInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState* state, + const StyleResolverState& state, ConversionCheckers& conversion_checkers) const { - CHECK(state); if (auto* list_value = DynamicTo<CSSValueList>(value)) { CSSPrimitiveValue::LengthTypeFlags types; for (const CSSValue* item : *list_value) { @@ -116,13 +115,13 @@ } if (InterpolationType::ConversionChecker* length_units_checker = - LengthUnitsChecker::MaybeCreate(types, *state)) { + LengthUnitsChecker::MaybeCreate(types, state)) { conversion_checkers.push_back(length_units_checker); } } return InterpolationValue(InterpolableTransformList::ConvertCSSValue( - value, state->CssToLengthConversionData(), + value, state.CssToLengthConversionData(), TransformOperations::BoxSizeDependentMatrixBlending::kAllow)); }
diff --git a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.h b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.h index 4cff520..27874d23 100644 --- a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.h
@@ -79,7 +79,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const override; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const override; };
diff --git a/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h b/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h index bee0836a..d43ca18 100644 --- a/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h
@@ -23,7 +23,7 @@ private: InterpolationValue MaybeConvertValue(const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final { const CSSValueList& list = To<CSSValueList>(value); DCHECK_GE(list.length(), 2u);
diff --git a/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc index fa7ec0c..c7b947d 100644 --- a/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc
@@ -117,7 +117,7 @@ InterpolationValue CSSTranslateInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const { if (!value.IsBaseValueList()) { return CreateNoneValue();
diff --git a/third_party/blink/renderer/core/animation/css_translate_interpolation_type.h b/third_party/blink/renderer/core/animation/css_translate_interpolation_type.h index a6b862b..f8c23cc 100644 --- a/third_party/blink/renderer/core/animation/css_translate_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_translate_interpolation_type.h
@@ -35,7 +35,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; PairwiseInterpolationValue MaybeMergeSingles(
diff --git a/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc index 61f4ff2..9e9ca417f 100644 --- a/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc
@@ -135,7 +135,7 @@ InterpolationValue CSSVisibilityInterpolationType::MaybeConvertValue( const CSSValue& value, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers& conversion_checkers) const { const auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (!identifier_value)
diff --git a/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.h b/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.h index 969bdde..4db9fb97 100644 --- a/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.h
@@ -40,7 +40,7 @@ InterpolationValue MaybeConvertInherit(const StyleResolverState&, ConversionCheckers&) const final; InterpolationValue MaybeConvertValue(const CSSValue&, - const StyleResolverState*, + const StyleResolverState&, ConversionCheckers&) const final; };
diff --git a/third_party/blink/renderer/core/animation/interpolable_filter.cc b/third_party/blink/renderer/core/animation/interpolable_filter.cc index 2f487b88..4f18b8bf 100644 --- a/third_party/blink/renderer/core/animation/interpolable_filter.cc +++ b/third_party/blink/renderer/core/animation/interpolable_filter.cc
@@ -148,7 +148,7 @@ // static InterpolableFilter* InterpolableFilter::MaybeConvertCSSValue( const CSSValue& css_value, - const StyleResolverState* state) { + const StyleResolverState& state) { if (css_value.IsURIValue()) return nullptr;
diff --git a/third_party/blink/renderer/core/animation/interpolable_filter.h b/third_party/blink/renderer/core/animation/interpolable_filter.h index fdf1070..ba40180 100644 --- a/third_party/blink/renderer/core/animation/interpolable_filter.h +++ b/third_party/blink/renderer/core/animation/interpolable_filter.h
@@ -36,7 +36,7 @@ mojom::blink::ColorScheme color_scheme, const ui::ColorProvider* color_provider); static InterpolableFilter* MaybeConvertCSSValue(const CSSValue&, - const StyleResolverState*); + const StyleResolverState&); // Create an InterpolableFilter representing the 'initial value for // interpolation' for the given OperationType.
diff --git a/third_party/blink/renderer/core/animation/interpolable_shadow.cc b/third_party/blink/renderer/core/animation/interpolable_shadow.cc index 52fae46..6437bc7 100644 --- a/third_party/blink/renderer/core/animation/interpolable_shadow.cc +++ b/third_party/blink/renderer/core/animation/interpolable_shadow.cc
@@ -88,7 +88,7 @@ // static InterpolableShadow* InterpolableShadow::MaybeConvertCSSValue( const CSSValue& value, - const StyleResolverState* state) { + const StyleResolverState& state) { const auto* shadow = DynamicTo<CSSShadowValue>(value); if (!shadow) { return nullptr; @@ -106,7 +106,7 @@ InterpolableLength* y = MaybeConvertLength(shadow->y.Get()); InterpolableLength* blur = MaybeConvertLength(shadow->blur.Get()); InterpolableLength* spread = MaybeConvertLength(shadow->spread.Get()); - InterpolableColor* color = MaybeConvertColor(shadow->color, state); + InterpolableColor* color = MaybeConvertColor(shadow->color, &state); // If any of the conversations failed, we can't represent this CSSValue. if (!x || !y || !blur || !spread || !color) {
diff --git a/third_party/blink/renderer/core/animation/interpolable_shadow.h b/third_party/blink/renderer/core/animation/interpolable_shadow.h index c8d4cc03..8542167b 100644 --- a/third_party/blink/renderer/core/animation/interpolable_shadow.h +++ b/third_party/blink/renderer/core/animation/interpolable_shadow.h
@@ -41,7 +41,7 @@ static InterpolableShadow* CreateNeutral(); static InterpolableShadow* MaybeConvertCSSValue(const CSSValue&, - const StyleResolverState*); + const StyleResolverState&); // Helpers for CSSListInterpolationFunctions. static PairwiseInterpolationValue MaybeMergeSingles(InterpolableValue* start,
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index d02bc0f..b408921 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -112,6 +112,7 @@ #include "third_party/blink/renderer/core/dom/popover_data.h" #include "third_party/blink/renderer/core/dom/presentation_attribute_style.h" #include "third_party/blink/renderer/core/dom/pseudo_element.h" +#include "third_party/blink/renderer/core/dom/qualified_name.h" #include "third_party/blink/renderer/core/dom/scriptable_document_parser.h" #include "third_party/blink/renderer/core/dom/scroll_marker_group_pseudo_element.h" #include "third_party/blink/renderer/core/dom/scroll_marker_pseudo_element.h" @@ -3136,6 +3137,10 @@ UpdateClassList(params.old_value, params.new_value); } else if (name == html_names::kNameAttr) { SetHasName(!params.new_value.IsNull()); + } else if (HasTagName(html_names::kATag) && name == html_names::kHrefAttr) { + // <a> element is a potential scroll marker, set flag to check and update if + // needed. + GetDocument().SetNeedsScrollMarkerGroupRelationsUpdate(); } else if (name == html_names::kPartAttr) { part().DidUpdateAttributeValue(params.old_value, params.new_value); GetDocument().GetStyleEngine().PartChangedForElement(*this);
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index e87c8d9..d2c0136 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -305,6 +305,9 @@ } SelectElementAccessibilityIssueReason CheckForIssue(const Node& descendant) { + if (descendant.getNodeType() == Node::kCommentNode) { + return SelectElementAccessibilityIssueReason::kValidChild; + } // Get the parent of the descendant. const Node* parent = descendant.parentNode(); // If the node has no parent, assume it is being appended to a @@ -344,10 +347,10 @@ return TraverseAncestorsAndCheckDescendant(descendant); } if (IsA<HTMLButtonElement>(*parent)) { - if (IsA<HTMLSelectedContentElement>(descendant)) { + if (IsAllowedDescendantOfButton(descendant)) { return SelectElementAccessibilityIssueReason::kValidChild; } - return CheckDescedantOfOption(descendant); + return SelectElementAccessibilityIssueReason::kDisallowedSelectChild; } if (IsA<HTMLLegendElement>(*parent)) { if (IsAllowedPhrasingContent(descendant) && @@ -388,6 +391,12 @@ IsA<HTMLTemplateElement>(descendant); } + bool IsAllowedDescendantOfButton(const Node& descendant) { + return IsA<HTMLSelectedContentElement>(descendant) || + CheckDescedantOfOption(descendant) == + SelectElementAccessibilityIssueReason::kValidChild; + } + SelectElementAccessibilityIssueReason CheckDescedantOfOption( const Node& descendant) { if (!IsA<HTMLDivElement>(descendant) && @@ -441,6 +450,10 @@ IsAllowedDescendantOfSelect(descendant, *parent)) { return SelectElementAccessibilityIssueReason::kValidChild; } + if (IsA<HTMLButtonElement>(*ancestor) && + IsAllowedDescendantOfButton(descendant)) { + return SelectElementAccessibilityIssueReason::kValidChild; + } } return SelectElementAccessibilityIssueReason::kDisallowedSelectChild; }
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 2f28250..bf9241e7 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -454,17 +454,6 @@ } } -// Returns the logical offset in the LocationContainer() coordination system, -// and its WritingMode. -std::tuple<LogicalOffset, WritingMode> LogicalLocation(const LayoutBox& box) { - LayoutBox* container = box.LocationContainer(); - WritingMode writing_mode = container->StyleRef().GetWritingMode(); - WritingModeConverter converter({writing_mode, TextDirection::kLtr}, - PhysicalSize(container->Size())); - return {converter.ToLogical(box.PhysicalLocation(), PhysicalSize(box.Size())), - writing_mode}; -} - } // namespace LayoutBoxRareData::LayoutBoxRareData() @@ -1323,22 +1312,10 @@ return kIndefiniteSize; } -LayoutUnit LayoutBox::LogicalLeft() const { +LogicalRect LayoutBox::LogicalRectInContainer() const { NOT_DESTROYED(); - auto [offset, container_writing_mode] = LogicalLocation(*this); - return IsParallelWritingMode(container_writing_mode, - StyleRef().GetWritingMode()) - ? offset.inline_offset - : offset.block_offset; -} - -LayoutUnit LayoutBox::LogicalTop() const { - NOT_DESTROYED(); - auto [offset, container_writing_mode] = LogicalLocation(*this); - return IsParallelWritingMode(container_writing_mode, - StyleRef().GetWritingMode()) - ? offset.block_offset - : offset.inline_offset; + return LocationContainer()->CreateWritingModeConverter().ToLogical( + PhysicalRect(PhysicalLocation(), Size())); } gfx::QuadF LayoutBox::AbsoluteContentQuad(MapCoordinatesFlags flags) const {
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index 13b1d18..912e0e8 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -216,21 +216,20 @@ LayoutBox* FirstChildBox() const; LayoutBox* LastChildBox() const; - LayoutUnit LogicalLeft() const; - LayoutUnit LogicalRight() const { - NOT_DESTROYED(); - return LogicalLeft() + LogicalWidth(); - } - LayoutUnit LogicalTop() const; - LayoutUnit LogicalBottom() const { - NOT_DESTROYED(); - return LogicalTop() + LogicalHeight(); - } + // Returns the LogicalRect of this box for LocationContainer()'s writing-mode. + // The coordinate origin is the border corner of the LocationContainer(). + // This function doesn't take into account of TextDirection. + LogicalRect LogicalRectInContainer() const; + + // Returns the inline-size for this box's writing-mode. It might be + // different from container's writing-mode. LayoutUnit LogicalWidth() const { NOT_DESTROYED(); PhysicalSize size = Size(); return StyleRef().IsHorizontalWritingMode() ? size.width : size.height; } + // Returns the block-size for this box's writing-mode. It might be + // different from container's writing-mode. LayoutUnit LogicalHeight() const { NOT_DESTROYED(); PhysicalSize size = Size();
diff --git a/third_party/blink/renderer/core/layout/layout_box_test.cc b/third_party/blink/renderer/core/layout/layout_box_test.cc index 9507c3f..aed8b367 100644 --- a/third_party/blink/renderer/core/layout/layout_box_test.cc +++ b/third_party/blink/renderer/core/layout/layout_box_test.cc
@@ -1958,7 +1958,7 @@ EXPECT_FALSE(GetLayoutView().IsUserScrollable()); } -TEST_F(LayoutBoxTest, LogicalTopLogicalLeft) { +TEST_F(LayoutBoxTest, LogicalRectInContainer) { SetBodyInnerHTML(R"HTML(" <style> .c { contain: layout; } @@ -1980,40 +1980,31 @@ constexpr LayoutUnit kTopMargin(3); constexpr LayoutUnit kRightMargin(5); constexpr LayoutUnit kLeftMargin(11); + constexpr LayoutUnit kSize(1); // Target DIVs are placed at (3, 11) from its container top-left. - LayoutBox* target = GetLayoutBoxByElementId("htb-htb"); - EXPECT_EQ(kTopMargin, target->LogicalTop()); - EXPECT_EQ(kLeftMargin, target->LogicalLeft()); - target = GetLayoutBoxByElementId("htb-vrl"); - EXPECT_EQ(kLeftMargin, target->LogicalTop()); - EXPECT_EQ(kTopMargin, target->LogicalLeft()); - target = GetLayoutBoxByElementId("htb-vlr"); - EXPECT_EQ(kLeftMargin, target->LogicalTop()); - EXPECT_EQ(kTopMargin, target->LogicalLeft()); + EXPECT_EQ(LogicalRect(kLeftMargin, kTopMargin, kSize, kSize), + GetLayoutBoxByElementId("htb-htb")->LogicalRectInContainer()); + EXPECT_EQ(LogicalRect(kLeftMargin, kTopMargin, kSize, kSize), + GetLayoutBoxByElementId("htb-vrl")->LogicalRectInContainer()); + EXPECT_EQ(LogicalRect(kLeftMargin, kTopMargin, kSize, kSize), + GetLayoutBoxByElementId("htb-vlr")->LogicalRectInContainer()); - // Container's writing-mode doesn't matter if it is vertical-lr. - target = GetLayoutBoxByElementId("vlr-htb"); - EXPECT_EQ(kTopMargin, target->LogicalTop()); - EXPECT_EQ(kLeftMargin, target->LogicalLeft()); - target = GetLayoutBoxByElementId("vlr-vrl"); - EXPECT_EQ(kLeftMargin, target->LogicalTop()); - EXPECT_EQ(kTopMargin, target->LogicalLeft()); - target = GetLayoutBoxByElementId("vlr-vlr"); - EXPECT_EQ(kLeftMargin, target->LogicalTop()); - EXPECT_EQ(kTopMargin, target->LogicalLeft()); + // Target DIVs are placed at (3, 11) in the vertical-lr container too. + EXPECT_EQ(LogicalRect(kTopMargin, kLeftMargin, kSize, kSize), + GetLayoutBoxByElementId("vlr-htb")->LogicalRectInContainer()); + EXPECT_EQ(LogicalRect(kTopMargin, kLeftMargin, kSize, kSize), + GetLayoutBoxByElementId("vlr-vrl")->LogicalRectInContainer()); + EXPECT_EQ(LogicalRect(kTopMargin, kLeftMargin, kSize, kSize), + GetLayoutBoxByElementId("vlr-vlr")->LogicalRectInContainer()); - // In a vertical-rl container, LogicalTop() and LogicalLeft() return - // flipped-block offsets. - target = GetLayoutBoxByElementId("vrl-htb"); - EXPECT_EQ(kTopMargin, target->LogicalTop()); - EXPECT_EQ(kRightMargin, target->LogicalLeft()); - target = GetLayoutBoxByElementId("vrl-vrl"); - EXPECT_EQ(kRightMargin, target->LogicalTop()); - EXPECT_EQ(kTopMargin, target->LogicalLeft()); - target = GetLayoutBoxByElementId("vrl-vlr"); - EXPECT_EQ(kRightMargin, target->LogicalTop()); - EXPECT_EQ(kTopMargin, target->LogicalLeft()); + // In the vertical-rl container. + EXPECT_EQ(LogicalRect(kTopMargin, kRightMargin, kSize, kSize), + GetLayoutBoxByElementId("vrl-htb")->LogicalRectInContainer()); + EXPECT_EQ(LogicalRect(kTopMargin, kRightMargin, kSize, kSize), + GetLayoutBoxByElementId("vrl-vrl")->LogicalRectInContainer()); + EXPECT_EQ(LogicalRect(kTopMargin, kRightMargin, kSize, kSize), + GetLayoutBoxByElementId("vrl-vlr")->LogicalRectInContainer()); } class LayoutBoxBackgroundPaintLocationTest : public RenderingTest,
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc b/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc index 199aa18..9b373b2 100644 --- a/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc +++ b/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc
@@ -393,8 +393,9 @@ for (const LayoutMultiColumnSet* candidate = FirstMultiColumnSet(); candidate; candidate = candidate->NextSiblingMultiColumnSet()) { column_set = candidate; - if (candidate->LogicalBottom() > block_offset) + if (candidate->LogicalRectInContainer().BlockEndOffset() > block_offset) { break; + } } if (!column_set) { return visual_point;
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.cc b/third_party/blink/renderer/core/layout/layout_replaced.cc index 0f8c311..06220acb 100644 --- a/third_party/blink/renderer/core/layout/layout_replaced.cc +++ b/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -400,13 +400,12 @@ const PhysicalOffset& point) const { NOT_DESTROYED(); - auto converter = LocationContainer()->CreateWritingModeConverter(); - LogicalRect logical_rect = - converter.ToLogical(PhysicalRect(PhysicalLocation(), Size())); + LogicalRect logical_rect = LogicalRectInContainer(); auto [top, bottom] = SelectionTopAndBottom(*this, logical_rect); LogicalOffset logical_point = - converter.ToLogical(point + PhysicalLocation(), {}); + LocationContainer()->CreateWritingModeConverter().ToLogical( + point + PhysicalLocation(), {}); LayoutUnit block_direction_position = logical_point.block_offset; LayoutUnit line_direction_position = logical_point.inline_offset;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc index daa5f67..36d9bab1 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
@@ -122,7 +122,7 @@ void LayoutSVGResourceClipper::RemoveAllClientsFromCache() { NOT_DESTROYED(); clip_content_path_validity_ = kClipContentPathUnknown; - clip_content_path_.Clear(); + clip_content_path_ = Path(); cached_paint_record_ = std::nullopt; local_clip_bounds_ = gfx::RectF(); MarkAllClientsForInvalidation(kClipCacheInvalidation | kPaintInvalidation);
diff --git a/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc b/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc index 1d8e9a72..1675d21 100644 --- a/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc +++ b/third_party/blink/renderer/modules/managed_device/navigator_managed_data.cc
@@ -4,7 +4,10 @@ #include "third_party/blink/renderer/modules/managed_device/navigator_managed_data.h" +#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom-blink.h" +#include "third_party/blink/public/common/features_generated.h" #include "third_party/blink/public/platform/browser_interface_broker_proxy.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/events/event.h" @@ -13,6 +16,8 @@ #include "third_party/blink/renderer/core/frame/navigator.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/modules/event_target_modules.h" +#include "third_party/blink/renderer/platform/bindings/exception_code.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { @@ -29,6 +34,21 @@ "Managed Configuration API is not supported on this platform."; #endif // BUILDFLAG(IS_ANDROID) +const char kDeviceAttributesNotAllowedByPermissionsPolicy[] = + "Permissions-Policy: device-attributes are disabled."; + +bool IsDeviceAttributesPermissionsPolicyFeatureEnabled() { + return RuntimeEnabledFeatures::DeviceAttributesPermissionPolicyEnabled(); +} + +bool AreDeviceAttributesAllowedByPermissionsPolicy(ExecutionContext* context) { + if (!IsDeviceAttributesPermissionsPolicyFeatureEnabled()) { + return true; + } + return context->IsFeatureEnabled( + network::mojom::PermissionsPolicyFeature::kDeviceAttributes); +} + } // namespace const char NavigatorManagedData::kSupplementName[] = "NavigatorManagedData"; @@ -154,16 +174,18 @@ } ScriptPromise<IDLNullable<IDLString>> NavigatorManagedData::getDirectoryId( - ScriptState* script_state) { + ScriptState* script_state, + ExceptionState& exception_state) { + if (!CheckDeviceAttributesAllowed(exception_state)) { + return EmptyPromise(); + } + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLNullable<IDLString>>>( script_state); pending_promises_.insert(resolver); - auto promise = resolver->Promise(); - if (!GetExecutionContext()) { - return promise; - } + GetService()->GetDirectoryId(WTF::BindOnce( &NavigatorManagedData::OnAttributeReceived, WrapWeakPersistent(this), WrapPersistent(script_state), WrapPersistent(resolver))); @@ -171,16 +193,18 @@ } ScriptPromise<IDLNullable<IDLString>> NavigatorManagedData::getHostname( - ScriptState* script_state) { + ScriptState* script_state, + ExceptionState& exception_state) { + if (!CheckDeviceAttributesAllowed(exception_state)) { + return EmptyPromise(); + } + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLNullable<IDLString>>>( script_state); pending_promises_.insert(resolver); - auto promise = resolver->Promise(); - if (!GetExecutionContext()) { - return promise; - } + GetService()->GetHostname(WTF::BindOnce( &NavigatorManagedData::OnAttributeReceived, WrapWeakPersistent(this), WrapPersistent(script_state), WrapPersistent(resolver))); @@ -188,16 +212,18 @@ } ScriptPromise<IDLNullable<IDLString>> NavigatorManagedData::getSerialNumber( - ScriptState* script_state) { + ScriptState* script_state, + ExceptionState& exception_state) { + if (!CheckDeviceAttributesAllowed(exception_state)) { + return EmptyPromise(); + } + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLNullable<IDLString>>>( script_state); pending_promises_.insert(resolver); - auto promise = resolver->Promise(); - if (!GetExecutionContext()) { - return promise; - } + GetService()->GetSerialNumber(WTF::BindOnce( &NavigatorManagedData::OnAttributeReceived, WrapWeakPersistent(this), WrapPersistent(script_state), WrapPersistent(resolver))); @@ -205,16 +231,18 @@ } ScriptPromise<IDLNullable<IDLString>> NavigatorManagedData::getAnnotatedAssetId( - ScriptState* script_state) { + ScriptState* script_state, + ExceptionState& exception_state) { + if (!CheckDeviceAttributesAllowed(exception_state)) { + return EmptyPromise(); + } + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLNullable<IDLString>>>( script_state); pending_promises_.insert(resolver); - auto promise = resolver->Promise(); - if (!GetExecutionContext()) { - return promise; - } + GetService()->GetAnnotatedAssetId(WTF::BindOnce( &NavigatorManagedData::OnAttributeReceived, WrapWeakPersistent(this), WrapPersistent(script_state), WrapPersistent(resolver))); @@ -222,22 +250,39 @@ } ScriptPromise<IDLNullable<IDLString>> -NavigatorManagedData::getAnnotatedLocation(ScriptState* script_state) { +NavigatorManagedData::getAnnotatedLocation(ScriptState* script_state, + ExceptionState& exception_state) { + if (!CheckDeviceAttributesAllowed(exception_state)) { + return EmptyPromise(); + } + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLNullable<IDLString>>>( script_state); pending_promises_.insert(resolver); - auto promise = resolver->Promise(); - if (!GetExecutionContext()) { - return promise; - } + GetService()->GetAnnotatedLocation(WTF::BindOnce( &NavigatorManagedData::OnAttributeReceived, WrapWeakPersistent(this), WrapPersistent(script_state), WrapPersistent(resolver))); return promise; } +bool NavigatorManagedData::CheckDeviceAttributesAllowed( + ExceptionState& exception_state) { + ExecutionContext* const context = GetExecutionContext(); + if (!context) { + return false; + } + if (!AreDeviceAttributesAllowedByPermissionsPolicy(context)) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotAllowedError, + kDeviceAttributesNotAllowedByPermissionsPolicy); + return false; + } + return true; +} + void NavigatorManagedData::OnConfigurationReceived( ScriptPromiseResolver<IDLRecord<IDLString, IDLAny>>* resolver, const std::optional<HashMap<String, String>>& configurations) {
diff --git a/third_party/blink/renderer/modules/managed_device/navigator_managed_data.h b/third_party/blink/renderer/modules/managed_device/navigator_managed_data.h index bc518ce..21f54d7 100644 --- a/third_party/blink/renderer/modules/managed_device/navigator_managed_data.h +++ b/third_party/blink/renderer/modules/managed_device/navigator_managed_data.h
@@ -63,13 +63,19 @@ kManagedconfigurationchange) // Device Attributes API: - ScriptPromise<IDLNullable<IDLString>> getDirectoryId(ScriptState*); - ScriptPromise<IDLNullable<IDLString>> getHostname(ScriptState*); - ScriptPromise<IDLNullable<IDLString>> getSerialNumber(ScriptState*); - ScriptPromise<IDLNullable<IDLString>> getAnnotatedAssetId(ScriptState*); - ScriptPromise<IDLNullable<IDLString>> getAnnotatedLocation(ScriptState*); + ScriptPromise<IDLNullable<IDLString>> getDirectoryId(ScriptState*, + ExceptionState&); + ScriptPromise<IDLNullable<IDLString>> getHostname(ScriptState*, + ExceptionState&); + ScriptPromise<IDLNullable<IDLString>> getSerialNumber(ScriptState*, + ExceptionState&); + ScriptPromise<IDLNullable<IDLString>> getAnnotatedAssetId(ScriptState*, + ExceptionState&); + ScriptPromise<IDLNullable<IDLString>> getAnnotatedLocation(ScriptState*, + ExceptionState&); private: + bool CheckDeviceAttributesAllowed(ExceptionState&); // ManagedConfigurationObserver: void OnConfigurationChanged() override;
diff --git a/third_party/blink/renderer/modules/managed_device/navigator_managed_data.idl b/third_party/blink/renderer/modules/managed_device/navigator_managed_data.idl index d4e6969..3493145 100644 --- a/third_party/blink/renderer/modules/managed_device/navigator_managed_data.idl +++ b/third_party/blink/renderer/modules/managed_device/navigator_managed_data.idl
@@ -14,14 +14,14 @@ attribute EventHandler onmanagedconfigurationchange; // Device Attributes API. - [CallWith=ScriptState, RuntimeEnabled=DeviceAttributes, Measure] + [CallWith=ScriptState, RaisesException, RuntimeEnabled=DeviceAttributes, Measure] Promise<DOMString?> getDirectoryId(); - [CallWith=ScriptState, RuntimeEnabled=DeviceAttributes, Measure] + [CallWith=ScriptState, RaisesException, RuntimeEnabled=DeviceAttributes, Measure] Promise<DOMString?> getHostname(); - [CallWith=ScriptState, RuntimeEnabled=DeviceAttributes, Measure] + [CallWith=ScriptState, RaisesException, RuntimeEnabled=DeviceAttributes, Measure] Promise<DOMString?> getSerialNumber(); - [CallWith=ScriptState, RuntimeEnabled=DeviceAttributes, Measure] + [CallWith=ScriptState, RaisesException, RuntimeEnabled=DeviceAttributes, Measure] Promise<DOMString?> getAnnotatedAssetId(); - [CallWith=ScriptState, RuntimeEnabled=DeviceAttributes, Measure] + [CallWith=ScriptState, RaisesException, RuntimeEnabled=DeviceAttributes, Measure] Promise<DOMString?> getAnnotatedLocation(); };
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc index 7ae20554..34827c65 100644 --- a/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc +++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc
@@ -9,6 +9,7 @@ #include "third_party/blink/renderer/core/html/html_div_element.h" #include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h" #include "third_party/blink/renderer/core/input_type_names.h" +#include "third_party/blink/renderer/core/layout/geometry/logical_rect.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" #include "third_party/blink/renderer/core/resize_observer/resize_observer.h" @@ -33,8 +34,9 @@ // then it will be a nullptr so we should assume zero. blink::LayoutBox* box = segment->GetLayoutBox(); if (box) { - current_width = box->LogicalWidth().ToInt(); - current_left = box->LogicalLeft().ToInt(); + blink::LogicalRect rect = box->LogicalRectInContainer(); + current_width = rect.size.inline_size.ToInt(); + current_left = rect.offset.inline_offset.ToInt(); } // If the width and left has not changed then do not update the segment.
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 6f3f25c5..f43ceda 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
@@ -3324,7 +3324,7 @@ if (!program->LinkStatus(this)) { SynthesizeGLError(GL_INVALID_OPERATION, "getAttribLocation", "program not linked"); - return 0; + return -1; } return ContextGL()->GetAttribLocation(ObjectOrZero(program), name.Utf8().c_str());
diff --git a/third_party/blink/renderer/platform/geometry/path.cc b/third_party/blink/renderer/platform/geometry/path.cc index 1cb943a..451a7dd 100644 --- a/third_party/blink/renderer/platform/geometry/path.cc +++ b/third_party/blink/renderer/platform/geometry/path.cc
@@ -306,10 +306,6 @@ return {gfx::SkPointToPointF(path_.getPoint(0)), 0}; } -void Path::Clear() { - path_.reset(); -} - bool Path::IsEmpty() const { return path_.isEmpty(); } @@ -322,10 +318,6 @@ return path_.isLine(nullptr); } -void Path::SetIsVolatile(bool is_volatile) { - path_.setIsVolatile(is_volatile); -} - void Path::MoveTo(const gfx::PointF& point) { path_.moveTo(gfx::PointFToSkPoint(point)); } @@ -345,42 +337,6 @@ path_.close(); } -void Path::AddEllipse(const gfx::PointF& c, - float radius_x, - float radius_y, - float start_angle, - float end_angle) { - DCHECK(EllipseIsRenderable(start_angle, end_angle)); - DCHECK_GE(start_angle, 0); - DCHECK_LT(start_angle, kTwoPiFloat); - - const SkRect oval = SkRect::MakeLTRB(c.x() - radius_x, c.y() - radius_y, - c.x() + radius_x, c.y() + radius_y); - - const float start_degrees = Rad2deg(start_angle); - const float sweep_degrees = Rad2deg(end_angle - start_angle); - - // We can't use SkPath::addOval(), because addOval() makes a new sub-path. - // addOval() calls moveTo() and close() internally. - - // Use 180, not 360, because SkPath::arcTo(oval, angle, 360, false) draws - // nothing. - // TODO(fmalita): we should fix that in Skia. - if (WebCoreFloatNearlyEqual(std::abs(sweep_degrees), 360)) { - // incReserve() results in a single allocation instead of multiple as is - // done by multiple calls to arcTo(). - path_.incReserve(10, 5, 4); - // SkPath::arcTo can't handle the sweepAngle that is equal to or greater - // than 2Pi. - const float sweep180 = std::copysign(180, sweep_degrees); - path_.arcTo(oval, start_degrees, sweep180, false); - path_.arcTo(oval, start_degrees + sweep180, sweep180, false); - return; - } - - path_.arcTo(oval, start_degrees, sweep_degrees, false); -} - Path Path::MakeRect(const gfx::RectF& rect) { return PathBuilder().AddRect(rect).Finalize(); } @@ -404,10 +360,6 @@ return PathBuilder().AddEllipse(center, radius_x, radius_y).Finalize(); } -void Path::AddPath(const Path& src, const AffineTransform& transform) { - path_.addPath(src.GetSkPath(), transform.ToSkMatrix()); -} - void Path::Translate(const gfx::Vector2dF& offset) { path_.offset(offset.x(), offset.y()); }
diff --git a/third_party/blink/renderer/platform/geometry/path.h b/third_party/blink/renderer/platform/geometry/path.h index 559aee0..3b92de7 100644 --- a/third_party/blink/renderer/platform/geometry/path.h +++ b/third_party/blink/renderer/platform/geometry/path.h
@@ -139,16 +139,10 @@ SkScalar accumulated_length_; }; - void Clear(); bool IsEmpty() const; bool IsClosed() const; bool IsLine() const; - // Specify whether this path is volatile. Temporary paths that are discarded - // or modified after use should be marked as volatile. This is a hint to the - // device to not cache this path. - void SetIsVolatile(bool); - // TODO(crbug.com/378688986): convert clients to PathBuilder and remove all // editing (non-const) methods. void MoveTo(const gfx::PointF&); @@ -158,8 +152,6 @@ const gfx::PointF& end_point); void CloseSubpath(); - void AddPath(const Path&, const AffineTransform&); - void Translate(const gfx::Vector2dF&); const SkPath& GetSkPath() const { return path_; } @@ -179,11 +171,6 @@ float radius_y); private: - void AddEllipse(const gfx::PointF&, - float radius_x, - float radius_y, - float start_angle, - float end_angle); SkPath StrokePath(const StrokeData&, float stroke_precision) const; SkPath path_;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 510d41f..74dc808 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1529,6 +1529,10 @@ }, }, { + name: "DeviceAttributesPermissionPolicy", + status: "experimental", + }, + { name: "DeviceBoundSessionCredentials", origin_trial_feature_name: "DeviceBoundSessionCredentials", origin_trial_os: ["win"], @@ -1789,11 +1793,13 @@ // controls visibility. { name: "DynamicSafeAreaInsets", + status: {"Android": "stable"}, }, // Dynamically change the safe area insets as browser controls scrolls. { name: "DynamicSafeAreaInsetsOnScroll", - depends_on: ["DynamicSafeAreaInsets"] + depends_on: ["DynamicSafeAreaInsets"], + status: {"Android": "stable"}, }, { // Fix for https://crbug.com/40821646. When enabled, it prevents
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 5923860..63e9570 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -308111,138 +308111,6 @@ {} ] ], - "reftests": { - "discard-check-remove-duplicate.svg": [ - "e99e7b0e5776acdf446f0d3a5c671b71100b688c", - [ - null, - [ - [ - "/svg/animations/reftests/reference/green-100x100.svg", - "==" - ] - ], - {} - ] - ], - "discard-check-remove-duplicate2.svg": [ - "aae13b64988a13adb5ff42da2636c2def382d7e9", - [ - null, - [ - [ - "/svg/animations/reftests/reference/green-100x100.svg", - "==" - ] - ], - {} - ] - ], - "discard-check-remove-replace.svg": [ - "efca35c13689dcfe043c81bca94cbeef23be6be3", - [ - null, - [ - [ - "/svg/animations/reftests/reference/green-100x100.svg", - "==" - ] - ], - {} - ] - ], - "discard-check-remove-replace2.svg": [ - "20c61bb985ca7398a164b01ecdacae41674258dc", - [ - null, - [ - [ - "/svg/animations/reftests/reference/green-100x100.svg", - "==" - ] - ], - {} - ] - ], - "discard-check-remove.svg": [ - "a63eee29c93f2f295e26ad6e5ecf96b59dc519fa", - [ - null, - [ - [ - "/svg/animations/reftests/reference/green-100x100.svg", - "==" - ] - ], - {} - ] - ], - "discard-check-remove2.html": [ - "92ecaec9d2137f9c70c1160af24536800f50ec53", - [ - null, - [ - [ - "/svg/animations/reftests/reference/green-100x100.svg", - "==" - ] - ], - {} - ] - ], - "discard-rect-as-child.svg": [ - "93e14c0d73e6ea14d910507047a3ba00c637cf74", - [ - null, - [ - [ - "/svg/animations/reftests/reference/green-100x100.svg", - "==" - ] - ], - {} - ] - ], - "discard-rect-as-href.svg": [ - "e9cf560991e86f9751b20ac7cd1a6227ad3d5861", - [ - null, - [ - [ - "/svg/animations/reftests/reference/green-100x100.svg", - "==" - ] - ], - {} - ] - ], - "discard-rect-with-anim-child-a.svg": [ - "57e6cb2d442a67284d8eed3690d47228bf8de28b", - [ - null, - [ - [ - "/svg/animations/reftests/reference/green-100x100.svg", - "==" - ] - ], - {} - ] - ], - "discard-rect-with-anim-child-b.svg": [ - "5b1fc113c4fac8f28357e1c2fced67786fd91138", - [ - null, - [ - [ - "/svg/animations/reftests/reference/green-100x100.svg", - "==" - ] - ], - {} - ] - ] - }, "scripted": { "animateMotion-animated-line.svg": [ "5e853dab03a547f2e963e0ecc51048a9ea3ea307", @@ -318985,7 +318853,7 @@ ], "support": { "clear-cache-helper.sub.js": [ - "2b2d35abfc571969f414d6f8f7d61f9ac189f284", + "5db0caf834cbf6a598f02761beda267dc8f1bcf8", [] ], "clear-site-data-cache.py": [ @@ -388210,7 +388078,7 @@ [] ], "helper.sub.js": [ - "a1d18d108e808ba128a200ab4c0ee0f5d64e3ccb", + "7df1a30549ae428908e6dd51236dd6c76db6c6d1", [] ], "inflight-fetch-helper.js": [ @@ -393315,7 +393183,7 @@ }, "yaml": { "color_space.yaml": [ - "0582f4953470c05d1b0f0704d40e778ebfc4dff1", + "118ca1e4d3880ca543d29a3203f3f664745621f5", [] ], "color_type.yaml": [ @@ -393359,7 +393227,7 @@ [] ], "pixel-manipulation.yaml": [ - "6721f5ffde52ac54372d6e6dbb6f0511baf58a3f", + "0dfa9a4329e067fdcdb21a075b24c7d837212703", [] ], "reset.yaml": [ @@ -423603,14 +423471,18 @@ [] ], "storage-access-beyond-cookies-iframe-iframe.html": [ - "44ac9cd8986067b611196836210511b07bbb2a61", + "9c0bd0194accfb9cd15f5d80707919e54c497c62", [] ], "storage-access-beyond-cookies-iframe.sub.html": [ - "7d43a06bc7eeb942c498f52856eb7e50b37b26b0", + "45fd60b834ae5f9c1d6741f0fb3fb5515f79047a", [] ] }, + "storage-access-beyond-cookies.BlobURLDedicatedWorker.sub.https.tentative.window-expected.txt": [ + "29c9c6525cebe703e920d6b02e155c6f48a4c3ef", + [] + ], "storage-access-beyond-cookies.SharedWorker.sub.https.window-expected.txt": [ "62f9206e3ca86c0f2f2d50a6f52b72fe53bb4ea1", [] @@ -471877,6 +471749,16 @@ ] }, "clear-site-data": { + "clear-cache-bfcache.sub.https.html": [ + "61d810f453b827946cb6ef943b4509b24e5f3246", + [ + null, + { + "testdriver": true, + "timeout": "long" + } + ] + ], "clear-cache-partitioning.https.html": [ "2deadeef2d0853d08a559a9af8050646fb8e3163", [ @@ -519719,6 +519601,13 @@ {} ] ], + "3d-point-mapping-coplanar.html": [ + "0ae0ab1ee483f627c9a1142f82d9976ce7ee5a3c", + [ + null, + {} + ] + ], "3d-rendering-context-behavior.html": [ "94e476c3426b53c96b6b1a7ebb70d7f0586e8313", [ @@ -610351,6 +610240,27 @@ {} ] ], + "2d.imageData.createImageBitmap.p3.rgba.unorm8.html": [ + "09d12ff82bc12ef093bf41524e71496a8c935484", + [ + null, + {} + ] + ], + "2d.imageData.createImageBitmap.srgb.rgba.float16.html": [ + "61519ebce984004d58a7b74f01c1ed38402c1ba7", + [ + null, + {} + ] + ], + "2d.imageData.createImageBitmap.srgb.rgba.unorm8.html": [ + "eee3846cf5aba02583a9ea7fcb31b194f79effa6", + [ + null, + {} + ] + ], "2d.imageData.get.basic.html": [ "71b2d5ab2f205d987b2ac187133d34a897e625fd", [ @@ -610519,6 +610429,13 @@ {} ] ], + "2d.imageData.object.ctor.pixelFormat.html": [ + "9d4c4ccc7ee04dd8ee08f6059b437a902e1bc7f7", + [ + null, + {} + ] + ], "2d.imageData.object.ctor.size.bounds.html": [ "5ea899ac861aac26bf97320213370d88f9372bab", [ @@ -610541,7 +610458,7 @@ ] ], "2d.imageData.object.properties.html": [ - "de586fda3ff90d9f879bb2f4c530d5dae7b93c48", + "72f314bf66035ae3664d360e437f80ad7dfb716a", [ null, {} @@ -610596,6 +610513,13 @@ {} ] ], + "2d.imageData.put.basic.rgba.float16.html": [ + "8307f7fda46883e1ec6e6d2430e9bc6f9532aac5", + [ + null, + {} + ] + ], "2d.imageData.put.clip.html": [ "f61fa4f5e9b4bb3f181f55beb20a8ea489f4da95", [ @@ -612410,7 +612334,7 @@ ] ], "2d.color.space.p3.to.srgb.html": [ - "8320a2948517ce39da51a6e89c6b289414a539da", + "abfda62cb522d97b56e391bc687fdb91ebf29a52", [ null, {} @@ -622827,6 +622751,48 @@ {} ] ], + "2d.imageData.createImageBitmap.p3.rgba.unorm8.html": [ + "4712a13acfd26b11522c5614d8f3bc6c5ed6f7c5", + [ + null, + {} + ] + ], + "2d.imageData.createImageBitmap.p3.rgba.unorm8.worker.js": [ + "51034aad72c5df91b5d00e8ce3edbb0c3372857c", + [ + "html/canvas/offscreen/pixel-manipulation/2d.imageData.createImageBitmap.p3.rgba.unorm8.worker.html", + {} + ] + ], + "2d.imageData.createImageBitmap.srgb.rgba.float16.html": [ + "3b31076d7c791e72b1a13454324d30caa8b23325", + [ + null, + {} + ] + ], + "2d.imageData.createImageBitmap.srgb.rgba.float16.worker.js": [ + "c0e2b265600cb6f699af2824598b3f6ba93d1b87", + [ + "html/canvas/offscreen/pixel-manipulation/2d.imageData.createImageBitmap.srgb.rgba.float16.worker.html", + {} + ] + ], + "2d.imageData.createImageBitmap.srgb.rgba.unorm8.html": [ + "687ffc2a29ea4eca2b5760b4f261133c608196f4", + [ + null, + {} + ] + ], + "2d.imageData.createImageBitmap.srgb.rgba.unorm8.worker.js": [ + "77993c46b4cc8f81b16bdd6c7d44a6ccef9ae48b", + [ + "html/canvas/offscreen/pixel-manipulation/2d.imageData.createImageBitmap.srgb.rgba.unorm8.worker.html", + {} + ] + ], "2d.imageData.get.basic.html": [ "c92771eab51798806f7440983fd9f630a4a2d638", [ @@ -623122,14 +623088,14 @@ ] ], "2d.imageData.object.properties.html": [ - "f936938b7fc6b9bea322952de0426965c42ffdec", + "5c334ceb301c96f7754cef7af1f3bfd199805f2c", [ null, {} ] ], "2d.imageData.object.properties.worker.js": [ - "e428e0d4fcead269bcc1c85a1212386754e129d6", + "6c2026c8eae371c15593b387d97e77d3d2ea5960", [ "html/canvas/offscreen/pixel-manipulation/2d.imageData.object.properties.worker.html", {} @@ -623226,6 +623192,20 @@ {} ] ], + "2d.imageData.put.basic.rgba.float16.html": [ + "f8bd9ad8a731812e78756b4760a0a12e40067e39", + [ + null, + {} + ] + ], + "2d.imageData.put.basic.rgba.float16.worker.js": [ + "06496eae05f0c41e01fb36814d52f8f481bdbccd", + [ + "html/canvas/offscreen/pixel-manipulation/2d.imageData.put.basic.rgba.float16.worker.html", + {} + ] + ], "2d.imageData.put.basic.worker.js": [ "6a68ffa792eea103ed9dada38ae6dc36f89d8c5c", [ @@ -626641,14 +626621,14 @@ ] ], "2d.color.space.p3.to.srgb.html": [ - "0197c10ad2882fae964b8963e32961791816a2ed", + "7d22528bc5b6878a565e358f7cf62e327396e5d9", [ null, {} ] ], "2d.color.space.p3.to.srgb.worker.js": [ - "da84a683bcfadaae54c5f31cf63a0bf50b661514", + "13ee21933dbfc3a6cf5f0a1eae945f1f7f573e5f", [ "html/canvas/offscreen/wide-gamut-canvas/2d.color.space.p3.to.srgb.worker.html", {} @@ -712245,6 +712225,24 @@ } ] ], + "storage-access-beyond-cookies.BlobURLDedicatedWorker.sub.https.tentative.window.js": [ + "2d04c2ee405fcff67dd0e6e79fbddc385ef05510", + [ + "storage-access-api/storage-access-beyond-cookies.BlobURLDedicatedWorker.sub.https.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/resources/testdriver-vendor.js" + ] + ] + } + ] + ], "storage-access-beyond-cookies.BroadcastChannel.sub.https.window.js": [ "feb268b4b8146290eec743779c4a8d9567bc74b3", [ @@ -725148,6 +725146,13 @@ {} ] ], + "historical.html": [ + "2a807125296bac8f2338ac9e1b94a0c42a2ac409", + [ + null, + {} + ] + ], "interval-restart-events.html": [ "3c3ad89a3230bb03048dc3fc9727558de511bee9", [ @@ -726367,7 +726372,7 @@ ] ], "script-content.svg": [ - "94836f7c0331cb8a1caebacef02a75018b2b4ddb", + "b882160b4e68d4eeb27cc498d2f3ed8967bbdd7d", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/clear-site-data/clear-cache-bfcache.sub.https.html b/third_party/blink/web_tests/external/wpt/clear-site-data/clear-cache-bfcache.sub.https.html new file mode 100644 index 0000000..61d810f4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/clear-site-data/clear-cache-bfcache.sub.https.html
@@ -0,0 +1,115 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<title>Clear-Site-Data: cache for bfcache</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="support/clear-cache-helper.sub.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="/common/utils.js"></script> +<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script> +<script type="module"> + +const sameOrigin = + 'https://{{host}}:{{ports[https][0]}}'; +const subdomainOrigin = + 'https://{{hosts[][www2]}}:{{ports[https][0]}}'; +const crossSiteOrigin = + 'https://{{hosts[alt][]}}:{{ports[https][0]}}'; + +// The tests are built on top of the back-forward-cache test harness. +// Here is the steps for the tests: +// 1. Open a new window and navigate to a test URL. +// 2. Navigate the window to a second page. +// 3. Trigger the clear-site-data header either by window.open() or loading an +// iframe from the second page. +// 4. Navigate back to the first page. +// 5. Assert that the first page is or is not cached. + +function runBfCacheClearTest(params, description) { + runBfcacheTest( + { + targetOrigin: sameOrigin, + scripts: ["/clear-site-data/support/clear-cache-helper.sub.js"], + funcBeforeBackNavigation: async (getUrlParams, mode) => { + + const cacheHelper = self.crypto.randomUUID(); + const testUrl = getUrl(cacheHelper, getUrlParams); + + let clearingPromise; + if (mode === "window") { + clearingPromise = new Promise(resolve => { + window.addEventListener("message", resolve, {once: true}); + window.open(testUrl); + }); + } else if (mode === "iframe") { + clearingPromise = new Promise(resolve => { + const iframe = document.createElement("iframe"); + iframe.src = testUrl; + document.body.appendChild(iframe); + iframe.onload = resolve; + }); + } else { + throw new Error("Unsupported mode"); + } + + await clearingPromise; + }, + argsBeforeBackNavigation: [params.getUrlParams, params.mode], + ...params, + }, + description + ); +} + +runBfCacheClearTest( + { + getUrlParams: { + clear: "cache", + }, + mode: "iframe", + shouldBeCached: false, + }, + "BfCached document shouldn't be cached after receiving clear-cache header from the same origin." +); + +runBfCacheClearTest( + { + targetOrigin: subdomainOrigin, + getUrlParams: { + subdomain: true, + clear: "cache", + }, + mode: "iframe", + shouldBeCached: true, + }, + "BfCached document should be cached after receiving clear-cache header from a subdomain." +); + +runBfCacheClearTest( + { + targetOrigin: crossSiteOrigin, + getUrlParams: { + secondOrigin: true, + clear: "cache", + }, + mode: "iframe", + shouldBeCached: true, + }, + "BfCached document should be cached after receiving clear-cache header from another site." +); + +runBfCacheClearTest( + { + getUrlParams: { + clear: "cache", + }, + mode: "window", + shouldBeCached: false, + }, + "BfCached document shouldn't be cached after receiving clear-cache header from another window." +); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/clear-site-data/support/clear-cache-helper.sub.js b/third_party/blink/web_tests/external/wpt/clear-site-data/support/clear-cache-helper.sub.js index 2b2d35ab..5db0caf 100644 --- a/third_party/blink/web_tests/external/wpt/clear-site-data/support/clear-cache-helper.sub.js +++ b/third_party/blink/web_tests/external/wpt/clear-site-data/support/clear-cache-helper.sub.js
@@ -39,7 +39,7 @@ } else { // !second_origin && !subdomain url += "{{hosts[][]}}"; } - url += ":{{ports[https][1]}}"; + url += ":{{ports[https][0]}}"; url += "/clear-site-data/support/clear-site-data-cache.py"; url = new URL(url); let params = new URLSearchParams(); @@ -130,4 +130,3 @@ openTestPageHelper(test, null, testUrls, 0, assert, resolve) }); } -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-009-ref.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-009-ref.tentative.html new file mode 100644 index 0000000..07b797f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-009-ref.tentative.html
@@ -0,0 +1,40 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Overflow Test Reference: scroll-marker-contain property invalidation - dynamic change of href</title> +<style> + .scroller { + overflow: auto; + height: 130px; + width: 100px; + } + + .scroller div { + width: 100px; + height: 100px; + background-color: blue; + margin: 5px; + } + + a { + color: red; + } + + #target-current { + color: green; + } +</style> +<div> + <a href="#target3">t1</a> + <a id="target-current" href="#target4">t2</a> +</div> +<div class="scroller"> + <div></div> + <div></div> +</div> +<div id="scroller2" class="scroller"> + <div id="target3"></div> + <div id="target4"></div> +</div> +<script> + scroller2.scrollTop = 200; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-009.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-009.tentative.html new file mode 100644 index 0000000..8037adf8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-009.tentative.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Overflow Test: scroll-marker-contain property invalidation - dynamic change of href</title> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/10916"> +<link rel="match" href="scroll-marker-contain-009-ref.tentative.html"> +<style> + #wrapper { + scroll-marker-contain: auto; + } + + .scroller { + overflow: auto; + height: 130px; + width: 100px; + } + + .scroller div { + width: 100px; + height: 100px; + background-color: blue; + margin: 5px; + } + + a { + color: red; + } + + a:target-current { + color: green; + } +</style> +<div id="wrapper"> + <a id="link1" href="#target1">t1</a> + <a id="link2" href="#target2">t2</a> +</div> +<div id="scroller1" class="scroller"> + <div id="target1"></div> + <div id="target2"></div> +</div> +<div id="scroller2" class="scroller"> + <div id="target3"></div> + <div id="target4"></div> +</div> +<script> + scroller2.scrollTop = 200; + document.documentElement.offsetTop; + link1.href = "#target3"; + link2.href = "#target4"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-010.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-010.tentative.html new file mode 100644 index 0000000..fbdad62 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-010.tentative.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Overflow Test: scroll-marker-contain property invalidation - dynamic addition of href</title> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/10916"> +<link rel="match" href="scroll-marker-contain-009-ref.tentative.html"> +<style> + #wrapper { + scroll-marker-contain: auto; + } + + .scroller { + overflow: auto; + height: 130px; + width: 100px; + } + + .scroller div { + width: 100px; + height: 100px; + background-color: blue; + margin: 5px; + } + + a { + color: red; + } + + a:target-current { + color: green; + } +</style> +<div id="wrapper"> + <a id="link1">t1</a> + <a id="link2">t2</a> +</div> +<div id="scroller1" class="scroller"> + <div id="target1"></div> + <div id="target2"></div> +</div> +<div id="scroller2" class="scroller"> + <div id="target3"></div> + <div id="target4"></div> +</div> +<script> + scroller2.scrollTop = 200; + document.documentElement.offsetTop; + link1.href = "#target3"; + link2.href = "#target4"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-011.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-011.tentative.html new file mode 100644 index 0000000..8cfc7813 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-contain-011.tentative.html
@@ -0,0 +1,48 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Overflow Test: scroll-marker-contain property invalidation - dynamic removal of href</title> +<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/10916"> +<link rel="match" href="scroll-marker-contain-009-ref.tentative.html"> +<style> + #wrapper { + scroll-marker-contain: auto; + } + + .scroller { + overflow: auto; + height: 130px; + width: 100px; + } + + .scroller div { + width: 100px; + height: 100px; + background-color: blue; + margin: 5px; + } + + a { + color: red; + } + + a:target-current { + color: green; + } +</style> +<div id="wrapper"> + <a id="link1" href="#target1">t1</a> + <a id="link2" href="#target2">t2</a> +</div> +<div id="scroller1" class="scroller"> + <div id="target1"></div> + <div id="target2"></div> +</div> +<div id="scroller2" class="scroller"> + <div id="target3"></div> + <div id="target4"></div> +</div> +<script> + scroller2.scrollTop = 200; + document.documentElement.offsetTop; + link1.href = ""; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/3d-point-mapping-overlapping.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/3d-point-mapping-overlapping.html new file mode 100644 index 0000000..ffcfc1a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/3d-point-mapping-overlapping.html
@@ -0,0 +1,115 @@ +<!DOCTYPE html> +<title>Hit test overlapping elements</title> +<link rel="help" href="https://svgwg.org/svg2-draft/interact.html#hit-testing"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style type="text/css" media="screen"> + body { + margin: 0; + } + + #box1 { + position: absolute; + height: 300px; + width: 300px; + background-color: #DDD; + } + + #box2 { + position: absolute; + top: 50px; + left: 50px; + height: 200px; + width: 200px; + background-color: #AAA; + transform: translateZ(50px); + } + + #box3 { + position: relative; + background-color: blue; + height: 100px; + width: 100px; + margin: 50px; + } + + #overlay { + position: absolute; + height: 310px; + width: 150px; + background-color: rgba(0, 128, 0, 0.3); + transform: translateZ(100px); + } +</style> + +<body> + <div id="box1"> + <div id="box2"> + <div id="box3"></div> + </div> + <div id="overlay"></div> + </div> +</body> + +<script> + class Point { + constructor(x, y) { + this.x = x; + this.y = y; + } + }; + const tests = [{ + expectedElemId: 'box1', + points: [ + new Point(151, 254), + new Point(152, 47), + new Point(288, 13), + new Point(289, 283), + ] + }, + { + expectedElemId: 'box2', + points: [ + new Point(158, 229), + new Point(206, 220), + new Point(223, 158), + new Point(157, 57), + ] + }, + { + expectedElemId: 'box3', + points: [ + new Point(157, 191), + new Point(193, 190), + new Point(196, 103), + new Point(152, 108), + ] + }, + { + // Two points over every box. + expectedElemId: 'overlay', + points: [ + new Point(132, 178), + new Point(125, 113), + new Point(81, 67), + new Point(92, 223), + new Point(32, 270), + new Point(28, 21), + ] + } + ]; + + tests.forEach(testcase => { + test(t => { + const expectedElem = document.getElementById(testcase.expectedElemId); + for (const point of testcase.points) { + const hitElem = document.elementFromPoint(point.x, point.y); + assert_equals(hitElem, expectedElem, + `point (${point.x}, ${point.y}) is inside element ${testcase.expectedElemId}`); + } + }, `${document.title}, hittesting ${testcase.expectedElemId})`); + }); +</script> + +</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/trust-token-redemption-supported-by-feature-policy.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/trust-token-redemption-supported-by-feature-policy.tentative-expected.txt index 352385b0..3afa9fc 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/trust-token-redemption-supported-by-feature-policy.tentative-expected.txt +++ b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/trust-token-redemption-supported-by-feature-policy.tentative-expected.txt
@@ -1,6 +1,6 @@ This is a testharness.js-based test. [FAIL] document.featurePolicy.features should advertise trust token redemption. - assert_in_array: value "trust-token-redemption" not in array ["geolocation", "ch-ua-full-version-list", "cross-origin-isolated", "screen-wake-lock", "translator", "execution-while-out-of-viewport", "publickey-credentials-get", "shared-storage-select-url", "ch-ua-arch", "bluetooth", "compute-pressure", "focus-without-user-activation", "ch-prefers-reduced-transparency", "deferred-fetch", "web-app-installation", "usb", "ch-save-data", "publickey-credentials-create", "shared-storage", "deferred-fetch-minimal", "rewriter", "run-ad-auction", "ch-downlink", "ch-ua-form-factors", "otp-credentials", "payment", "ch-ua", "ch-ua-model", "ch-ect", "autoplay", "camera", "language-detector", "private-state-token-issuance", "digital-credentials-get", "accelerometer", "ch-ua-platform-version", "idle-detection", "private-aggregation", "speaker-selection", "interest-cohort", "ch-viewport-height", "captured-surface-control", "local-fonts", "ch-ua-platform", "midi", "ch-ua-full-version", "shared-autofill", "xr-spatial-tracking", "clipboard-read", "gamepad", "popins", "writer", "display-capture", "keyboard-map", "join-ad-interest-group", "ch-ua-high-entropy-values", "ch-width", "ch-prefers-reduced-motion", "browsing-topics", "encrypted-media", "gyroscope", "serial", "ch-rtt", "ch-ua-mobile", "window-management", "vertical-scroll", "unload", "ch-dpr", "ch-prefers-color-scheme", "execution-while-not-rendered", "ch-ua-wow64", "attribution-reporting", "fullscreen", "identity-credentials-get", "private-state-token-redemption", "hid", "summarizer", "ch-ua-bitness", "storage-access", "sync-xhr", "ch-device-memory", "ch-viewport-width", "picture-in-picture", "magnetometer", "clipboard-write", "media-playback-while-not-visible", "microphone", "ambient-light-sensor"] + assert_in_array: value "trust-token-redemption" not in array ["geolocation", "ch-ua-full-version-list", "cross-origin-isolated", "screen-wake-lock", "translator", "execution-while-out-of-viewport", "publickey-credentials-get", "shared-storage-select-url", "ch-ua-arch", "bluetooth", "compute-pressure", "focus-without-user-activation", "ch-prefers-reduced-transparency", "deferred-fetch", "web-app-installation", "usb", "ch-save-data", "publickey-credentials-create", "shared-storage", "deferred-fetch-minimal", "rewriter", "run-ad-auction", "ch-downlink", "ch-ua-form-factors", "otp-credentials", "payment", "ch-ua", "ch-ua-model", "ch-ect", "autoplay", "camera", "language-detector", "private-state-token-issuance", "digital-credentials-get", "accelerometer", "ch-ua-platform-version", "idle-detection", "private-aggregation", "speaker-selection", "interest-cohort", "ch-viewport-height", "captured-surface-control", "local-fonts", "ch-ua-platform", "midi", "ch-ua-full-version", "shared-autofill", "xr-spatial-tracking", "clipboard-read", "gamepad", "popins", "writer", "display-capture", "keyboard-map", "join-ad-interest-group", "device-attributes", "ch-ua-high-entropy-values", "ch-width", "ch-prefers-reduced-motion", "browsing-topics", "encrypted-media", "gyroscope", "serial", "ch-rtt", "ch-ua-mobile", "window-management", "vertical-scroll", "unload", "ch-dpr", "ch-prefers-color-scheme", "execution-while-not-rendered", "ch-ua-wow64", "attribution-reporting", "fullscreen", "identity-credentials-get", "private-state-token-redemption", "hid", "summarizer", "ch-ua-bitness", "storage-access", "sync-xhr", "ch-device-memory", "ch-viewport-width", "picture-in-picture", "magnetometer", "clipboard-write", "media-playback-while-not-visible", "microphone", "ambient-light-sensor"] Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js index a1d18d1..7df1a305 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js
@@ -105,7 +105,7 @@ runBfcacheTest(params, description); } -async function navigateAndThenBack(pageA, pageB, urlB, +async function navigateAndThenBack(pageA, pageB, urlB, scripts = [], funcBeforeBackNavigation, argsBeforeBackNavigation) { await pageA.execute_script( @@ -118,6 +118,16 @@ ); await pageB.execute_script(waitForPageShow); + + for (const src of scripts) { + await pageB.execute_script((src) => { + const script = document.createElement("script"); + script.src = src; + document.head.append(script); + return new Promise(resolve => script.onload = resolve); + }, [src]); + } + if (funcBeforeBackNavigation) { await pageB.execute_script(funcBeforeBackNavigation, argsBeforeBackNavigation); @@ -172,7 +182,7 @@ await pageA.execute_script(params.funcBeforeNavigation, params.argsBeforeNavigation); - await navigateAndThenBack(pageA, pageB, urlB, + await navigateAndThenBack(pageA, pageB, urlB, params.scripts, params.funcBeforeBackNavigation, params.argsBeforeBackNavigation);
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/historical.html b/third_party/blink/web_tests/external/wpt/svg/animations/historical.html new file mode 100644 index 0000000..2a80712 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/animations/historical.html
@@ -0,0 +1,29 @@ +<!doctype html> +<html> +<meta charset="utf-8"> +<title>Historical features of SVG Animation</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<svg width="100" height="100" id="test-discard"> + <rect x="0" y="0" width="50" height="50" fill="black" transform="translate(0, 0)"> + <animateTransform attributeName="transform" begin="0s" dur="0.1s" from="0, 0" to="50, 50"/> + <discard begin="0.1s"/> + </rect> +</svg> + +<script> +async_test(t => { + const testDiscardEl = document.getElementById('test-discard'); + t.step_timeout(() => { + for (const tag of ["rect", "animateTransform", "discard"]) { + assert_not_equals(testDiscardEl.querySelector(tag), null, tag); + } + t.done(); + }, 500); +}, 'discard element'); + +test(() => { + assert_equals(window.SVGDiscardElement, undefined); +}, 'SVGDiscardElement'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-duplicate.svg b/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-duplicate.svg deleted file mode 100644 index e99e7b0..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-duplicate.svg +++ /dev/null
@@ -1,30 +0,0 @@ -<svg onload="startTest()" xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" class="reftest-wait"> - <title>discard element removes the element it references and itself</title> - <h:link rel="help" href="https://svgwg.org/specs/animations/#DiscardElement"/> - <h:link rel="match" href="reference/green-100x100.svg"/> - <h:script src="/common/rendering-utils.js"/> - <h:script src="/common/reftest-wait.js"/> - - <rect id="r1" width="100" height="100" fill="green"/> - <rect id="r2" width="100" height="100" fill="red" /> - <discard id="discard1" href="#r2" begin="2s"/> - <discard id="discard2" href="#r2" begin="2s"/> - <set attributeName="display" to="inline" begin="2.01s" dur="1s" fill="freeze" onbegin="checkDelete()"/> - - <script> - function startTest() { - document.documentElement.setCurrentTime(2); - } - - function checkDelete() { - let d1 = document.getElementById("discard1"); - let d2 = document.getElementById("discard2"); - let r2 = document.getElementById("r2"); - - if (d1 || d2 || r2) { - document.getElementById("r1").setAttribute("fill", "orange"); - } - takeScreenshot(); - } - </script> -</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-duplicate2.svg b/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-duplicate2.svg deleted file mode 100644 index aae13b6..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-duplicate2.svg +++ /dev/null
@@ -1,34 +0,0 @@ -<svg onload="startTest()" xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" class="reftest-wait"> - <title>discard element removes the element it references and itself</title> - <h:link rel="help" href="https://svgwg.org/specs/animations/#DiscardElement"/> - <h:link rel="match" href="reference/green-100x100.svg"/> - <h:script src="/common/rendering-utils.js"/> - <h:script src="/common/reftest-wait.js"/> - - <rect id="r1" width="100" height="100" fill="yellow"/> - <rect id="r2" width="100" height="100" fill="red" /> - <rect id="r2" x="0" width="100" height="100" fill="red" /> - <discard id="discard1" href="#r2" begin="2s"/> - <discard id="discard2" href="#r2" begin="2s"/> - <set attributeName="display" to="inline" begin="2.01s" dur="1s" fill="freeze" onbegin="checkDelete()"/> - - <script><![CDATA[ - function startTest() { - document.documentElement.setCurrentTime(2); - } - - function checkDelete() { - let d1 = document.getElementById("discard1"); - let d2 = document.getElementById("discard2"); - let r2 = document.getElementById("r2"); - - if (d1 || d2) { - document.getElementById("r1").setAttribute("fill", "orange"); - } - if (r2 && r2.hasAttribute("x")) { - document.getElementById("r2").setAttribute("fill", "green"); - } - takeScreenshot(); - } - ]]></script> -</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-replace.svg b/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-replace.svg deleted file mode 100644 index efca35c1..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-replace.svg +++ /dev/null
@@ -1,26 +0,0 @@ -<svg onload="startTest()" xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" class="reftest-wait"> - <title>discard element removes the element it references and itself</title> - <h:link rel="help" href="https://svgwg.org/specs/animations/#DiscardElement"/> - <h:link rel="match" href="reference/green-100x100.svg"/> - <h:script src="/common/rendering-utils.js"/> - <h:script src="/common/reftest-wait.js"/> - - <rect id="r1" width="100" height="100" fill="orange"/> - <rect id="r2" width="100" height="100" fill="red" /> - <discard href="#r2" begin="2s"/> - <set attributeName="display" to="inline" begin="2.01s" dur="1s" fill="freeze" onbegin="checkDelete()"/> - - <script> - let r2 = document.getElementById("r2"); - - function startTest() { - document.documentElement.setCurrentTime(2); - } - - function checkDelete() { - document.documentElement.appendChild(r2); - r2.setAttribute("fill", "green"); - takeScreenshot(); - } - </script> -</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-replace2.svg b/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-replace2.svg deleted file mode 100644 index 20c61bb..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove-replace2.svg +++ /dev/null
@@ -1,31 +0,0 @@ -<svg onload="startTest()" xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" class="reftest-wait"> - <title>discard element removes the element it references and itself</title> - <h:link rel="help" href="https://svgwg.org/specs/animations/#DiscardElement"/> - <h:link rel="match" href="reference/green-100x100.svg"/> - <h:script src="/common/rendering-utils.js"/> - <h:script src="/common/reftest-wait.js"/> - - <rect id="r1" width="100" height="100" fill="green"/> - <rect id="r2" width="100" height="100" fill="red" /> - <discard id="discard" href="#r2" begin="2s"/> - <set attributeName="display" to="inline" begin="2.01s" dur="1s" fill="freeze" onbegin="undelete()"/> - <set attributeName="display" to="inline" begin="2.02s" dur="1s" fill="freeze" onbegin="checkDelete()"/> - - <script> - let r2 = document.getElementById("r2"); - let discard = document.getElementById("discard"); - - function startTest() { - document.documentElement.setCurrentTime(2); - } - - function undelete() { - document.documentElement.appendChild(r2); - document.documentElement.appendChild(discard); - } - - function checkDelete() { - takeScreenshot(); - } - </script> -</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove.svg b/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove.svg deleted file mode 100644 index a63eee29..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove.svg +++ /dev/null
@@ -1,28 +0,0 @@ -<svg onload="startTest()" xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" class="reftest-wait"> - <title>discard element removes the element it references and itself</title> - <h:link rel="help" href="https://svgwg.org/specs/animations/#DiscardElement"/> - <h:link rel="match" href="reference/green-100x100.svg"/> - <h:script src="/common/rendering-utils.js"/> - <h:script src="/common/reftest-wait.js"/> - - <rect id="r1" width="100" height="100" fill="green"/> - <rect id="r2" width="100" height="100" fill="red" /> - <discard id="discard1" href="#r2" begin="2s"/> - <set attributeName="display" to="inline" begin="2.01s" dur="1s" fill="freeze" onbegin="checkDelete()"/> - - <script> - function startTest() { - document.documentElement.setCurrentTime(2); - } - - function checkDelete() { - let d1 = document.getElementById("discard1"); - let r2 = document.getElementById("r2"); - - if (d1 || r2) { - document.getElementById("r1").setAttribute("fill", "orange"); - } - takeScreenshot(); - } - </script> -</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove2.html b/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove2.html deleted file mode 100644 index 92ecaec..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-check-remove2.html +++ /dev/null
@@ -1,41 +0,0 @@ -<!doctype html> -<html class="reftest-wait"> -<head> - <meta charset="utf-8"> - <title>discard element removes the element it references and itself</title> - <script src="/common/rendering-utils.js"></script> - <script src="/common/reftest-wait.js"></script> - <link rel="help" href="https://svgwg.org/specs/animations/#DiscardElement"> - <link rel="match" href="reference/green-100x100.svg"> -</head> -<body> - <style> - html, body, svg { - padding: 0; - margin: 0; - } - </style> - <svg onload="startTest()"> - <rect id="r1" width="100" height="100" fill="green"/> - <rect id="r2" width="100" height="100" fill="red" /> - <discard id="discard1" href="#r2" begin="2s"/> - <set attributeName="display" to="inline" begin="2.01s" dur="1s" fill="freeze" onbegin="checkDelete()"/> - - <script> - function startTest() { - document.documentElement.setCurrentTime(2); - } - - function checkDelete() { - let d1 = document.getElementById("discard1"); - let r2 = document.getElementById("r2"); - - if (d1 || r2) { - document.getElementById("r1").setAttribute("fill", "orange"); - } - takeScreenshot(); - } - </script> - </svg> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-as-child.svg b/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-as-child.svg deleted file mode 100644 index 93e14c0d..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-as-child.svg +++ /dev/null
@@ -1,17 +0,0 @@ -<svg onload="startTest()" xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" class="reftest-wait"> - <title>discard element removes its parent by default</title> - <h:link rel="help" href="https://svgwg.org/specs/animations/#DiscardElement"/> - <h:link rel="match" href="reference/green-100x100.svg"/> - <h:script src="/common/rendering-utils.js"/> - <h:script src="/common/reftest-wait.js"/> - <rect width="100" height="100" fill="green"/> - <rect width="100" height="100" fill="red"> - <discard begin="2s"/> - </rect> - <script> - function startTest() { - document.documentElement.setCurrentTime(4); - takeScreenshot(); - } - </script> -</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-as-href.svg b/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-as-href.svg deleted file mode 100644 index e9cf5609..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-as-href.svg +++ /dev/null
@@ -1,16 +0,0 @@ -<svg onload="startTest()" xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" class="reftest-wait"> - <title>discard element removes the element it references</title> - <h:link rel="help" href="https://svgwg.org/specs/animations/#DiscardElement"/> - <h:link rel="match" href="reference/green-100x100.svg"/> - <h:script src="/common/rendering-utils.js"/> - <h:script src="/common/reftest-wait.js"/> - <rect width="100" height="100" fill="green"/> - <rect id="r2" width="100" height="100" fill="red"/> - <discard id="discard1" href="#r2" begin="2s"/> - <script> - function startTest() { - document.documentElement.setCurrentTime(4); - takeScreenshot(); - } - </script> -</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-with-anim-child-a.svg b/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-with-anim-child-a.svg deleted file mode 100644 index 57e6cb2..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-with-anim-child-a.svg +++ /dev/null
@@ -1,18 +0,0 @@ -<svg onload="startTest()" xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" class="reftest-wait"> - <title>discard element removes its parent by default</title> - <h:link rel="help" href="https://svgwg.org/specs/animations/#DiscardElement"/> - <h:link rel="match" href="reference/green-100x100.svg"/> - <h:script src="/common/rendering-utils.js"/> - <h:script src="/common/reftest-wait.js"/> - <rect width="100" height="100" fill="green"/> - <rect width="100" height="100" fill="blue"> - <set attributeName="fill" to="red" begin="2s" fill="freeze" /> - <discard id="discard1" begin="4s"/> - </rect> - <script> - function startTest() { - document.documentElement.setCurrentTime(4); - takeScreenshot(); - } - </script> -</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-with-anim-child-b.svg b/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-with-anim-child-b.svg deleted file mode 100644 index 5b1fc113..0000000 --- a/third_party/blink/web_tests/external/wpt/svg/animations/reftests/discard-rect-with-anim-child-b.svg +++ /dev/null
@@ -1,18 +0,0 @@ -<svg onload="startTest()" xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" class="reftest-wait"> - <title>discard element removes its parent by default</title> - <h:link rel="help" href="https://svgwg.org/specs/animations/#DiscardElement"/> - <h:link rel="match" href="reference/green-100x100.svg"/> - <h:script src="/common/rendering-utils.js"/> - <h:script src="/common/reftest-wait.js"/> - <rect width="100" height="100" fill="green"/> - <rect width="100" height="100" fill="blue"> - <set attributeName="fill" to="red" begin="4s" fill="freeze" /> - <discard begin="2s"/> - </rect> - <script> - function startTest() { - document.documentElement.setCurrentTime(4); - takeScreenshot(); - } - </script> -</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/interact/script-content.svg b/third_party/blink/web_tests/external/wpt/svg/interact/script-content.svg index 94836f7..b882160 100644 --- a/third_party/blink/web_tests/external/wpt/svg/interact/script-content.svg +++ b/third_party/blink/web_tests/external/wpt/svg/interact/script-content.svg
@@ -46,11 +46,9 @@ <script>function s10() { return s11(); }</script> </desc> -<!-- Becomes https://svgwg.org/svg2-draft/struct.html#UnknownElement - if the implementation does not support <discard> --> -<discard> +<unknown> <script>function s11() { return s12(); }</script> -</discard> +</unknown> <ellipse> <script>function s12() { return s13(); }</script>
diff --git a/third_party/blink/web_tests/fast/forms/select/customizable-select/allowed-select-descendants-console-message-expected.txt b/third_party/blink/web_tests/fast/forms/select/customizable-select/allowed-select-descendants-console-message-expected.txt index 2b84e9d..05741d9 100644 --- a/third_party/blink/web_tests/fast/forms/select/customizable-select/allowed-select-descendants-console-message-expected.txt +++ b/third_party/blink/web_tests/fast/forms/select/customizable-select/allowed-select-descendants-console-message-expected.txt
@@ -25,7 +25,7 @@ .. .. - + .. .. .. @@ -64,3 +64,5 @@ .. + +..
diff --git a/third_party/blink/web_tests/fast/forms/select/customizable-select/allowed-select-descendants-console-message.html b/third_party/blink/web_tests/fast/forms/select/customizable-select/allowed-select-descendants-console-message.html index 58932f7..d7cfd3b 100644 --- a/third_party/blink/web_tests/fast/forms/select/customizable-select/allowed-select-descendants-console-message.html +++ b/third_party/blink/web_tests/fast/forms/select/customizable-select/allowed-select-descendants-console-message.html
@@ -141,6 +141,42 @@ <option>..</option> </select> + <!-- <selectedcontent> as descendant of <div>, <span> --> + <select> + <button> + <div> + <selectedcontent></selectedcontent> + </div> + </button> + </select> + + <select> + <button> + <span> + <selectedcontent></selectedcontent> + </span> + </button> + </select> + + <!-- Allowed phrasing content as descendant of <button> and <div> --> + <select> + <button> + <div> + <small>Text</small> + </div> + <small>Text</small> + </button> + </select> + + <select> + <button> + <selectedcontent></selectedcontent> + <svg width="100" height="100"> + <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" /> + </svg> + </button> + </select> + <!-- <selectedcontent> and <option> content with multiple levels of children --> <select> <button> @@ -344,6 +380,18 @@ </option> </select> + <!-- Comments --> + <select> + <!-- 1 --> + <optgroup> + <!-- 2 --> + <option> + <!-- 3 --> + .. + </option> + </optgroup> + </select> + <script> testRunner.dumpAsText(); </script>
diff --git a/third_party/blink/web_tests/platform/linux/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png b/third_party/blink/web_tests/platform/linux/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png deleted file mode 100644 index c47e74d..0000000 --- a/third_party/blink/web_tests/platform/linux/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac14-arm64/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png b/third_party/blink/web_tests/platform/mac-mac14-arm64/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png deleted file mode 100644 index 9587d54..0000000 --- a/third_party/blink/web_tests/platform/mac-mac14-arm64/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png b/third_party/blink/web_tests/platform/mac/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png deleted file mode 100644 index b5a0f33..0000000 --- a/third_party/blink/web_tests/platform/mac/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png b/third_party/blink/web_tests/platform/win/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png deleted file mode 100644 index d982ecfd..0000000 --- a/third_party/blink/web_tests/platform/win/transforms/3d/point-mapping/3d-point-mapping-overlapping-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/transforms/3d/point-mapping/3d-point-mapping-overlapping.html b/third_party/blink/web_tests/transforms/3d/point-mapping/3d-point-mapping-overlapping.html deleted file mode 100644 index fda961e..0000000 --- a/third_party/blink/web_tests/transforms/3d/point-mapping/3d-point-mapping-overlapping.html +++ /dev/null
@@ -1,117 +0,0 @@ -<html> -<head> - <title>Hit test overlapping 3d elements</title> - <script src="point-mapping-helpers.js" type="text/javascript" charset="utf-8"></script> - - <script type="text/javascript" charset="utf-8"> - - function test() - { - dispatchEvent(285, 50, 'box2', 197, 1); - dispatchEvent(174, 108, 'box3', 50, 2); - - dispatchEvent(61, 50, 'overlay', 39, 28); - dispatchEvent(119, 108, 'overlay', 97, 86); - } - - </script> - <style type="text/css" media="screen"> - - body { - margin: 0; - border: 1px solid black; - cursor: crosshair; - } - - .test { - display: inline-block; - position: relative; - height: 300px; - width: 300px; - border: 1px solid black; - margin: 20px; - } - - .box { - height: 200px; - width: 200px; - -webkit-box-sizing: border-box; - background-color: #DDD; - border: 1px solid black; - } - - .box:hover { - outline: 3px solid orange; - } - - .container { - position: absolute; - height: 260px; - width: 260px; - margin: 20px; - border: 1px solid black; - -webkit-box-sizing: border-box; - -webkit-perspective: 400; - } - - .transformed { - position: absolute; - top: 20px; - left: 30px; - height: 200px; - width: 200px; - border: 1px solid black; - background-color: #AAA; - -webkit-box-sizing: border-box; - transform: translateZ(50px); - } - - #overlay { - position: absolute; - height: 300px; - width: 150px; - background-color: rgba(0, 128, 0, 0.3); - transform: translateZ(100px); - } - - .inner { - position: relative; - background-color: blue; - height: 100px; - width: 100px; - margin: 50px; - } - - #results { - position: absolute; - left: 30px; - top: 400px; - } - - #mousepos { - position: absolute; - left: 30px; - top: 700px; - color: gray; - font-size: smaller; - } - </style> -</head> -<body onclick="clicked(event)"> - -<div id="results"></div> -<div class="test"> - <!-- Simple transformed div in perpsective --> - <div class="container box" id="box1"> - <div class="transformed box" id="box2"> - <div class="inner" id="box3"></div> - </div> - </div> - <div id="overlay"></div> -</div> -<p>The green overlay is translated in Z by 100px, so should hit test in front relative to the blue box.</p> - -<div id="mousepos"></div> - -</body> -</html>
diff --git a/third_party/blink/web_tests/virtual/customizable-select-disabled/fast/forms/select/customizable-select/allowed-select-descendants-console-message-expected.txt b/third_party/blink/web_tests/virtual/customizable-select-disabled/fast/forms/select/customizable-select/allowed-select-descendants-console-message-expected.txt index d2630f7..c3b7a30 100644 --- a/third_party/blink/web_tests/virtual/customizable-select-disabled/fast/forms/select/customizable-select/allowed-select-descendants-console-message-expected.txt +++ b/third_party/blink/web_tests/virtual/customizable-select-disabled/fast/forms/select/customizable-select/allowed-select-descendants-console-message-expected.txt
@@ -17,6 +17,20 @@ CONSOLE WARNING: A button tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. CONSOLE WARNING: A selectedcontent tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. CONSOLE WARNING: A button tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A div tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A selectedcontent tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A button tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A span tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A selectedcontent tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A button tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A div tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A small tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A small tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A button tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A selectedcontent tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A svg tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A circle tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. +CONSOLE WARNING: A button tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. CONSOLE WARNING: A selectedcontent tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. CONSOLE WARNING: A span tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. CONSOLE WARNING: A svg tag was parsed inside of a <select> which was not inserted into the document. This is not valid HTML and the behavior may be changed in future versions of chrome. @@ -75,7 +89,7 @@ .. .. - + .. .. .. @@ -114,3 +128,5 @@ .. + +..
diff --git a/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt b/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt index 10301c5..b779d29 100644 --- a/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt +++ b/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt
@@ -38,6 +38,7 @@ cross-origin-isolated deferred-fetch deferred-fetch-minimal +device-attributes digital-credentials-get display-capture encrypted-media
diff --git a/third_party/blink/web_tests/wpt_internal/isolated-permissions-policy/permissions_policy.https.html b/third_party/blink/web_tests/wpt_internal/isolated-permissions-policy/permissions_policy.https.html index 756f04c8..889a100 100644 --- a/third_party/blink/web_tests/wpt_internal/isolated-permissions-policy/permissions_policy.https.html +++ b/third_party/blink/web_tests/wpt_internal/isolated-permissions-policy/permissions_policy.https.html
@@ -49,6 +49,7 @@ 'cross-origin-isolated', 'deferred-fetch', 'deferred-fetch-minimal', + 'device-attributes', 'digital-credentials-get', 'display-capture', 'encrypted-media',
diff --git a/third_party/catapult b/third_party/catapult index 556571f..d451fed 160000 --- a/third_party/catapult +++ b/third_party/catapult
@@ -1 +1 @@ -Subproject commit 556571f9e93b7e4fe6f61c09b0281442722facef +Subproject commit d451fed9573b5eb485dc364514d1ec95f20eadb0
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 3b6a406..e8b639c 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 3b6a4060c03f56f901cb39084b52b5ef1dea16fa +Subproject commit e8b639c4812cbc6276f37fb393da8537422844f8
diff --git a/third_party/llvm-libc/src b/third_party/llvm-libc/src index aa5c758..6df4308 160000 --- a/third_party/llvm-libc/src +++ b/third_party/llvm-libc/src
@@ -1 +1 @@ -Subproject commit aa5c758d870f1a1f2f0b51c960dc96f73a50eb54 +Subproject commit 6df4308a5d808514f7af2e941ba2f0b28133762d
diff --git a/third_party/perfetto b/third_party/perfetto index 745c6d3..181c298 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit 745c6d3fead9008f05ee73172e46d059863b5ab3 +Subproject commit 181c298de2ebe848dad23788d76ae1f517aae6ec
diff --git a/third_party/skia b/third_party/skia index 5f0f9b7..245d2b8 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit 5f0f9b76b975a5c70022a35372bd1618628d3e78 +Subproject commit 245d2b8fb04212b4b7f122f02438a1f0ac62141e
diff --git a/third_party/swiftshader b/third_party/swiftshader index 4982425..2b32337 160000 --- a/third_party/swiftshader +++ b/third_party/swiftshader
@@ -1 +1 @@ -Subproject commit 4982425ff1bdcb2ce52a360edde58a379119bfde +Subproject commit 2b323370501c03d249c91b57fe8585e63960f9e9
diff --git a/third_party/tflite/OWNERS b/third_party/tflite/OWNERS index d8bf21a..b8ada031 100644 --- a/third_party/tflite/OWNERS +++ b/third_party/tflite/OWNERS
@@ -6,3 +6,4 @@ sophiechang@chromium.org tbansal@chromium.org zekunjiang@google.com +wittman@chromium.org
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps index 22fd0de..8ede18e 160000 --- a/third_party/vulkan-deps +++ b/third_party/vulkan-deps
@@ -1 +1 @@ -Subproject commit 22fd0de3755bed1806292e15b640b93e1812bb2b +Subproject commit 8ede18e2d91dfd40c5e71c25f42761519142dd1a
diff --git a/third_party/vulkan-tools/src b/third_party/vulkan-tools/src index 9c0fff2..59dc56a 160000 --- a/third_party/vulkan-tools/src +++ b/third_party/vulkan-tools/src
@@ -1 +1 @@ -Subproject commit 9c0fff2798d769b4c0681001c24d3d55467dde8f +Subproject commit 59dc56aa3023434317a5197d77be51855b5fd2fb
diff --git a/third_party/vulkan-validation-layers/src b/third_party/vulkan-validation-layers/src index 91fd4f2..2d41063e 160000 --- a/third_party/vulkan-validation-layers/src +++ b/third_party/vulkan-validation-layers/src
@@ -1 +1 @@ -Subproject commit 91fd4f29aed4015857822e8edad5004e7e3f90da +Subproject commit 2d41063e90346d2fceca5f40b90e43a7a3368f7b
diff --git a/third_party/wayland-protocols/BUILD.gn b/third_party/wayland-protocols/BUILD.gn index ab56af6..79df6e8 100644 --- a/third_party/wayland-protocols/BUILD.gn +++ b/third_party/wayland-protocols/BUILD.gn
@@ -91,6 +91,10 @@ sources = [ "unstable/notification-shell/notification-shell-unstable-v1.xml" ] } +wayland_protocol("org_kde_kwin_appmenu") { + sources = [ "kde/src/protocols/appmenu.xml" ] +} + wayland_protocol("org_kde_kwin_idle") { sources = [ "kde/src/protocols/idle.xml" ] }
diff --git a/third_party/webrtc b/third_party/webrtc index 5ed7ffd..74b5100 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit 5ed7ffd7ff73d95bf87d85de4eb469bb78af6c2b +Subproject commit 74b51006acd2bd9f533c3c309a73cdf2479057c4
diff --git a/tools/android/avd/proto/android_34_automotive_x64.textpb b/tools/android/avd/proto/android_34_automotive_x64.textpb new file mode 100644 index 0000000..50a25d23 --- /dev/null +++ b/tools/android/avd/proto/android_34_automotive_x64.textpb
@@ -0,0 +1,27 @@ +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Configuration for an Android-14 Automotive (U, API 34) AVD on google_apis on x86_64 + +emulator_package { + package_name: "chromium/third_party/android_sdk/public/emulator" + version: "abxH5kvB9WO4Xg_EHEiIjAl1rqmM2hQRhU5e4_9AFboC" # 35.3.11 (Stable) +} + +system_image_package { + package_name: "chromium/third_party/android_sdk/public/system-images/android-34/android-automotive/x86_64" + version: "yu3GTxX-EiMAdks2nEQxDflUnmmPrO7e_z753zemG9sC" # r4 (UAA1.250210.001) +} +system_image_name: "system-images;android-34-ext9;android-automotive;x86_64" + +avd_package { + package_name: "chromium/third_party/android_sdk/public/avds/android-34/android-automotive/x86_64" + # Created in https://ci.chromium.org/ui/b/8718495335733819377 + version: "EsNdPOtuQIFC5knxkvnYtcDWZUQ-S7Rtt02s9STMJH4C" +} +avd_name: "android_34_automotive_x64" + +avd_launch_settings { + gpu_mode: "swangle_indirect" +} \ No newline at end of file
diff --git a/tools/android/avd/proto/android_34_automotive_x64_local.textpb b/tools/android/avd/proto/android_34_automotive_x64_local.textpb new file mode 100644 index 0000000..8000278 --- /dev/null +++ b/tools/android/avd/proto/android_34_automotive_x64_local.textpb
@@ -0,0 +1,27 @@ +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Configuration for an Android-14 (U, API 34) AVD on google_apis on x86_64 + +emulator_package { + package_name: "chromium/third_party/android_sdk/public/emulator" + version: "abxH5kvB9WO4Xg_EHEiIjAl1rqmM2hQRhU5e4_9AFboC" # 35.3.11 (Stable) +} + +system_image_package { + package_name: "chromium/third_party/android_sdk/public/system-images/android-34/android-automotive/x86_64" + version: "yu3GTxX-EiMAdks2nEQxDflUnmmPrO7e_z753zemG9sC" # r4 (UAA1.250210.001) +} +system_image_name: "system-images;android-34-ext9;android-automotive;x86_64" + +avd_package { + package_name: "chromium/third_party/android_sdk/public/avds/android-34/android-automotive/x86_64" + # Created in https://ci.chromium.org/ui/b/8718495335733819377 + version: "bVeZZMzmAyZG7mdp1lNkpa1VAM38Tgp_0URIMIwQb9MC" +} +avd_name: "android_34_automotive_x64" + +avd_launch_settings { + gpu_mode: "swangle_indirect" +} \ No newline at end of file
diff --git a/tools/cast3p/runtime.version b/tools/cast3p/runtime.version index 54d32e91..ee17a74 100644 --- a/tools/cast3p/runtime.version +++ b/tools/cast3p/runtime.version
@@ -1 +1 @@ -471484 +472081
diff --git a/tools/clang/scripts/upload_revision.py b/tools/clang/scripts/upload_revision.py index 2cf6bd3..7d716146 100755 --- a/tools/clang/scripts/upload_revision.py +++ b/tools/clang/scripts/upload_revision.py
@@ -70,12 +70,6 @@ Cq-Include-Trybots: chromium/try:win-official,win32-official Cq-Include-Trybots: chromium/try:win-arm64-rel Cq-Include-Trybots: chromium/try:linux-swangle-try-x64,win-swangle-try-x86 -Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-arm64-dbg -Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-arm64-rel -Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-riscv64-dbg -Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-riscv64-rel -Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-x86-dbg -Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-x86-rel Cq-Include-Trybots: chromium/try:android-cronet-riscv64-dbg Cq-Include-Trybots: chromium/try:android-cronet-riscv64-rel Cq-Include-Trybots: chrome/try:iphone-device,ipad-device
diff --git a/tools/cygprofile/BUILD.gn b/tools/cygprofile/BUILD.gn index 5fe2803..a43996e 100644 --- a/tools/cygprofile/BUILD.gn +++ b/tools/cygprofile/BUILD.gn
@@ -20,9 +20,11 @@ enable_android_wrapper = true args = [ - # Assume that we are running this script from the output directory. + # Currently tools/cygprofile/android_profile_tool.py runs run_benchmark + # from the root dir instead of the out dir, so the out dir needs to be + # relative to the source root dir. "--out-dir", - ".", + rebase_path(root_build_dir, "//"), "--android-browser", invoker.browser_name, "--target-arch",
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index bb285e1..4a17f75a 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -24798,6 +24798,9 @@ </action> <action name="MobileNTPOpenedInNewTab"> + <obsolete> + Deprecated 04/2025. Replaced with NewTabPage.OpenedInNewTab UMA. + </obsolete> <owner>friedrichh@chromium.org</owner> <description> The user manually created a New Tab Page (NTP) in a new tab that has not
diff --git a/tools/metrics/histograms/PRESUBMIT.py b/tools/metrics/histograms/PRESUBMIT.py index 0fe0374..95b5bc8 100644 --- a/tools/metrics/histograms/PRESUBMIT.py +++ b/tools/metrics/histograms/PRESUBMIT.py
@@ -261,7 +261,7 @@ cache_file_path=_CACHE_FILE_PATH, allowlist_path_override=None, xml_paths_override=None): - """Checks that histograms_allowlist.txt contains valid histograms. + """Checks that HistogramsAllowlist.java contains valid histograms. This function is a wrapper around ExecuteCheckWebViewHistogramsAllowlistOnUpload that adds caching support. @@ -279,7 +279,7 @@ def ExecuteCheckWebViewHistogramsAllowlistOnUpload(input_api, output_api, allowlist_path_override, xml_paths_override): - """Checks that histograms_allowlist.txt contains valid histograms.""" + """Checks that HistogramsAllowlist.java contains valid histograms.""" xml_filter = lambda f: Path(f.LocalPath()).suffix == '.xml' xml_files = input_api.AffectedFiles(include_deletes=False, file_filter=xml_filter)
diff --git a/tools/metrics/histograms/PRESUBMIT_test.py b/tools/metrics/histograms/PRESUBMIT_test.py index fb9030df..5113ab9 100644 --- a/tools/metrics/histograms/PRESUBMIT_test.py +++ b/tools/metrics/histograms/PRESUBMIT_test.py
@@ -107,7 +107,7 @@ '/example_valid_enums.xml') example_allowlist_path = (f'{os.path.dirname(__file__)}' '/test_data' - '/allowlist_example.txt') + '/AllowlistExample.java') (mock_input_api, missing_allow_list_entries_histograms_path ) = _MockInputFromTestFile('no_allowlist_entries_histograms.xml') @@ -124,7 +124,7 @@ self.assertEqual(len(results), 1) self.assertRegex( results[0].message.replace('\n', ' '), 'All histograms in' - ' .*allowlist_example.txt must be valid.') + ' .*AllowlistExample.java must be valid.') self.assertEqual(results[0].type, 'error') def testCheckBooleansAreEnumsFailureIsDetected(self): @@ -164,7 +164,7 @@ '/example_valid_enums.xml') example_allowlist_path = (f'{os.path.dirname(__file__)}' '/test_data' - '/allowlist_example.txt') + '/AllowlistExample.java') (mock_input_api, valid_histograms_path ) = _MockInputFromTestFile('example_valid_histograms.xml') @@ -381,7 +381,7 @@ '/example_valid_enums.xml') example_allowlist_path = (f'{os.path.dirname(__file__)}' '/test_data' - '/allowlist_example.txt') + '/AllowlistExample.java') with open(valid_histograms_path, 'r') as f: valid_histograms_contents = f.read()
diff --git a/tools/metrics/histograms/histograms_allowlist_check.py b/tools/metrics/histograms/histograms_allowlist_check.py index e7c9f16..106e3b2 100644 --- a/tools/metrics/histograms/histograms_allowlist_check.py +++ b/tools/metrics/histograms/histograms_allowlist_check.py
@@ -19,8 +19,9 @@ constants or duplicated code among users of this check. """ - ANDROID_WEBVIEW = os.path.join('android_webview', 'java', 'res', 'raw', - 'histograms_allowlist.txt') + ANDROID_WEBVIEW = os.path.join('android_webview', 'java', 'src', 'org', + 'chromium', 'android_webview', 'metrics', + 'HistogramsAllowlist.java') def relative_path(self): """Returns the path of the allowlist file relative to src/.""" @@ -31,8 +32,19 @@ def get_histograms_allowlist_content(allowlist_path): + histogramNames = [] with open(allowlist_path) as file: - return [line.rstrip() for line in file] + shouldParse = False + for line in file: + if line.strip() == '// histograms_allowlist_check START_PARSING': + shouldParse = True + continue + if line.strip() == '// histograms_allowlist_check END_PARSING': + break + if shouldParse: + # Remove white space, quotes and commas from the entries. + histogramNames.append(line.strip().replace('"', '').replace(',', '')) + return histogramNames def check_histograms_allowlist(output_api, allowlist_path, histograms_files):
diff --git a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS index 299d15f..e407edb 100644 --- a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS +++ b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
@@ -38,6 +38,7 @@ xiaohuic@chromium.org # attribution_reporting csharrison@chromium.org +linnan@chromium.org # autofill fleimgruber@google.com jihadghanna@google.com
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index b4c7512..1324cb2 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -144,6 +144,18 @@ <variant name="PreloadApk" summary="Preload-APK"/> </variants> +<variants name="GridTabSwitcherAnimationType"> + <variant name="Expand" summary="Grid to Tab"/> + <variant name="Shrink" summary="Tab to Grid"/> +</variants> + +<variants name="GridTabSwitcherMessageType"> + <variant name="PriceAlertsMessageCard" + summary="the promo message for price notifications"/> + <variant name="PriceWelcomeMessageCard" + summary="the message introducing price chips"/> +</variants> + <variants name="InstanceAllocationType"> <variant name="ExistingInstance" summary="a restoration of a persisted instance"/> @@ -2102,20 +2114,21 @@ </summary> </histogram> -<histogram base="true" - name="Android.GridTabSwitcher.Animation.FirstFrameLatency" units="ms" - expires_after="2025-12-20"> +<histogram + name="Android.GridTabSwitcher.Animation.FirstFrameLatency.{GridTabSwitcherAnimationType}" + units="ms" expires_after="2025-12-20"> <owner>ckitagawa@chromium.org</owner> <owner>clank-isochron-team@google.com</owner> <summary> This histogram records the time taken between the tab and tab switcher layout. Timing starts when the layout transition begins and ends on the first frame. This is recorded each time the layout transition animation - occurs. + occurs. {GridTabSwitcherAnimationType} </summary> </histogram> -<histogram base="true" name="Android.GridTabSwitcher.Animation.TotalDuration" +<histogram + name="Android.GridTabSwitcher.Animation.TotalDuration.{GridTabSwitcherAnimationType}" units="ms" expires_after="2025-12-20"> <owner>ckitagawa@chromium.org</owner> <owner>clank-isochron-team@google.com</owner> @@ -2123,6 +2136,7 @@ This histogram records the time taken between the tab and tab switcher layout. Timing starts when the layout transition begins and ends on the last frame. This is recorded each time the layout transition animation occurs. + {GridTabSwitcherAnimationType} </summary> </histogram> @@ -8045,6 +8059,96 @@ </summary> </histogram> +<histogram name="GestureNavigation.Activated2" + enum="GestureNavigationDirection" expires_after="2025-08-31"> + <owner>twellington@chromium.org</owner> + <owner>clank-app-team@google.com</owner> + <summary> + Overscroll gesture was made beyond a threshold big enough to regard it as a + valid gesture navigation i.e. at least 1/3 of the arrow puck is visible. + Similar to 'Triggered' but is used in pair with 'Cancelled' on M81 forward + to measure cancellation rate. Implemented for Android. + </summary> +</histogram> + +<histogram name="GestureNavigation.Cancelled2" + enum="GestureNavigationDirection" expires_after="2025-08-31"> + <owner>twellington@chromium.org</owner> + <owner>clank-app-team@google.com</owner> + <summary> + Overscroll gestures that were cancelled before they were completed. Similar + to 'Abandoned' but is used in pair with 'Activated' on M81 forward to + measure cancellation rate. Implemented for Android. + </summary> +</histogram> + +<histogram name="GestureNavigation.Completed2" + enum="GestureNavigationDirection" expires_after="2025-08-31"> + <owner>twellington@chromium.org</owner> + <owner>clank-app-team@google.com</owner> + <summary> + Navigations that were triggered due to completed overscroll gesture. + Implemented for Android. + </summary> +</histogram> + +<histogram name="GestureNavigation.Reversed2" enum="GestureNavigationDirection" + expires_after="2025-08-31"> + <owner>twellington@chromium.org</owner> + <owner>clank-app-team@google.com</owner> + <summary> + Overscroll gesture was made to trigger navigation, but within 3 seconds user + used overscroll gesture to navigate back to the page. Implemented for + Android. + </summary> +</histogram> + +<histogram name="GestureNavigation.Type2" enum="GestureNavigationType" + expires_after="2025-08-31"> + <owner>twellington@chromium.org</owner> + <owner>clank-app-team@google.com</owner> + <summary> + Gesture navigation type. It can be either Chrome's own gesture UI that + supports back and forward navigation or OS-provided default system gesture + navigation that supports only back action on both left and right edge. This + is recorded on Chrome startup at the feature component initialization. + </summary> +</histogram> + +<histogram name="GridTabSwitcher.FramePerSecond.{GridTabSwitcherAnimationType}" + units="frame/sec" expires_after="2025-08-24"> + <owner>ckitagawa@chromium.org</owner> + <owner>meiliang@chromium.org</owner> + <summary> + This histogram records the frame rate of the transition animation between + Tab and Grid Tab Switcher. {GridTabSwitcherAnimationType} + </summary> +</histogram> + +<histogram + name="GridTabSwitcher.MaxFrameInterval.{GridTabSwitcherAnimationType}" + units="ms" expires_after="2025-09-09"> + <owner>ckitagawa@chromium.org</owner> + <owner>meiliang@chromium.org</owner> + <summary> + This histogram records the maximum interval between rendered frames during + the transition animation between Tab and Grid Tab Switcher. + {GridTabSwitcherAnimationType} + </summary> +</histogram> + +<histogram name="GridTabSwitcher.{GridTabSwitcherMessageType}.DisableReason" + enum="GridTabSwitcherMessageDisableReason" expires_after="2022-10-01"> + <owner>zhiyuancai@chromium.org</owner> + <owner>wychen@chromium.org</owner> + <owner>ayman@chromium.org</owner> + <summary> + Records why the {GridTabSwitcherMessageType} is disabled in GridTabSwitcher + and will no longer be shown to users. Recorded when the message is disabled. + Implemented for Android. + </summary> +</histogram> + </histograms> </histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/ash/enums.xml b/tools/metrics/histograms/metadata/ash/enums.xml index de2a46c..4b57b0d 100644 --- a/tools/metrics/histograms/metadata/ash/enums.xml +++ b/tools/metrics/histograms/metadata/ash/enums.xml
@@ -256,6 +256,16 @@ <!-- LINT.ThenChange(//chromeos/ash/components/boca/babelorca/babel_orca_consumer.h:ReceivingStoppedReason) --> +<!-- LINT.IfChange(BabelOrcaSendingStoppedReason) --> + +<enum name="BabelOrcaSendingStoppedReason"> + <int value="0" label="Class Tools session ended"/> + <int value="1" label="Session captions turned off"/> + <int value="2" label="Send messages requests error"/> +</enum> + +<!-- LINT.ThenChange(//chromeos/ash/components/boca/babelorca/babel_orca_producer.h:SendingStoppedReason) --> + <!-- LINT.IfChange(BabelOrcaStreamEndReason) --> <enum name="BabelOrcaStreamEndReason">
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index b692d1d..275971f 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -1240,6 +1240,17 @@ </summary> </histogram> +<histogram name="Ash.Boca.Babelorca.SendingStoppedReason" + enum="BabelOrcaSendingStoppedReason" expires_after="2026-03-21"> + <owner>anasr@google.com</owner> + <owner>cros-edu-eng@google.com</owner> + <summary> + Records why sending captions was turned off at the producer, whether this + was by the user turning off captions, or ending the session or because of a + request error that needs user manual retry. + </summary> +</histogram> + <histogram name="Ash.Boca.Babelorca.StreamEndReason" enum="BabelOrcaStreamEndReason" expires_after="2026-03-21"> <owner>anasr@google.com</owner> @@ -1263,6 +1274,19 @@ </token> </histogram> +<histogram name="Ash.Boca.Babelorca.{Scope}.OAuthFetchError" + enum="GoogleServiceAuthError" expires_after="2026-03-21"> + <owner>anasr@google.com</owner> + <owner>cros-edu-eng@google.com</owner> + <summary> + Records the OAuth token fetch result for BabelOrca requests. + </summary> + <token key="Scope"> + <variant name="SchoolTools"/> + <variant name="Tachyon"/> + </token> +</histogram> + <histogram name="Ash.Boca.NumberOfActiveStudentsWhenSessionEnded" units="students" expires_after="2025-08-10"> <owner>caott@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/attribution_reporting/OWNERS b/tools/metrics/histograms/metadata/attribution_reporting/OWNERS index 586f71a..973271b 100644 --- a/tools/metrics/histograms/metadata/attribution_reporting/OWNERS +++ b/tools/metrics/histograms/metadata/attribution_reporting/OWNERS
@@ -3,3 +3,4 @@ # Prefer sending CLs to the owners listed below. # Use chromium-metrics-reviews@google.com as a backup. csharrison@chromium.org +linnan@chromium.org
diff --git a/tools/metrics/histograms/metadata/blink/enums.xml b/tools/metrics/histograms/metadata/blink/enums.xml index 63b2d142..59e1c05 100644 --- a/tools/metrics/histograms/metadata/blink/enums.xml +++ b/tools/metrics/histograms/metadata/blink/enums.xml
@@ -6248,6 +6248,7 @@ <int value="132" label="Rewriter"/> <int value="133" label="Translator"/> <int value="134" label="LanguageDetector"/> + <int value="135" label="DeviceAttributes"/> </enum> <enum name="FedCmAccountChooserResult">
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml index 235d2d6..7b6270a 100644 --- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -497,16 +497,6 @@ <affected-histogram name="FirstUserAction.BackgroundTimeNewTask"/> </histogram_suffixes> -<histogram_suffixes name="GridTabSwitcherAnimationType" separator="."> - <suffix name="Expand" label="Grid to Tab"/> - <suffix name="Shrink" label="Tab to Grid"/> - <affected-histogram - name="Android.GridTabSwitcher.Animation.FirstFrameLatency"/> - <affected-histogram name="Android.GridTabSwitcher.Animation.TotalDuration"/> - <affected-histogram name="GridTabSwitcher.FramePerSecond"/> - <affected-histogram name="GridTabSwitcher.MaxFrameInterval"/> -</histogram_suffixes> - <histogram_suffixes name="HiddenWhileFlushing" separator="."> <suffix name="HiddenWhileFlushing" label="Tab hidden while flushing FCP value."/>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml index 5e2b6f1..1e4d743 100644 --- a/tools/metrics/histograms/metadata/navigation/histograms.xml +++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -1467,7 +1467,7 @@ </histogram> <histogram name="Navigation.MainFrameHasRTLDomain2" enum="Boolean" - expires_after="2025-09-28"> + expires_after="2026-04-07"> <owner>cthomp@chromium.org</owner> <owner>trusty-transport@chromium.org</owner> <summary> @@ -1478,7 +1478,7 @@ </histogram> <histogram name="Navigation.MainFrameHasRTLDomainDifferentPage2" enum="Boolean" - expires_after="2025-05-19"> + expires_after="2026-04-07"> <owner>cthomp@chromium.org</owner> <owner>trusty-transport@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/new_tab_page/enums.xml b/tools/metrics/histograms/metadata/new_tab_page/enums.xml index 94cd4ad..f0c1ba5 100644 --- a/tools/metrics/histograms/metadata/new_tab_page/enums.xml +++ b/tools/metrics/histograms/metadata/new_tab_page/enums.xml
@@ -550,6 +550,42 @@ <int value="1" label="Module is shown and collapsed"/> </enum> +<!-- LINT.IfChange(TabLaunchType) --> + +<enum name="TabLaunchType"> + <int value="0" label="From Link"/> + <int value="1" label="From External App"/> + <int value="2" label="From Chrome Ui"/> + <int value="3" label="From Restore"/> + <int value="4" label="From Longpress Foreground"/> + <int value="5" label="From Longpress Background"/> + <int value="6" label="From Reparenting"/> + <int value="7" label="From Launcher Shortcut"/> + <int value="8" label="From Speculative Background Creation"/> + <int value="9" label="From Browser Actions"/> + <int value="10" label="From Launch New Incognito Tab"/> + <int value="11" label="From Startup"/> + <int value="12" label="From Start Surface"/> + <int value="13" label="From Tab Group Ui"/> + <int value="14" label="From Longpress Background In Group"/> + <int value="15" label="From App Widget"/> + <int value="16" label="From Longpress Incognito"/> + <int value="17" label="From Recent Tabs"/> + <int value="18" label="From Reading List"/> + <int value="19" label="From Tab Switcher Ui"/> + <int value="20" label="From Restore Tabs Ui"/> + <int value="21" label="From Omnibox"/> + <int value="22" label="Unset"/> + <int value="23" label="From Sync Background"/> + <int value="24" label="From Recent Tabs Foreground"/> + <int value="25" label="From Collaboration Background In Group"/> + <int value="26" label="From Bookmark Bar Background"/> + <int value="27" label="From Reparenting Background"/> + <int value="28" label="Size"/> +</enum> + +<!-- LINT.ThenChange(//chrome/browser/ui/android/tab_model/tab_model.h:TabLaunchType) --> + <enum name="TypeOfDeletedMostVisitedApp"> <summary> This enum denotes the type of app on the deleted ntp_tile as part of bug fix
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml index 4e20b46c..0150083 100644 --- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml +++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -1406,6 +1406,18 @@ </summary> </histogram> +<histogram name="NewTabPage.OpenedInNewTab" enum="TabLaunchType" + expires_after="2025-12-31"> + <owner>eirage@chromium.org</owner> + <owner>hanxi@chromium.org</owner> + <summary> + Records the TabLaunchType enum when a New Tab Page (NTP) is created in a new + tab. This histogram is logged when a new tab is created, including manually + created New Tab or the initial tab at Chrome startup. This histogram is + Android-only. + </summary> +</histogram> + <histogram name="NewTabPage.OutlookCalendar.EventClickIndex" units="count" expires_after="2026-01-20"> <owner>jennserrano@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index 20207e5..f7b35e2 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -50,13 +50,6 @@ <variant name="YouTubePwa"/> </variants> -<variants name="GridTabSwitcherMessageTypes"> - <variant name="PriceAlertsMessageCard" - summary="the promo message for price notifications"/> - <variant name="PriceWelcomeMessageCard" - summary="the message introducing price chips"/> -</variants> - <variants name="GroupFreshnessType"> <variant name="NoDailyUpdates" summary="interest groups that don't specify a dailyUpdateUrl"/> @@ -5612,95 +5605,6 @@ </summary> </histogram> -<histogram name="GestureNavigation.Activated2" - enum="GestureNavigationDirection" expires_after="2025-08-31"> - <owner>twellington@chromium.org</owner> - <owner>clank-app-team@google.com</owner> - <summary> - Overscroll gesture was made beyond a threshold big enough to regard it as a - valid gesture navigation i.e. at least 1/3 of the arrow puck is visible. - Similar to 'Triggered' but is used in pair with 'Cancelled' on M81 forward - to measure cancellation rate. Implemented for Android. - </summary> -</histogram> - -<histogram name="GestureNavigation.Cancelled2" - enum="GestureNavigationDirection" expires_after="2025-08-31"> - <owner>twellington@chromium.org</owner> - <owner>clank-app-team@google.com</owner> - <summary> - Overscroll gestures that were cancelled before they were completed. Similar - to 'Abandoned' but is used in pair with 'Activated' on M81 forward to - measure cancellation rate. Implemented for Android. - </summary> -</histogram> - -<histogram name="GestureNavigation.Completed2" - enum="GestureNavigationDirection" expires_after="2025-08-31"> - <owner>twellington@chromium.org</owner> - <owner>clank-app-team@google.com</owner> - <summary> - Navigations that were triggered due to completed overscroll gesture. - Implemented for Android. - </summary> -</histogram> - -<histogram name="GestureNavigation.Reversed2" enum="GestureNavigationDirection" - expires_after="2025-08-31"> - <owner>twellington@chromium.org</owner> - <owner>clank-app-team@google.com</owner> - <summary> - Overscroll gesture was made to trigger navigation, but within 3 seconds user - used overscroll gesture to navigate back to the page. Implemented for - Android. - </summary> -</histogram> - -<histogram name="GestureNavigation.Type2" enum="GestureNavigationType" - expires_after="2025-08-31"> - <owner>twellington@chromium.org</owner> - <owner>clank-app-team@google.com</owner> - <summary> - Gesture navigation type. It can be either Chrome's own gesture UI that - supports back and forward navigation or OS-provided default system gesture - navigation that supports only back action on both left and right edge. This - is recorded on Chrome startup at the feature component initialization. - </summary> -</histogram> - -<histogram base="true" name="GridTabSwitcher.FramePerSecond" units="frame/sec" - expires_after="2025-08-24"> - <owner>ckitagawa@chromium.org</owner> - <owner>meiliang@chromium.org</owner> - <summary> - This histogram records the frame rate of the transition animation between - Tab and Grid Tab Switcher. - </summary> -</histogram> - -<histogram base="true" name="GridTabSwitcher.MaxFrameInterval" units="ms" - expires_after="2025-09-09"> - <owner>ckitagawa@chromium.org</owner> - <owner>meiliang@chromium.org</owner> - <summary> - This histogram records the maximum interval between rendered frames during - the transition animation between Tab and Grid Tab Switcher. - </summary> -</histogram> - -<histogram name="GridTabSwitcher.{MessageType}.DisableReason" - enum="GridTabSwitcherMessageDisableReason" expires_after="2022-10-01"> - <owner>zhiyuancai@chromium.org</owner> - <owner>wychen@chromium.org</owner> - <owner>ayman@chromium.org</owner> - <summary> - Records why the {MessageType} is disabled in GridTabSwitcher and will no - longer be shown to users. Recorded when the message is disabled. Implemented - for Android. - </summary> - <token key="MessageType" variants="GridTabSwitcherMessageTypes"/> -</histogram> - <histogram name="Hardware.Display.Count.OnChange" units="units" expires_after="2025-08-24"> <owner>sashamcintosh@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/readaloud/histograms.xml b/tools/metrics/histograms/metadata/readaloud/histograms.xml index d49a9de..e788890 100644 --- a/tools/metrics/histograms/metadata/readaloud/histograms.xml +++ b/tools/metrics/histograms/metadata/readaloud/histograms.xml
@@ -29,7 +29,7 @@ </variants> <histogram name="ReadAloud.DurationListened" units="ms" - expires_after="2025-08-31"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -41,7 +41,7 @@ </histogram> <histogram name="ReadAloud.DurationListened.LockedScreen" units="ms" - expires_after="2025-04-13"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -53,7 +53,7 @@ </histogram> <histogram name="ReadAloud.DurationScrubbingBackwardsSeekbar" units="ms" - expires_after="2025-07-06"> + expires_after="2026-04-07"> <owner>sanaakbani@google.com</owner> <owner>basiaz@google.com</owner> <summary> @@ -65,7 +65,7 @@ </histogram> <histogram name="ReadAloud.DurationScrubbingForwardsSeekbar" units="ms" - expires_after="2025-07-06"> + expires_after="2026-04-07"> <owner>sanaakbani@google.com</owner> <owner>basiaz@google.com</owner> <summary> @@ -77,7 +77,7 @@ </histogram> <histogram name="ReadAloud.Eligibility.IneligiblityReason" - enum="ReadAloudIneligibilityReason" expires_after="2025-06-22"> + enum="ReadAloudIneligibilityReason" expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -90,7 +90,7 @@ </histogram> <histogram name="ReadAloud.Eligibility.IsUserEligible" enum="BooleanEligible" - expires_after="2025-08-24"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -101,7 +101,7 @@ </histogram> <histogram name="ReadAloud.EmptyURLPlayback" enum="ReadAloudEntrypoint" - expires_after="2025-04-20"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -112,7 +112,7 @@ </histogram> <histogram name="ReadAloud.HasDateModified" enum="BooleanSuccess" - expires_after="2025-08-04"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -124,7 +124,7 @@ </histogram> <histogram name="ReadAloud.HasTapToSeekFoundMatch" enum="BooleanSuccess" - expires_after="2025-08-31"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -135,7 +135,7 @@ </histogram> <histogram name="ReadAloud.HighlightingEnabled" enum="BooleanEnabled" - expires_after="2025-08-31"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -146,7 +146,7 @@ </histogram> <histogram name="ReadAloud.HighlightingEnabled.OnStartup" enum="BooleanEnabled" - expires_after="2025-05-11"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -157,18 +157,19 @@ </histogram> <histogram name="ReadAloud.HighlightingSupported" enum="BooleanSupported" - expires_after="2024-12-08"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> <summary> Histogram for recording if highlighting is supported. Emitted when a - playback is successfully created. + playback is successfully created. Warning: This histogram was expired from + 2024-12 to 2025-04; data may be missing. </summary> </histogram> <histogram name="ReadAloud.IsPageReadabilitySuccessful" enum="BooleanSuccess" - expires_after="2025-08-17"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -180,7 +181,7 @@ </histogram> <histogram name="ReadAloud.IsPageReadable" enum="BooleanEligible" - expires_after="2025-08-17"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -198,7 +199,7 @@ </histogram> <histogram name="ReadAloud.IsTabPlaybackCreationSuccessful" - enum="BooleanSuccess" expires_after="2025-08-17"> + enum="BooleanSuccess" expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -209,7 +210,7 @@ </histogram> <histogram name="ReadAloud.ReadAloudError.{Phase}" enum="ReadAloudErrorCode" - expires_after="2025-04-13"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -223,7 +224,7 @@ </histogram> <histogram name="ReadAloud.ReadAloudNetError.{Phase}" enum="NetErrorCodes" - expires_after="2025-03-30"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -238,7 +239,7 @@ </histogram> <histogram name="ReadAloud.ReadAloudPlaybackWithoutReadabilityCheckError" - enum="ReadAloudEntrypoint" expires_after="2025-04-13"> + enum="ReadAloudEntrypoint" expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -250,7 +251,7 @@ </histogram> <histogram name="ReadAloud.ReadAloudUnsuportedError.{Phase}" - enum="RejectionReason" expires_after="2025-04-13"> + enum="RejectionReason" expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -262,7 +263,7 @@ </histogram> <histogram name="ReadAloud.ServerReadabilityResult" enum="BooleanEligible" - expires_after="2025-06-29"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -277,7 +278,7 @@ </histogram> <histogram name="ReadAloud.SpeedChange" enum="ReadAloudSpeed" - expires_after="2025-04-20"> + expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -288,7 +289,7 @@ </histogram> <histogram name="ReadAloud.TabPlaybackCreationFailure" - enum="ReadAloudEntrypoint" expires_after="2025-08-04"> + enum="ReadAloudEntrypoint" expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -300,7 +301,7 @@ </histogram> <histogram name="ReadAloud.TabPlaybackCreationSuccess" - enum="ReadAloudEntrypoint" expires_after="2025-08-31"> + enum="ReadAloudEntrypoint" expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> @@ -312,17 +313,18 @@ </histogram> <histogram name="ReadAloud.TabPlaybackStoppedReason" - enum="PlaybackStoppedReason" expires_after="2024-12-08"> + enum="PlaybackStoppedReason" expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner> <summary> Android only. Records reason for stopping a tab playback. Note that this - doesn't include stopping the voice preview playbacks. + doesn't include stopping the voice preview playbacks. Warning: This + histogram was expired from 2024-12 to 2025-04; data may be missing. </summary> </histogram> -<histogram name="ReadAloud.TapToSeekTime" units="ms" expires_after="2025-08-31"> +<histogram name="ReadAloud.TapToSeekTime" units="ms" expires_after="2026-04-07"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> <owner>iwells@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml index 91dfd71..39f1a6b 100644 --- a/tools/metrics/histograms/metadata/security/histograms.xml +++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -1131,7 +1131,7 @@ </histogram> <histogram name="SiteIsolation.SavedUserTriggeredIsolatedOrigins.Size" - units="origins" expires_after="2025-04-20"> + units="origins" expires_after="2026-04-20"> <owner>alexmos@chromium.org</owner> <owner>creis@chromium.org</owner> <owner>lukasza@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml index 754ff7a..53d9093 100644 --- a/tools/metrics/histograms/metadata/startup/histograms.xml +++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -391,6 +391,27 @@ </token> </histogram> +<histogram name="Startup.Android.Cold.{StartupType}.TimeSpentInBinder" + units="ms" expires_after="2025-10-14"> + <owner>nafisabedin@google.com</owner> + <owner>yfriedman@chromium.org</owner> + <improvement direction="LOWER_IS_BETTER"/> + <summary> + Records the total time spent handling Binder calls on a cold start for a + particular {StartupType}. + + Metric is recorded once per application lifetime during a cold start, only + when the cold start metric (e.g. TimeToFirstDraw) pertaining to + {StartupType} is also recorded. + + The underlying mechanism used to time this relies on undocumented Android + APIs, meaning that it may break in the future. + </summary> + <token key="StartupType"> + <variant name="NewTabPage"/> + </token> +</histogram> + <histogram name="Startup.Android.DurationSinceLastBackgroundTime" units="ms" expires_after="2025-08-10"> <owner>hanxi@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml index f7bdb33..243da83 100644 --- a/tools/metrics/histograms/metadata/tab/histograms.xml +++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -951,7 +951,7 @@ </histogram> <histogram name="TabGroups.SavedTabGroupTabTimeSinceModification" - units="minutes" expires_after="2025-05-11"> + units="minutes" expires_after="2025-10-11"> <owner>dljames@chromium.org</owner> <owner>top-chrome-desktop-ui@google.com</owner> <summary> @@ -963,7 +963,7 @@ </histogram> <histogram name="TabGroups.SavedTabGroupTimeSinceModification" units="minutes" - expires_after="2025-05-25"> + expires_after="2025-10-25"> <owner>dljames@chromium.org</owner> <owner>top-chrome-desktop-ui@google.com</owner> <summary> @@ -995,7 +995,7 @@ </histogram> <histogram name="TabGroups.Shared.GroupDeleted" enum="Boolean" - expires_after="2025-05-25"> + expires_after="2025-10-25"> <owner>dljames@chromium.org</owner> <owner>top-chrome-desktop-ui@google.com</owner> <summary> @@ -1050,7 +1050,7 @@ </histogram> <histogram name="TabGroups.Shared.TabGroupAge" units="minutes" - expires_after="2025-05-25"> + expires_after="2025-10-25"> <owner>dljames@chromium.org</owner> <owner>top-chrome-desktop-ui@google.com</owner> <summary> @@ -1061,7 +1061,7 @@ </histogram> <histogram name="TabGroups.Shared.TotalTabGroupCount" units="groups" - expires_after="2025-05-25"> + expires_after="2025-10-25"> <owner>dljames@chromium.org</owner> <owner>top-chrome-desktop-ui@google.com</owner> <summary> @@ -1073,7 +1073,7 @@ </histogram> <histogram name="TabGroups.Shared.TotalTabGroupTabCount" units="tabs" - expires_after="2025-05-25"> + expires_after="2025-10-25"> <owner>dljames@chromium.org</owner> <owner>top-chrome-desktop-ui@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/test_data/AllowlistExample.java b/tools/metrics/histograms/test_data/AllowlistExample.java new file mode 100644 index 0000000..e5c9477 --- /dev/null +++ b/tools/metrics/histograms/test_data/AllowlistExample.java
@@ -0,0 +1,28 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package tools.metrics.histograms.test_data; + +private class AllowlistExample { + + private String ignoredMethod() { + return "histograms_allowlist_check should ignore this code"; + } + + private String[] getAllowlist() { + String[] histogramsAllowlist = + new String[] { + // histograms_allowlist_check START_PARSING + "UMA.FileMetricsProvider.InitialAccessResult", + "UMA.FileMetricsProvider.AccessResult", + // histograms_allowlist_check END_PARSING + }; + return histogramsAllowlist; + } + + private String anotherIgnoredMethod() { + String ignored = "This is all ignored."; + return ignored; + } +}
diff --git a/tools/metrics/histograms/test_data/allowlist_example.txt b/tools/metrics/histograms/test_data/allowlist_example.txt deleted file mode 100644 index 6c1ce99..0000000 --- a/tools/metrics/histograms/test_data/allowlist_example.txt +++ /dev/null
@@ -1,2 +0,0 @@ -UMA.FileMetricsProvider.InitialAccessResult -UMA.FileMetricsProvider.AccessResult \ No newline at end of file
diff --git a/tools/metrics/histograms/test_data/no_allowlist_entries_histograms.xml b/tools/metrics/histograms/test_data/no_allowlist_entries_histograms.xml index e74dc142..4aae6ce 100644 --- a/tools/metrics/histograms/test_data/no_allowlist_entries_histograms.xml +++ b/tools/metrics/histograms/test_data/no_allowlist_entries_histograms.xml
@@ -1,7 +1,7 @@ <!-- This is a version of histograms.xml file that doesn't contain all the entries that are expected due to their presence in - android_webview/java/res/raw/histograms_allowlist.txt, this file can be used + HistogramsAllowlist.java, this file can be used to validate test scenarios that rely on such circumstances. --> @@ -9,4 +9,4 @@ units="%" expires_after="M298"> <owner>person@chromium.org</owner> <summary>Foo</summary> -</histogram> \ No newline at end of file +</histogram>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index ce0a58f..5c09ddd 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@ "full_remote_path": "perfetto-luci-artifacts/40b529923598b739b2892a536a7692eedbed5685/linux-arm64/trace_processor_shell" }, "win": { - "hash": "55c7d570969d3a22502b3dfe3f7bdd5a62734628", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/514efabacc29850a8e85dacba4210a3494d79c70/trace_processor_shell.exe" + "hash": "0cbfb22f24bde5b8c8cb729386931ca0f8839710", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/745c6d3fead9008f05ee73172e46d059863b5ab3/trace_processor_shell.exe" }, "linux_arm": { "hash": "28bd9c986197285caeb7e5f7e8434e8f61bd7822", @@ -22,7 +22,7 @@ }, "linux": { "hash": "bcf8255faac0e7c69248e175955b7bae8d0df3ac", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/754171b07092af1f8ffc5de23ace51f4ea3f04da/trace_processor_shell" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/181c298de2ebe848dad23788d76ae1f517aae6ec/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index 27aace1e..f252c88 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -487,6 +487,7 @@ "java/src/org/chromium/ui/util/AttrUtils.java", "java/src/org/chromium/ui/util/ColorBlendAnimationFactory.java", "java/src/org/chromium/ui/util/ColorUtils.java", + "java/src/org/chromium/ui/util/KeyboardNavigationListener.java", "java/src/org/chromium/ui/util/MotionEventUtils.java", "java/src/org/chromium/ui/util/RunnableTimer.java", "java/src/org/chromium/ui/util/StyleUtils.java",
diff --git a/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/KeyboardNavigationListener.java b/ui/android/java/src/org/chromium/ui/util/KeyboardNavigationListener.java similarity index 97% rename from components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/KeyboardNavigationListener.java rename to ui/android/java/src/org/chromium/ui/util/KeyboardNavigationListener.java index 8abdd8e4..10c7375 100644 --- a/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/KeyboardNavigationListener.java +++ b/ui/android/java/src/org/chromium/ui/util/KeyboardNavigationListener.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.components.browser_ui.util; +package org.chromium.ui.util; import android.view.KeyEvent; import android.view.View;
diff --git a/ui/gfx/android/android_surface_control_compat.cc b/ui/gfx/android/android_surface_control_compat.cc index befe5a9d..38afa24 100644 --- a/ui/gfx/android/android_surface_control_compat.cc +++ b/ui/gfx/android/android_surface_control_compat.cc
@@ -505,8 +505,8 @@ // Xor with a mask to reduce likelihood of flow id collision with non-surface // tasks. First 64-bits of SHA256 hash of "SurfaceControl::Transaction", // interpreted as a big-endian integer. Python snippet: - // hashlib.sha256(b'SurfaceControl::Transaction').hexdigest()[:8] - constexpr uint64_t kMask = 0x11119f59; + // hashlib.sha256(b'SurfaceControl::Transaction').hexdigest()[:16] + constexpr uint64_t kMask = 0x11119f59bb2a2b31; return kMask ^ transaction_id; }
diff --git a/ui/gfx/mac/io_surface.cc b/ui/gfx/mac/io_surface.cc index dfe1a6f0..d9b2479 100644 --- a/ui/gfx/mac/io_surface.cc +++ b/ui/gfx/mac/io_surface.cc
@@ -325,10 +325,10 @@ if (should_clear) { // Zero-initialize the IOSurface. Calling IOSurfaceLock/IOSurfaceUnlock // appears to be sufficient. https://crbug.com/584760#c17 - IOReturn r = IOSurfaceLock(surface.get(), 0, nullptr); - DCHECK_EQ(kIOReturnSuccess, r); + kern_return_t r = IOSurfaceLock(surface.get(), 0, nullptr); + DCHECK_EQ(KERN_SUCCESS, r); r = IOSurfaceUnlock(surface.get(), 0, nullptr); - DCHECK_EQ(kIOReturnSuccess, r); + DCHECK_EQ(KERN_SUCCESS, r); } // Ensure that all IOSurfaces start as sRGB.
diff --git a/ui/gfx/mac/io_surface.h b/ui/gfx/mac/io_surface.h index 7bf30e59..631c5bee7 100644 --- a/ui/gfx/mac/io_surface.h +++ b/ui/gfx/mac/io_surface.h
@@ -5,7 +5,6 @@ #ifndef UI_GFX_MAC_IO_SURFACE_H_ #define UI_GFX_MAC_IO_SURFACE_H_ -#include <IOKit/IOReturn.h> #include <IOSurface/IOSurfaceRef.h> #include <mach/mach.h>
diff --git a/ui/gfx/win/wuc_backdrop.cc b/ui/gfx/win/wuc_backdrop.cc index ba7daf3..2e485b8 100644 --- a/ui/gfx/win/wuc_backdrop.cc +++ b/ui/gfx/win/wuc_backdrop.cc
@@ -4,7 +4,7 @@ #include "ui/gfx/win/wuc_backdrop.h" -#include <dispatcherqueue.h> +#include <DispatcherQueue.h> #include <windows.ui.composition.core.h> #include <wrl/client.h>
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index 4072c41..fdcd3263 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -64,6 +64,8 @@ "host/gtk_surface1.h", "host/linux_ui_delegate_wayland.cc", "host/linux_ui_delegate_wayland.h", + "host/org_kde_kwin_appmenu.cc", + "host/org_kde_kwin_appmenu.h", "host/org_kde_kwin_idle.cc", "host/org_kde_kwin_idle.h", "host/overlay_prioritizer.cc", @@ -261,6 +263,7 @@ "//third_party/wayland-protocols:linux_dmabuf_protocol", "//third_party/wayland-protocols:linux_drm_syncobj_protocol", "//third_party/wayland-protocols:linux_explicit_synchronization_protocol", + "//third_party/wayland-protocols:org_kde_kwin_appmenu", "//third_party/wayland-protocols:org_kde_kwin_idle", "//third_party/wayland-protocols:pointer_constraints_protocol", "//third_party/wayland-protocols:pointer_gestures_protocol",
diff --git a/ui/ozone/platform/wayland/common/wayland_object.cc b/ui/ozone/platform/wayland/common/wayland_object.cc index f6190ffc..a3b43ac 100644 --- a/ui/ozone/platform/wayland/common/wayland_object.cc +++ b/ui/ozone/platform/wayland/common/wayland_object.cc
@@ -5,6 +5,7 @@ #include "ui/ozone/platform/wayland/common/wayland_object.h" #include <alpha-compositing-unstable-v1-client-protocol.h> +#include <appmenu-client-protocol.h> #include <chrome-color-management-client-protocol.h> #include <content-type-v1-client-protocol.h> #include <cursor-shape-v1-client-protocol.h> @@ -107,6 +108,10 @@ } } +void delete_appmenu(org_kde_kwin_appmenu* appmenu) { + org_kde_kwin_appmenu_release(appmenu); +} + } // namespace bool CanBind(const std::string& interface, @@ -160,6 +165,9 @@ IMPLEMENT_WAYLAND_OBJECT_TRAITS(gtk_primary_selection_source) IMPLEMENT_WAYLAND_OBJECT_TRAITS(gtk_shell1) IMPLEMENT_WAYLAND_OBJECT_TRAITS_WITH_DELETER(gtk_surface1, delete_gtk_surface1) +IMPLEMENT_WAYLAND_OBJECT_TRAITS_WITH_DELETER(org_kde_kwin_appmenu, + delete_appmenu) +IMPLEMENT_WAYLAND_OBJECT_TRAITS(org_kde_kwin_appmenu_manager) IMPLEMENT_WAYLAND_OBJECT_TRAITS(org_kde_kwin_idle) IMPLEMENT_WAYLAND_OBJECT_TRAITS(org_kde_kwin_idle_timeout) IMPLEMENT_WAYLAND_OBJECT_TRAITS(overlay_prioritizer)
diff --git a/ui/ozone/platform/wayland/common/wayland_object.h b/ui/ozone/platform/wayland/common/wayland_object.h index 8a1caa3e..f107706 100644 --- a/ui/ozone/platform/wayland/common/wayland_object.h +++ b/ui/ozone/platform/wayland/common/wayland_object.h
@@ -109,6 +109,8 @@ DECLARE_WAYLAND_OBJECT_TRAITS(gtk_primary_selection_source) DECLARE_WAYLAND_OBJECT_TRAITS(gtk_shell1) DECLARE_WAYLAND_OBJECT_TRAITS(gtk_surface1) +DECLARE_WAYLAND_OBJECT_TRAITS(org_kde_kwin_appmenu) +DECLARE_WAYLAND_OBJECT_TRAITS(org_kde_kwin_appmenu_manager) DECLARE_WAYLAND_OBJECT_TRAITS(org_kde_kwin_idle) DECLARE_WAYLAND_OBJECT_TRAITS(org_kde_kwin_idle_timeout) DECLARE_WAYLAND_OBJECT_TRAITS(overlay_prioritizer)
diff --git a/ui/ozone/platform/wayland/host/org_kde_kwin_appmenu.cc b/ui/ozone/platform/wayland/host/org_kde_kwin_appmenu.cc new file mode 100644 index 0000000..1d796d8 --- /dev/null +++ b/ui/ozone/platform/wayland/host/org_kde_kwin_appmenu.cc
@@ -0,0 +1,69 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/ozone/platform/wayland/host/org_kde_kwin_appmenu.h" + +#include <appmenu-client-protocol.h> + +#include "base/logging.h" +#include "ui/ozone/platform/wayland/host/wayland_connection.h" + +namespace ui { + +namespace { +constexpr uint32_t kVersion = 1; +} // namespace + +// static +constexpr char OrgKdeKwinAppmenuManager::kInterfaceName[]; + +// static +void OrgKdeKwinAppmenuManager::Instantiate(WaylandConnection* connection, + wl_registry* registry, + uint32_t name, + const std::string& interface, + uint32_t version) { + CHECK_EQ(interface, kInterfaceName) << "Expected \"" << kInterfaceName + << "\" but got \"" << interface << "\""; + + if (connection->org_kde_kwin_appmenu_manager_ || + !wl::CanBind(interface, version, kVersion, kVersion)) { + return; + } + + auto manager = + wl::Bind<org_kde_kwin_appmenu_manager>(registry, name, kVersion); + if (!manager) { + LOG(ERROR) << "Failed to bind to org_kde_kwin_appmenu_manager global"; + return; + } + connection->org_kde_kwin_appmenu_manager_ = + std::make_unique<OrgKdeKwinAppmenuManager>(manager.release(), connection); +} + +OrgKdeKwinAppmenuManager::OrgKdeKwinAppmenuManager( + org_kde_kwin_appmenu_manager* manager, + WaylandConnection* connection) + : manager_(manager), connection_(connection) {} + +OrgKdeKwinAppmenuManager::~OrgKdeKwinAppmenuManager() = default; + +std::unique_ptr<OrgKdeKwinAppmenu> OrgKdeKwinAppmenuManager::Create( + wl_surface* surface) { + return std::make_unique<OrgKdeKwinAppmenu>( + org_kde_kwin_appmenu_manager_create(manager_.get(), surface)); +} + +OrgKdeKwinAppmenu::OrgKdeKwinAppmenu(org_kde_kwin_appmenu* appmenu) + : appmenu_(appmenu) {} + +OrgKdeKwinAppmenu::~OrgKdeKwinAppmenu() = default; + +void OrgKdeKwinAppmenu::SetAddress(const std::string& service_name, + const std::string& object_path) { + org_kde_kwin_appmenu_set_address(appmenu_.get(), service_name.c_str(), + object_path.c_str()); +} + +} // namespace ui
diff --git a/ui/ozone/platform/wayland/host/org_kde_kwin_appmenu.h b/ui/ozone/platform/wayland/host/org_kde_kwin_appmenu.h new file mode 100644 index 0000000..021b6c8 --- /dev/null +++ b/ui/ozone/platform/wayland/host/org_kde_kwin_appmenu.h
@@ -0,0 +1,56 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_ORG_KDE_KWIN_APPMENU_H_ +#define UI_OZONE_PLATFORM_WAYLAND_HOST_ORG_KDE_KWIN_APPMENU_H_ + +#include "base/memory/raw_ptr.h" +#include "ui/ozone/platform/wayland/common/wayland_object.h" + +namespace ui { + +class OrgKdeKwinAppmenu { + public: + explicit OrgKdeKwinAppmenu(org_kde_kwin_appmenu* appmenu); + OrgKdeKwinAppmenu(const OrgKdeKwinAppmenu&) = delete; + OrgKdeKwinAppmenu& operator=(const OrgKdeKwinAppmenu&) = delete; + ~OrgKdeKwinAppmenu(); + + void SetAddress(const std::string& service_name, + const std::string& object_path); + + private: + wl::Object<org_kde_kwin_appmenu> appmenu_; +}; + +// Wraps the KDE Wayland appmenu manager, which is provided via +// org_kde_kwin_appmenu_manager interface. +class OrgKdeKwinAppmenuManager + : public wl::GlobalObjectRegistrar<OrgKdeKwinAppmenuManager> { + public: + static constexpr const char kInterfaceName[] = "org_kde_kwin_appmenu_manager"; + + static void Instantiate(WaylandConnection* connection, + wl_registry* registry, + uint32_t name, + const std::string& interface, + uint32_t version); + + OrgKdeKwinAppmenuManager(org_kde_kwin_appmenu_manager* manager, + WaylandConnection* connection); + OrgKdeKwinAppmenuManager(const OrgKdeKwinAppmenuManager&) = delete; + OrgKdeKwinAppmenuManager& operator=(const OrgKdeKwinAppmenuManager&) = delete; + ~OrgKdeKwinAppmenuManager(); + + std::unique_ptr<OrgKdeKwinAppmenu> Create(wl_surface* surface); + + private: + wl::Object<org_kde_kwin_appmenu_manager> manager_; + + const raw_ptr<WaylandConnection> connection_; +}; + +} // namespace ui + +#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_ORG_KDE_KWIN_APPMENU_H_
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc index 7ccde0a5..d7e74f7a 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.cc +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
@@ -34,6 +34,7 @@ #include "ui/ozone/platform/wayland/host/fractional_scale_manager.h" #include "ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.h" #include "ui/ozone/platform/wayland/host/gtk_shell1.h" +#include "ui/ozone/platform/wayland/host/org_kde_kwin_appmenu.h" #include "ui/ozone/platform/wayland/host/org_kde_kwin_idle.h" #include "ui/ozone/platform/wayland/host/overlay_prioritizer.h" #include "ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.h" @@ -156,6 +157,8 @@ &GtkPrimarySelectionDeviceManager::Instantiate); RegisterGlobalObjectFactory(GtkShell1::kInterfaceName, &GtkShell1::Instantiate); + RegisterGlobalObjectFactory(OrgKdeKwinAppmenuManager::kInterfaceName, + &OrgKdeKwinAppmenuManager::Instantiate); RegisterGlobalObjectFactory(OrgKdeKwinIdle::kInterfaceName, &OrgKdeKwinIdle::Instantiate); RegisterGlobalObjectFactory(OverlayPrioritizer::kInterfaceName,
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h index 0add10d..2350c41 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.h +++ b/ui/ozone/platform/wayland/host/wayland_connection.h
@@ -42,6 +42,7 @@ class GtkPrimarySelectionDeviceManager; class GtkShell1; +class OrgKdeKwinAppmenuManager; class OrgKdeKwinIdle; class OverlayPrioritizer; class SinglePixelBuffer; @@ -220,6 +221,10 @@ GtkShell1* gtk_shell1() { return gtk_shell1_.get(); } + OrgKdeKwinAppmenuManager* org_kde_kwin_appmenu_manager() const { + return org_kde_kwin_appmenu_manager_.get(); + } + OrgKdeKwinIdle* org_kde_kwin_idle() { return org_kde_kwin_idle_.get(); } ZwpPrimarySelectionDeviceManager* zwp_primary_selection_device_manager() @@ -334,6 +339,7 @@ friend class FractionalScaleManager; friend class GtkPrimarySelectionDeviceManager; friend class GtkShell1; + friend class OrgKdeKwinAppmenuManager; friend class OrgKdeKwinIdle; friend class OverlayPrioritizer; friend class SinglePixelBuffer; @@ -489,6 +495,7 @@ std::unique_ptr<GtkShell1> gtk_shell1_; // Objects specific to KDE Plasma desktop environment. + std::unique_ptr<OrgKdeKwinAppmenuManager> org_kde_kwin_appmenu_manager_; std::unique_ptr<OrgKdeKwinIdle> org_kde_kwin_idle_; std::unique_ptr<WaylandDataDragController> data_drag_controller_;
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc index b672dd4..8920fea 100644 --- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
@@ -23,6 +23,7 @@ #include "ui/ozone/platform/wayland/host/dump_util.h" #include "ui/ozone/platform/wayland/host/gtk_shell1.h" #include "ui/ozone/platform/wayland/host/gtk_surface1.h" +#include "ui/ozone/platform/wayland/host/org_kde_kwin_appmenu.h" #include "ui/ozone/platform/wayland/host/wayland_bubble.h" #include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h" #include "ui/ozone/platform/wayland/host/wayland_connection.h" @@ -162,6 +163,7 @@ toplevel_session_.reset(); xdg_toplevel_.reset(); + appmenu_.reset(); ClearInFlightRequestsSerial(); connection()->Flush(); @@ -710,6 +712,22 @@ pointer_constraints->UnlockPointer(); } +void WaylandToplevelWindow::SetAppmenu(const std::string& service_name, + const std::string& object_path) { + appmenu_service_name_ = service_name; + appmenu_object_path_ = object_path; + + if (xdg_toplevel_) { + TryAnnounceAppmenu(); + } +} + +void WaylandToplevelWindow::UnsetAppmenu() { + appmenu_.reset(); + appmenu_service_name_.clear(); + appmenu_object_path_.clear(); +} + void WaylandToplevelWindow::SetSystemModal(bool modal) { system_modal_ = modal; if (xdg_toplevel_) { @@ -878,6 +896,8 @@ gtk_surface1_ = connection()->gtk_shell1()->GetGtkSurface1(root_surface()->surface()); } + + TryAnnounceAppmenu(); } void WaylandToplevelWindow::OnDecorationModeChanged() { @@ -923,4 +943,13 @@ } } +void WaylandToplevelWindow::TryAnnounceAppmenu() { + if (auto* appmenu_manager = connection()->org_kde_kwin_appmenu_manager()) { + if (!appmenu_service_name_.empty() && !appmenu_object_path_.empty()) { + appmenu_ = appmenu_manager->Create(root_surface()->surface()); + appmenu_->SetAddress(appmenu_service_name_, appmenu_object_path_); + } + } +} + } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h index e7aaee4af..487e5b5 100644 --- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h +++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h
@@ -31,6 +31,7 @@ namespace ui { class GtkSurface1; +class OrgKdeKwinAppmenu; class XdgToplevel; class WaylandToplevelWindow : public WaylandWindow, @@ -130,6 +131,9 @@ bool allow_system_drag) override; bool SupportsPointerLock() override; void LockPointer(bool enabled) override; + void SetAppmenu(const std::string& service_name, + const std::string& object_path) override; + void UnsetAppmenu() override; // WorkspaceExtension: std::string GetWorkspace() const override; @@ -189,6 +193,9 @@ // configure-time stages of the toplevel window initialization. void UpdateSessionStateIfNeeded(); + // Try to announce the appmenu associated with this toplevel, if there's any. + void TryAnnounceAppmenu(); + std::unique_ptr<XdgToplevel> xdg_toplevel_; // True if it's maximized before requesting the window state change from the @@ -245,6 +252,11 @@ this}; std::unique_ptr<XdgToplevelSession> toplevel_session_; + // Global application menu integration. + std::unique_ptr<OrgKdeKwinAppmenu> appmenu_; + std::string appmenu_service_name_; + std::string appmenu_object_path_; + base::WeakPtrFactory<WaylandToplevelWindow> weak_ptr_factory_{this}; };
diff --git a/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/ui/ozone/platform/wayland/ozone_platform_wayland.cc index d871f691..5c0851e 100644 --- a/ui/ozone/platform/wayland/ozone_platform_wayland.cc +++ b/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -415,6 +415,9 @@ properties.supports_native_pixmaps = surface_factory_->SupportsNativePixmaps(); } + + properties.supports_global_application_menus = + connection_->org_kde_kwin_appmenu_manager() != nullptr; } else if (buffer_manager_) { DCHECK(has_initialized_gpu()); // These properties are set when the GetPlatformRuntimeProperties is
diff --git a/ui/ozone/platform/x11/ozone_platform_x11.cc b/ui/ozone/platform/x11/ozone_platform_x11.cc index 35023e3..dcca94fc 100644 --- a/ui/ozone/platform/x11/ozone_platform_x11.cc +++ b/ui/ozone/platform/x11/ozone_platform_x11.cc
@@ -195,7 +195,6 @@ properties->supports_vulkan_swap_chain = true; properties->skia_can_fall_back_to_x11 = true; properties->platform_shows_drag_image = false; - properties->supports_global_application_menus = true; properties->app_modal_dialogs_use_event_blocker = true; properties->fetch_buffer_formats_for_gmb_on_gpu = true; @@ -219,6 +218,7 @@ properties.supports_server_window_menus = x11::Connection::Get()->WmSupportsHint( x11::GetAtom("_GTK_SHOW_WINDOW_MENU")); + properties.supports_global_application_menus = true; return properties; }
diff --git a/ui/ozone/public/ozone_platform.h b/ui/ozone/public/ozone_platform.h index e35bd76..1384e162 100644 --- a/ui/ozone/public/ozone_platform.h +++ b/ui/ozone/public/ozone_platform.h
@@ -136,10 +136,6 @@ // If true, the platform shows and updates the drag image. bool platform_shows_drag_image = true; - // Linux only, but see a TODO in BrowserDesktopWindowTreeHostLinux. - // Determines whether the platform supports the global application menu. - bool supports_global_application_menus = false; - // Determines if the application modal dialogs should use the event blocker // to allow the only browser window receiving UI events. bool app_modal_dialogs_use_event_blocker = false; @@ -213,6 +209,10 @@ // Whether windowing system level session management is supported. If set, // GetSessionManager method must return a valid object. bool supports_session_management = false; + + // Linux only, but see a TODO in BrowserDesktopWindowTreeHostLinux. + // Determines whether the platform supports the global application menu. + bool supports_global_application_menus = false; }; // Corresponds to chrome_browser_main_extra_parts.h.
diff --git a/ui/platform_window/extensions/wayland_extension.h b/ui/platform_window/extensions/wayland_extension.h index 4dc290c..2fba9cd 100644 --- a/ui/platform_window/extensions/wayland_extension.h +++ b/ui/platform_window/extensions/wayland_extension.h
@@ -59,6 +59,15 @@ virtual bool SupportsPointerLock() = 0; virtual void LockPointer(bool enabled) = 0; + // Associates a dbus appmenu that has the specified service name and the + // object path with this toplevel. The dbus appmenu implements the + // com.canonical.dbusmenu interface. + virtual void SetAppmenu(const std::string& service_name, + const std::string& object_path) = 0; + + // Unsets the appmenu associated with this toplevel. + virtual void UnsetAppmenu() = 0; + protected: virtual ~WaylandToplevelExtension();
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.cc b/ui/views/bubble/bubble_dialog_delegate_view.cc index f5441b9..1d4dfaa 100644 --- a/ui/views/bubble/bubble_dialog_delegate_view.cc +++ b/ui/views/bubble/bubble_dialog_delegate_view.cc
@@ -444,7 +444,6 @@ close_on_deactivate_pins_(std::make_unique<CloseOnDeactivatePin::Pins>()), bubble_created_time_(base::TimeTicks::Now()) { bubble_uma_logger().set_delegate(this); - SetOwnedByWidget(true); SetAnchorView(anchor_view); SetArrow(arrow); SetShowCloseButton(false); @@ -538,7 +537,6 @@ bool autosize) : BubbleDialogDelegate(anchor_view, arrow, shadow, autosize) { bubble_uma_logger().set_bubble_view(this); - SetOwnedByWidget(false); } BubbleDialogDelegateView::~BubbleDialogDelegateView() {
diff --git a/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc b/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc index e22d71c6c..e1339e9b 100644 --- a/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc +++ b/ui/views/bubble/bubble_dialog_delegate_view_unittest.cc
@@ -1408,6 +1408,7 @@ auto anchored_view = std::make_unique<View>(); BubbleDialogDelegate delegate(anchored_view.get(), BubbleBorder::Arrow::TOP_LEFT); + delegate.SetOwnedByWidget(true); delegate.SetContentsView(std::make_unique<Label>()); TestBubbleUmaLogger logger;
diff --git a/ui/views/bubble/bubble_dialog_model_host.cc b/ui/views/bubble/bubble_dialog_model_host.cc index f1d62ec1..44426b1f 100644 --- a/ui/views/bubble/bubble_dialog_model_host.cc +++ b/ui/views/bubble/bubble_dialog_model_host.cc
@@ -851,6 +851,7 @@ base::BindRepeating(&BubbleDialogModelHost::OnContentsViewChanged, base::Unretained(this)))), theme_observer_(this, contents_view_) { + SetOwnedByWidget(true); model_->set_host(DialogModelHost::GetPassKey(), this); // Dialog callbacks can safely refer to |model_|, they can't be called after
diff --git a/ui/views/focus/focus_traversal_unittest.cc b/ui/views/focus/focus_traversal_unittest.cc index 51c4fe5d..ada4a2b 100644 --- a/ui/views/focus/focus_traversal_unittest.cc +++ b/ui/views/focus/focus_traversal_unittest.cc
@@ -217,6 +217,7 @@ std::unique_ptr<Widget> CreateBubbleDialog() { auto delegate = std::make_unique<BubbleDialogDelegate>( style_tab_, BubbleBorder::TOP_LEFT); + delegate->SetOwnedByWidget(true); auto root_view = std::make_unique<MdTextButton>(Button::PressedCallback(), u"bubble button"); delegate->SetContentsView(std::move(root_view));
diff --git a/ui/views/views_features.cc b/ui/views/views_features.cc index a62be74d..4c6ae8f 100644 --- a/ui/views/views_features.cc +++ b/ui/views/views_features.cc
@@ -44,11 +44,4 @@ "KeyboardAccessibleTooltipInViews", base::FEATURE_ENABLED_BY_DEFAULT); -// Whether the window appearance follows the color provider's color mode. -// This is only effective for mac. Some plumbing is not restricted to mac, -// therefore this flag is included in all platforms. -BASE_FEATURE(kMacWindowFollowsColorProviderColorMode, - "MacWindowFollowsColorProviderColorMode", - base::FEATURE_ENABLED_BY_DEFAULT); - } // namespace views::features
diff --git a/ui/views/views_features.h b/ui/views/views_features.h index bc1658c..d586436 100644 --- a/ui/views/views_features.h +++ b/ui/views/views_features.h
@@ -17,7 +17,6 @@ VIEWS_EXPORT BASE_DECLARE_FEATURE(kEnableTouchDragCursorSync); VIEWS_EXPORT BASE_DECLARE_FEATURE(kEnableTransparentHwndEnlargement); VIEWS_EXPORT BASE_DECLARE_FEATURE(kKeyboardAccessibleTooltipInViews); -VIEWS_EXPORT BASE_DECLARE_FEATURE(kMacWindowFollowsColorProviderColorMode); } // namespace views::features
diff --git a/ui/views/widget/native_widget_aura_unittest.cc b/ui/views/widget/native_widget_aura_unittest.cc index a7c5ecc5..25128e02 100644 --- a/ui/views/widget/native_widget_aura_unittest.cc +++ b/ui/views/widget/native_widget_aura_unittest.cc
@@ -78,6 +78,8 @@ bool can_activate_ = true; }; +} // namespace + class NativeWidgetAuraTest : public ViewsTestBase { public: NativeWidgetAuraTest() = default; @@ -863,7 +865,6 @@ TEST_F(NativeWidgetAuraTest, TransientChildModalWindowVisibility) { // Create the delegate first so it's destroyed last. auto delegate_owned = std::make_unique<WidgetDelegate>(); - delegate_owned->SetOwnedByWidget(false); // Create a parent window. auto parent = std::make_unique<Widget>(); Widget::InitParams parent_params(Widget::InitParams::CLIENT_OWNS_WIDGET, @@ -1126,5 +1127,4 @@ native_widget_->UpdateVisualState(); } -} // namespace } // namespace views
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index 4aa1343..897646ac 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -550,9 +550,7 @@ } void NativeWidgetMac::SetColorMode(ui::ColorProviderKey::ColorMode color_mode) { - if (ns_window_host_ && - base::FeatureList::IsEnabled( - features::kMacWindowFollowsColorProviderColorMode)) { + if (ns_window_host_) { ns_window_host_->SetColorMode(color_mode); } }
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc index dd8404d6..c06a5a40 100644 --- a/ui/views/widget/widget_unittest.cc +++ b/ui/views/widget/widget_unittest.cc
@@ -165,9 +165,7 @@ public: explicit WidgetTestBubbleDialogDelegateView(View* anchor) - : BubbleDialogDelegateView(anchor, BubbleBorder::NONE) { - SetOwnedByWidget(false); - } + : BubbleDialogDelegateView(anchor, BubbleBorder::NONE) {} ~WidgetTestBubbleDialogDelegateView() override = default; bool ShouldShowCloseButton() const override {
diff --git a/v8 b/v8 index 9737790..bd4ded6 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit 9737790587bc0ce61a1ffc9fadde3abf70dbb5a9 +Subproject commit bd4ded6cee0c3cbd1106937be7a43116671692b2