diff --git a/DEPS b/DEPS index 3c55f24b..2321183 100644 --- a/DEPS +++ b/DEPS
@@ -307,7 +307,7 @@ # 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': 'b14b07f77468cf45e4bdca467c187090c9a7dbd3', + 'v8_revision': 'fa0dfe29a7bcc29e36b243add34a83844ce8b21a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -394,7 +394,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': '393a4b1223f616d755c9fe7e125ac92b47196acc', + 'devtools_frontend_revision': '884d920106c5a692e7f55b415cbc2f351650456f', # 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. @@ -450,7 +450,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling nearby # and whatever else without interference from each other. - 'nearby_revision': '63e744e1338412c5ad17094f22445c6dfe71de6e', + 'nearby_revision': '850c3e2788015668572249d205d91d6af78c5739', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling securemessage # and whatever else without interference from each other. @@ -818,12 +818,12 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '7feb1ebbf40bb986c85f970d6872415eaf686f07', + 'e4f08e8b415dc075f27de50dd82ccd0ae82b9b2c', 'condition': 'checkout_android and checkout_src_internal', }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + '504421a2e612c9042411ae65e24d7a7682dfdbe2', + 'url': Var('chromium_git') + '/website.git' + '@' + 'b848d511837d6ccd44c6f7bef1576c0842d7e0ac', }, 'src/ios/third_party/earl_grey2/src': { @@ -1196,7 +1196,7 @@ Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '9405c73532966c47623ae2c6389b7b065aa6414f', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '2a585a1bc1c2ae0d74870e33dd0f66b9aecce629', 'condition': 'checkout_src_internal', }, @@ -1459,7 +1459,7 @@ Var('chromium_git') + '/external/libaddressinput.git' + '@' + 'e8712e415627f22d0b00ebee8db99547077f39bd', 'src/third_party/libaom/source/libaom': - Var('aomedia_git') + '/aom.git' + '@' + 'ce0ee71ca6aa97e2f564a05a8045699d29c18834', + Var('aomedia_git') + '/aom.git' + '@' + 'ebe946034afb793a69d71fc864b561e691e403de', 'src/third_party/libavif/src': Var('chromium_git') + '/external/github.com/AOMediaCodec/libavif.git' + '@' + Var('libavif_revision'), @@ -1661,7 +1661,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '1072e37cbb64611f0b911427c6c2e497d4925881', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'fa384c4660e10ae4390efd2dbeaa67b0fad58044', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1846,7 +1846,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'eb1892c3e4ab734a135e8752f5442e270a4738d1', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '70ad987c64d6c8467d33ad2acf658ce3a6691d0b', + Var('webrtc_git') + '/src.git' + '@' + '8f4df7bec911f867059fdc3102242a4c45b0f70b', # 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. @@ -3955,7 +3955,7 @@ 'src/components/plus_addresses/resources/internal': { 'url': Var('chrome_git') + '/chrome/components/plus_addresses/resources.git' + '@' + - '65376fc4825ef797744bbdda81d2e571ded37ad8', + '8babd9da0911bfc8afe09c49358d10be85a2558e', 'condition': 'checkout_src_internal', }, @@ -4009,7 +4009,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - '37b02362be97b8b735e8a28a496f01e664ddc9ea', + '1be329bcbd76dfac79c8324e6fee465326c761d5', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/android_webview/browser/aw_feature_map.cc b/android_webview/browser/aw_feature_map.cc index 27dc4bdb..8d84d5a 100644 --- a/android_webview/browser/aw_feature_map.cc +++ b/android_webview/browser/aw_feature_map.cc
@@ -22,7 +22,6 @@ // (e.g. content/, components/, etc). const base::Feature* const kFeaturesExposedToJava[] = { &features::kWebViewConnectionlessSafeBrowsing, - &features::kWebViewMetricsFiltering, &features::kWebViewDisplayCutout, &features::kWebViewExitReasonMetric, &features::kWebViewMixedContentAutoupgrades,
diff --git a/android_webview/browser/metrics/aw_metrics_service_client.cc b/android_webview/browser/metrics/aw_metrics_service_client.cc index 1557405..224faa5e 100644 --- a/android_webview/browser/metrics/aw_metrics_service_client.cc +++ b/android_webview/browser/metrics/aw_metrics_service_client.cc
@@ -109,19 +109,12 @@ } int AwMetricsServiceClient::GetSampleRatePerMille() const { - if (base::FeatureList::IsEnabled(features::kWebViewMetricsFiltering)) { - return 1000; - } - return GetBaseSampleRatePerMille(); + return 1000; } bool AwMetricsServiceClient::ShouldApplyMetricsFiltering() const { - if (base::FeatureList::IsEnabled(features::kWebViewMetricsFiltering)) { - bool used_to_sample_in = - GetSampleBucketValue() < GetBaseSampleRatePerMille(); - return !used_to_sample_in; - } - return false; + bool used_to_sample_in = GetSampleBucketValue() < GetBaseSampleRatePerMille(); + return !used_to_sample_in; } std::string AwMetricsServiceClient::GetAppPackageNameIfLoggable() {
diff --git a/android_webview/browser/metrics/aw_metrics_service_client.h b/android_webview/browser/metrics/aw_metrics_service_client.h index 30c778a..cfcc16c 100644 --- a/android_webview/browser/metrics/aw_metrics_service_client.h +++ b/android_webview/browser/metrics/aw_metrics_service_client.h
@@ -151,12 +151,8 @@ // Always returns `true`, indicating to record the package name bool ShouldRecordPackageName() override; - // If `android_webview::features::kWebViewMetricsFiltering` is - // enabled: // - return `true` if client used to be sampled out. // - return `false` if client used to be in-sampled. - // - // If the feature isn't enabled, return false. virtual bool ShouldApplyMetricsFiltering() const; protected:
diff --git a/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc b/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc index 285113f..b4daee73 100644 --- a/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc +++ b/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc
@@ -169,24 +169,8 @@ "Android.WebView.AppDataDirectory.TimeToComputeSize", 0); } -TEST_F(AwMetricsServiceClientTest, TestShouldApplyMetricsFilteringFeatureOff) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndDisableFeature( - android_webview::features::kWebViewMetricsFiltering); - - // Both metrics consent and app consent true; - GetClient()->SetHaveMetricsConsent(true, true); - - EXPECT_EQ(GetClient()->GetSampleRatePerMille(), 20); - EXPECT_EQ(GetClient()->ShouldApplyMetricsFiltering(), false); -} - TEST_F(AwMetricsServiceClientTest, TestShouldApplyMetricsFilteringFeatureOn_AllMetrics) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - android_webview::features::kWebViewMetricsFiltering); - // Both metrics consent and app consent true; GetClient()->SetHaveMetricsConsent(true, true); GetClient()->SetSampleBucketValue(19); @@ -197,10 +181,6 @@ TEST_F(AwMetricsServiceClientTest, TestShouldApplyMetricsFilteringFeatureOn_OnlyCriticalMetrics) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - android_webview::features::kWebViewMetricsFiltering); - // Both metrics consent and app consent true; GetClient()->SetHaveMetricsConsent(true, true); GetClient()->SetSampleBucketValue(20);
diff --git a/android_webview/common/aw_features.cc b/android_webview/common/aw_features.cc index 2b922fc..38d3a812 100644 --- a/android_webview/common/aw_features.cc +++ b/android_webview/common/aw_features.cc
@@ -94,12 +94,6 @@ "WebViewJavaJsBridgeMojo", base::FEATURE_DISABLED_BY_DEFAULT); -// Enable reporting filtered metrics from webview clients used to be -// out-sampled. -BASE_FEATURE(kWebViewMetricsFiltering, - "WebViewMetricsFiltering", - base::FEATURE_ENABLED_BY_DEFAULT); - // Field trial feature for controlling support of Origin Trials on WebView. BASE_FEATURE(kWebViewOriginTrials, "WebViewOriginTrials",
diff --git a/android_webview/common/aw_features.h b/android_webview/common/aw_features.h index 4b8b2536..a8026d9b 100644 --- a/android_webview/common/aw_features.h +++ b/android_webview/common/aw_features.h
@@ -31,7 +31,6 @@ BASE_DECLARE_FEATURE(kWebViewInjectPlatformJsApis); BASE_DECLARE_FEATURE(kWebViewJavaJsBridgeMojo); BASE_DECLARE_FEATURE(kWebViewMediaIntegrityApi); -BASE_DECLARE_FEATURE(kWebViewMetricsFiltering); BASE_DECLARE_FEATURE(kWebViewMixedContentAutoupgrades); BASE_DECLARE_FEATURE(kWebViewOriginTrials); BASE_DECLARE_FEATURE(kWebViewRecordAppDataDirectorySize);
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 fdb67fa..4ed5790 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
@@ -595,10 +595,6 @@ "When enabled, blocks rendering on font preloads to reduce CLS. " + "See go/critical-font-analysis"), Flag.baseFeature( - AwFeatures.WEBVIEW_METRICS_FILTERING, - "If enabled, clients used to be out-sampled will report filtered metrics." - + " This has no effect if metrics reporting is disabled"), - Flag.baseFeature( SafeBrowsingFeatures.SAFE_BROWSING_SKIP_SUBRESOURCES, "When enabled, Safe Browsing will skip subresources"), Flag.baseFeature( @@ -720,11 +716,6 @@ "Enables PartitionAlloc's MemoryReclaimer, which tries decommitting unused " + "system pages as much as possible so that other applications can " + "reuse the memory pages."), - Flag.baseFeature(VizFeatures.EVICT_SUBTREE, "Enables evicting entire tree of surfaces."), - Flag.baseFeature( - ContentFeatures.NAVIGATION_UPDATES_CHILD_VIEWS_VISIBILITY, - "Enables notifying children of the top-most RenderWidgetHostView that they " - + "were hidden during a navigation."), Flag.baseFeature( BlinkFeatures.FORM_CONTROLS_VERTICAL_WRITING_MODE_TEXT_SUPPORT, "Enables support for CSS vertical writing mode on text-based form controls."),
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 8c04017..e772e09 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
@@ -6,9 +6,7 @@ import android.content.Context; -import org.chromium.android_webview.AwFeatureMap; import org.chromium.android_webview.R; -import org.chromium.android_webview.common.AwFeatures; import org.chromium.base.ContextUtils; import org.chromium.components.metrics.HistogramEventProtos.HistogramEventProto; @@ -23,8 +21,6 @@ private final Set<Long> mHistogramNameHashes; public HistogramsAllowlist() { - assert AwFeatureMap.isEnabled(AwFeatures.WEBVIEW_METRICS_FILTERING) - : "HistogramsAllowlist must not be initialized if metrics filtering is not enabled"; Context appContext = ContextUtils.getApplicationContext(); InputStream inputStream = appContext.getResources().openRawResource(R.raw.histograms_allowlist);
diff --git a/android_webview/java/src/org/chromium/android_webview/metrics/MetricsFilteringDecorator.java b/android_webview/java/src/org/chromium/android_webview/metrics/MetricsFilteringDecorator.java index 6bbe980..3081a0b 100644 --- a/android_webview/java/src/org/chromium/android_webview/metrics/MetricsFilteringDecorator.java +++ b/android_webview/java/src/org/chromium/android_webview/metrics/MetricsFilteringDecorator.java
@@ -6,8 +6,6 @@ import com.google.protobuf.InvalidProtocolBufferException; -import org.chromium.android_webview.AwFeatureMap; -import org.chromium.android_webview.common.AwFeatures; import org.chromium.base.Log; import org.chromium.components.metrics.AndroidMetricsLogConsumer; import org.chromium.components.metrics.ChromeUserMetricsExtensionProtos.ChromeUserMetricsExtension; @@ -24,14 +22,8 @@ private final HistogramsAllowlist mHistogramsAllowlist; public MetricsFilteringDecorator(AndroidMetricsLogConsumer uploader) { - // Class initialization requires native to be loaded to query WEBVIEW_METRICS_FILTERING - // feature state. mLogUploader = uploader; - if (AwFeatureMap.isEnabled(AwFeatures.WEBVIEW_METRICS_FILTERING)) { - mHistogramsAllowlist = new HistogramsAllowlist(); - } else { - mHistogramsAllowlist = null; - } + mHistogramsAllowlist = new HistogramsAllowlist(); } @Override @@ -47,16 +39,6 @@ } private byte[] applyMetricsFilteringIfNeeded(byte[] data) { - // Avoid parsing the proto if the feature is disabled to compare the performance of the - // control and experiment groups. - // Note: This has the edge case that a log uploaded from a previous session could have - // METRICS_ONLY_CRITICAL set, but could get uploaded with full metrics if the feature is - // disabled (mHistogramsAllowlist == null) during this session. This is a known issue and is - // an acceptable trade off in order to be able to accurately measure the impact of proto - // deserialization. - if (mHistogramsAllowlist == null) { - return data; - } try { ChromeUserMetricsExtension proto = ChromeUserMetricsExtension.parseFrom(data); if (shouldApplyMetricsFiltering(proto)) {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/MetricsFilteringDecoratorTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/MetricsFilteringDecoratorTest.java index ad504f42..b5ca958b 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/MetricsFilteringDecoratorTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/MetricsFilteringDecoratorTest.java
@@ -14,12 +14,10 @@ import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.UseParametersRunnerFactory; -import org.chromium.android_webview.common.AwFeatures; import org.chromium.android_webview.common.PlatformServiceBridge; import org.chromium.android_webview.metrics.AwMetricsUtils; import org.chromium.android_webview.metrics.MetricsFilteringDecorator; import org.chromium.base.test.util.Batch; -import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.components.metrics.AndroidMetricsLogConsumer; import org.chromium.components.metrics.ChromeUserMetricsExtensionProtos.ChromeUserMetricsExtension; @@ -74,7 +72,6 @@ @Test @Feature({"AndroidWebView"}) - @CommandLineFlags.Add("enable-features=" + AwFeatures.WEBVIEW_METRICS_FILTERING) public void testMetricsFiltering_applied() throws Throwable { ChromeUserMetricsExtension log = ChromeUserMetricsExtension.newBuilder() @@ -114,7 +111,6 @@ @Test @Feature({"AndroidWebView"}) - @CommandLineFlags.Add("enable-features=" + AwFeatures.WEBVIEW_METRICS_FILTERING) public void testMetricsFiltering_notApplied() throws Throwable { ChromeUserMetricsExtension log = ChromeUserMetricsExtension.newBuilder() @@ -135,7 +131,6 @@ @Test @Feature({"AndroidWebView"}) - @CommandLineFlags.Add("enable-features=" + AwFeatures.WEBVIEW_METRICS_FILTERING) public void testMetricsFiltering_missingSystemProfile() throws Throwable { ChromeUserMetricsExtension log = ChromeUserMetricsExtension.newBuilder() @@ -149,39 +144,4 @@ // We expect to receive an identical log to the one we provided. Assert.assertEquals(log, receivedLog); } - - @Test - @Feature({"AndroidWebView"}) - @CommandLineFlags.Add("disable-features=" + AwFeatures.WEBVIEW_METRICS_FILTERING) - public void testMetricsFiltering_featureOff() throws Throwable { - // Note: It should not typically be the case that a METRICS_ONLY_CRITICAL log is - // processed while the feature is off, however this can happen in the following - // scenario: - // 1. Feature is enabled for some clients. - // 2. Clients generate METRICS_ONLY_CRITICAL logs, but not all of them are sent (e.g. no - // network connection) - // 3. Feature gets disabled for those clients (e.g. server-side config change) - // 4. Clients go to upload previously generated logs - // - // This is an edge case that would happen to a small subset of logs in the case - // the feature gets disabled. Although the above results in METRICS_ONLY_CRITICAL - // logs containing full data, we are OK with that behavior given the feature check - // on the Java side ensures we are able to evaluate the performance impact of - // the proto parsing code. - ChromeUserMetricsExtension log = - ChromeUserMetricsExtension.newBuilder() - .setSystemProfile( - SystemProfileProto.newBuilder() - .setMetricsFilteringStatus( - MetricsFilteringStatus.METRICS_ONLY_CRITICAL)) - .addHistogramEvent(createHistogramWithName("Histogram.Not.In.Allowlist")) - .addUserActionEvent(getUserAction()) - .build(); - - int status = mUploader.log(log.toByteArray()); - Assert.assertEquals(HttpURLConnection.HTTP_OK, status); - ChromeUserMetricsExtension receivedLog = mPlatformServiceBridge.waitForNextMetricsLog(); - // We expect to receive an identical log to the one we provided. - Assert.assertEquals(log, receivedLog); - } }
diff --git a/ash/dbus/gesture_properties_service_provider.cc b/ash/dbus/gesture_properties_service_provider.cc index 44d12ee..7d6e6a7 100644 --- a/ash/dbus/gesture_properties_service_provider.cc +++ b/ash/dbus/gesture_properties_service_provider.cc
@@ -84,8 +84,7 @@ case ui::ozone::mojom::GesturePropValue::Tag::kInts: { writer.AppendUint32(values->get_ints().size()); writer.OpenVariant("ai", &variant_writer); - variant_writer.AppendArrayOfInt32s(values->get_ints().data(), - values->get_ints().size()); + variant_writer.AppendArrayOfInt32s(values->get_ints()); writer.CloseContainer(&variant_writer); break; } @@ -119,8 +118,7 @@ case ui::ozone::mojom::GesturePropValue::Tag::kReals: { writer.AppendUint32(values->get_reals().size()); writer.OpenVariant("ad", &variant_writer); - variant_writer.AppendArrayOfDoubles(values->get_reals().data(), - values->get_reals().size()); + variant_writer.AppendArrayOfDoubles(values->get_reals()); writer.CloseContainer(&variant_writer); break; }
diff --git a/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl.cc b/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl.cc index d54efbd7..44ada42 100644 --- a/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl.cc +++ b/ash/quick_pair/scanning/fast_pair/fast_pair_discoverable_scanner_impl.cc
@@ -393,7 +393,7 @@ /*address=*/it->first, /*model_id=*/it->second)); - pending_devices_address_to_model_id_.erase(it); + it = pending_devices_address_to_model_id_.erase(it); } }
diff --git a/ash/system/message_center/ash_notification_view.cc b/ash/system/message_center/ash_notification_view.cc index 40ab7fc6..a1ccf08 100644 --- a/ash/system/message_center/ash_notification_view.cc +++ b/ash/system/message_center/ash_notification_view.cc
@@ -1643,6 +1643,11 @@ : *notification; } +std::vector<views::LabelButton*> +AshNotificationView::GetActionButtonsForTest() { + return action_buttons(); +} + views::Label* AshNotificationView::GetTitleRowLabelForTest() { return title_row_->title_view(); }
diff --git a/ash/system/message_center/ash_notification_view.h b/ash/system/message_center/ash_notification_view.h index 670e41cf..88b02438 100644 --- a/ash/system/message_center/ash_notification_view.h +++ b/ash/system/message_center/ash_notification_view.h
@@ -147,6 +147,8 @@ return control_buttons_view_; } + std::vector<views::LabelButton*> GetActionButtonsForTest(); + views::Label* GetTitleRowLabelForTest(); // View containing all grouped notifications, propagates size changes
diff --git a/ash/system/notification_center/notification_list_view.cc b/ash/system/notification_center/notification_list_view.cc index 8d74645..f4d7316 100644 --- a/ash/system/notification_center/notification_list_view.cc +++ b/ash/system/notification_center/notification_list_view.cc
@@ -788,6 +788,14 @@ InterruptClearAll(); ResetBounds(); + // `child` Can be deleted by either `InterruptClearAll` or `ResetBounds` since + // both call `DeleteRemovedNotifications`. Therefore, we need to check if it + // exists again. See https://b/315187548 + child = GetNotificationById(id); + if (!child) { + return; + } + child->set_is_removed(); // If the MessageView is slid out, then do nothing here. The MOVE_DOWN
diff --git a/ash/webui/camera_app_ui/resources.h b/ash/webui/camera_app_ui/resources.h index 94b59ee..3a72b92 100644 --- a/ash/webui/camera_app_ui/resources.h +++ b/ash/webui/camera_app_ui/resources.h
@@ -81,6 +81,8 @@ {"label_back_camera", IDS_LABEL_BACK_CAMERA}, {"label_barcode_text", IDS_LABEL_BARCODE_TEXT}, {"label_barcode_url", IDS_LABEL_BARCODE_URL}, + {"label_barcode_wifi", IDS_LABEL_BARCODE_WIFI}, + {"label_barcode_wifi_chip", IDS_LABEL_BARCODE_WIFI_CHIP}, {"label_crop_done", IDS_LABEL_CROP_DONE}, {"label_current_and_maximal_record_time", IDS_LABEL_CURRENT_AND_MAXIMAL_RECORD_TIME},
diff --git a/ash/webui/camera_app_ui/resources/js/barcode_chip.ts b/ash/webui/camera_app_ui/resources/js/barcode_chip.ts index d3923e02..92aaa1c 100644 --- a/ash/webui/camera_app_ui/resources/js/barcode_chip.ts +++ b/ash/webui/camera_app_ui/resources/js/barcode_chip.ts
@@ -259,12 +259,17 @@ const container = dom.get('#barcode-chip-wifi-container', HTMLDivElement); activate(container); + const ssidString = assertExists(wifiConfig.ssid); + const textEl = dom.get('#barcode-chip-wifi-content', HTMLSpanElement); - const label = loadTimeData.getI18nMessage( - I18nString.BARCODE_WIFI_CHIPTEXT, assertExists(wifiConfig.ssid)); - textEl.textContent = label; + const text = + loadTimeData.getI18nMessage(I18nString.BARCODE_WIFI_CHIPTEXT, ssidString); + textEl.textContent = text; const chip = dom.get('#barcode-chip-wifi', HTMLDivElement); + const label = loadTimeData.getI18nMessage( + I18nString.LABEL_BARCODE_WIFI_CHIP, ssidString); + chip.setAttribute('aria-label', label); chip.onclick = () => { // TODO(dorahkim): After is crrev/c/4964660 is landed, connect to the Wi-fi // here.
diff --git a/ash/webui/camera_app_ui/resources/js/i18n_string.ts b/ash/webui/camera_app_ui/resources/js/i18n_string.ts index 26762be..786c537 100644 --- a/ash/webui/camera_app_ui/resources/js/i18n_string.ts +++ b/ash/webui/camera_app_ui/resources/js/i18n_string.ts
@@ -70,6 +70,8 @@ LABEL_BACK_CAMERA = 'label_back_camera', LABEL_BARCODE_TEXT = 'label_barcode_text', LABEL_BARCODE_URL = 'label_barcode_url', + LABEL_BARCODE_WIFI = 'label_barcode_wifi', + LABEL_BARCODE_WIFI_CHIP = 'label_barcode_wifi_chip', LABEL_CROP_DONE = 'label_crop_done', LABEL_CURRENT_AND_MAXIMAL_RECORD_TIME = 'label_current_and_maximal_record_time',
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings.grd b/ash/webui/camera_app_ui/resources/strings/camera_strings.grd index 9be2181a..b10efa8 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings.grd +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings.grd
@@ -296,7 +296,13 @@ URL detected. </message> <message desc="Text showing on the barcode chip when wifi is detected under scan mode." name="IDS_BARCODE_WIFI_CHIPTEXT"> - Join "<ph name="wifiname">$1<ex>wifi network name</ex></ph>" Network + Join "<ph name="wifiname">$1<ex>wifi network name</ex></ph>" + </message> + <message desc="Label for the barcode chip when wifi is detected under scan mode." name="IDS_LABEL_BARCODE_WIFI"> + Wi-Fi network detected. + </message> + <message desc="Label for the barcode chip when wifi is detected under scan mode." name="IDS_LABEL_BARCODE_WIFI_CHIP"> + Join <ph name="wifiname">$1<ex>wifi network name</ex></ph> </message> <message desc="Label for the button of expert mode options." name="IDS_EXPERT_MODE_BUTTON"> Expert mode
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_BARCODE_WIFI_CHIPTEXT.png.sha1 b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_BARCODE_WIFI_CHIPTEXT.png.sha1 index d6c88dc..7372b93 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_BARCODE_WIFI_CHIPTEXT.png.sha1 +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_BARCODE_WIFI_CHIPTEXT.png.sha1
@@ -1 +1 @@ -af4f79a26b8c636c5c571cd3e5c8cc4fbfa08f48 \ No newline at end of file +c7fc44edb568b50f525d06416c977d264c0d85f8 \ No newline at end of file
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_LABEL_BARCODE_WIFI.png.sha1 b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_LABEL_BARCODE_WIFI.png.sha1 new file mode 100644 index 0000000..7372b93 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_LABEL_BARCODE_WIFI.png.sha1
@@ -0,0 +1 @@ +c7fc44edb568b50f525d06416c977d264c0d85f8 \ No newline at end of file
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_LABEL_BARCODE_WIFI_CHIP.png.sha1 b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_LABEL_BARCODE_WIFI_CHIP.png.sha1 new file mode 100644 index 0000000..7372b93 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_LABEL_BARCODE_WIFI_CHIP.png.sha1
@@ -0,0 +1 @@ +c7fc44edb568b50f525d06416c977d264c0d85f8 \ No newline at end of file
diff --git a/ash/webui/camera_app_ui/resources/views/main.html b/ash/webui/camera_app_ui/resources/views/main.html index 69120d2b..686c75c 100644 --- a/ash/webui/camera_app_ui/resources/views/main.html +++ b/ash/webui/camera_app_ui/resources/views/main.html
@@ -137,7 +137,9 @@ </div> </div> <div id="barcode-chip-wifi-container" - class="invisible barcode-chip-container"> + class="invisible barcode-chip-container" + role="dialog" + i18n-label="label_barcode_wifi"> <div id="barcode-chip-wifi" tabindex="0" role="button"> <svg-wrapper name="wifi.svg"></svg-wrapper>
diff --git a/ash/webui/os_feedback_ui/resources/confirmation_page.ts b/ash/webui/os_feedback_ui/resources/confirmation_page.ts index 26a5bfc..79b4017 100644 --- a/ash/webui/os_feedback_ui/resources/confirmation_page.ts +++ b/ash/webui/os_feedback_ui/resources/confirmation_page.ts
@@ -10,6 +10,7 @@ import './os_feedback_shared.css.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; +import {OpenWindowProxyImpl} from 'chrome://resources/js/open_window_proxy.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './confirmation_page.html.js'; @@ -119,10 +120,9 @@ break; case 'chromebookCommunity': // If app locale is not available, default to en. - window.open( + OpenWindowProxyImpl.getInstance().openUrl( `https://support.google.com/chromebook/?hl=${ - this.i18n('language') || 'en'}#topic=3399709`, - '_blank'); + this.i18n('language') || 'en'}#topic=3399709`); this.handleEmitMetrics( FeedbackAppPostSubmitAction.kOpenChromebookCommunity); break;
diff --git a/ash/webui/personalization_app/resources/BUILD.gn b/ash/webui/personalization_app/resources/BUILD.gn index 989c56e..079c76d3 100644 --- a/ash/webui/personalization_app/resources/BUILD.gn +++ b/ash/webui/personalization_app/resources/BUILD.gn
@@ -89,6 +89,7 @@ "js/wallpaper/sea_pen/sea_pen_template_query_element.ts", "js/wallpaper/sea_pen/sea_pen_images_element.ts", "js/wallpaper/sea_pen/sea_pen_recent_wallpapers_element.ts", + "js/wallpaper/sea_pen/sea_pen_router_element.ts", "js/wallpaper/sea_pen/sea_pen_templates_element.ts", "js/wallpaper/sea_pen/sparkle_placeholder_element.ts", "js/wallpaper/time_of_day_wallpaper_dialog_element.ts", @@ -100,7 +101,6 @@ "js/wallpaper/wallpaper_preview_element.ts", "js/wallpaper/wallpaper_selected_element.ts", "js/wallpaper/wallpaper_subpage_element.ts", - "js/wallpaper/wallpaper_subpage_top_element.ts", ] non_web_component_files = [
diff --git a/ash/webui/personalization_app/resources/js/personalization_app.ts b/ash/webui/personalization_app/resources/js/personalization_app.ts index 8782409a..c621a85e 100644 --- a/ash/webui/personalization_app/resources/js/personalization_app.ts +++ b/ash/webui/personalization_app/resources/js/personalization_app.ts
@@ -123,9 +123,11 @@ export {SeaPenImagesElement} from './wallpaper/sea_pen/sea_pen_images_element.js'; export {SeaPenInputQueryElement} from './wallpaper/sea_pen/sea_pen_input_query_element.js'; export {SeaPenRecentWallpapersElement} from './wallpaper/sea_pen/sea_pen_recent_wallpapers_element.js'; +export {SeaPenRouterElement, SeaPenPaths} from './wallpaper/sea_pen/sea_pen_router_element.js'; export {SeaPenState} from './wallpaper/sea_pen/sea_pen_state.js'; export {getSeaPenStore, setSeaPenStore, SeaPenStoreInterface} from './wallpaper/sea_pen/sea_pen_store.js'; export {SeaPenTemplateQueryElement} from './wallpaper/sea_pen/sea_pen_template_query_element.js'; +export {SeaPenTemplatesElement} from './wallpaper/sea_pen/sea_pen_templates_element.js'; export {setSeaPenProviderForTesting} from './wallpaper/sea_pen/sea_pen_interface_provider.js'; export {SparklePlaceholderElement} from './wallpaper/sea_pen/sparkle_placeholder_element.js'; export {isDefaultImage, isGooglePhotosPhoto, isWallpaperImage} from './wallpaper/utils.js'; @@ -141,7 +143,6 @@ export {WallpaperPreviewElement} from './wallpaper/wallpaper_preview_element.js'; export {WallpaperSelectedElement} from './wallpaper/wallpaper_selected_element.js'; export {WallpaperSubpageElement} from './wallpaper/wallpaper_subpage_element.js'; -export {WallpaperSubpageTopElement} from './wallpaper/wallpaper_subpage_top_element.js'; export {DailyRefreshType} from './wallpaper/wallpaper_state.js'; export {TimeOfDayAcceptEvent, TimeOfDayWallpaperDialogElement} from './wallpaper/time_of_day_wallpaper_dialog_element.js';
diff --git a/ash/webui/personalization_app/resources/js/personalization_router_element.html b/ash/webui/personalization_app/resources/js/personalization_router_element.html index ec19c7f..c2345f3 100644 --- a/ash/webui/personalization_app/resources/js/personalization_router_element.html +++ b/ash/webui/personalization_app/resources/js/personalization_router_element.html
@@ -73,5 +73,8 @@ <wallpaper-subpage path="[[path_]]" query-params="[[queryParams_]]"> </wallpaper-subpage> </template> + <template is="dom-if" if="[[shouldShowSeaPen_(path_)]]" restamp> + <sea-pen-router base-path="[[seaPenBasePath_]]"></sea-pen-router> + </template> <personalization-toast></personalization-toast> </div>
diff --git a/ash/webui/personalization_app/resources/js/personalization_router_element.ts b/ash/webui/personalization_app/resources/js/personalization_router_element.ts index d4ea9d95..049a1d4 100644 --- a/ash/webui/personalization_app/resources/js/personalization_router_element.ts +++ b/ash/webui/personalization_app/resources/js/personalization_router_element.ts
@@ -19,6 +19,8 @@ import {isAmbientModeAllowed} from './load_time_booleans.js'; import {logPersonalizationPathUMA} from './personalization_metrics_logger.js'; import {getTemplate} from './personalization_router_element.html.js'; +import {isSeaPenEnabled} from './wallpaper/sea_pen/load_time_booleans.js'; +import {SeaPenQueryParams} from './wallpaper/sea_pen/sea_pen_router_element.js'; import {WallpaperObserver} from './wallpaper/wallpaper_observer.js'; export enum Paths { @@ -38,14 +40,13 @@ TOPIC_SOURCE_LIST = 'topic-source-list' } -export interface QueryParams { +export interface QueryParams extends SeaPenQueryParams { id?: string; googlePhotosAlbumId?: string; // If present, expected to always be 'true'. googlePhotosAlbumIsShared?: 'true'; topicSource?: string; scrollTo?: ScrollableTarget; - seaPenTemplateId?: string; } export function isPathValid(path: string|null): boolean { @@ -64,6 +65,14 @@ return isAmbientPath(path) && !isAmbientModeAllowed(); } +export function isSeaPenPath(path: string|null): boolean { + return !!path && path.startsWith(Paths.SEA_PEN_COLLECTION); +} + +export function isSeaPenPathNotAllowed(path: string|null): boolean { + return isSeaPenPath(path) && !isSeaPenEnabled(); +} + export class PersonalizationRouterElement extends PolymerElement { static get is() { return 'personalization-router'; @@ -87,11 +96,19 @@ queryParams_: { type: Object, }, + + seaPenBasePath_: { + type: String, + value() { + return Paths.SEA_PEN_COLLECTION; + }, + }, }; } private path_: string; private query_: string; private queryParams_: QueryParams; + private seaPenBasePath_: string; static instance(): PersonalizationRouterElement { return document.querySelector(PersonalizationRouterElement.is) as @@ -154,10 +171,6 @@ this.goToRoute(Paths.AMBIENT_ALBUMS, {topicSource: topicSource.toString()}); } - selectSeaPenTemplate(templateId: string) { - this.goToRoute(Paths.SEA_PEN_COLLECTION, {seaPenTemplateId: templateId}); - } - goToRoute(path: Paths, queryParams: QueryParams = {}) { this.setProperties({path_: path, queryParams_: queryParams}); } @@ -177,7 +190,12 @@ } private shouldShowWallpaperSubpage_(path: string|null): boolean { - return !!path && path.startsWith(Paths.COLLECTIONS); + return !!path && path.startsWith(Paths.COLLECTIONS) && + !path.startsWith(Paths.SEA_PEN_COLLECTION); + } + + private shouldShowSeaPen_(path: string|null): boolean { + return isSeaPenEnabled() && isSeaPenPath(path); } private shouldShowBreadcrumb_(path: string|null): boolean { @@ -192,7 +210,8 @@ // Navigates to the top of the subpage. window.scrollTo(0, 0); - if (!isPathValid(path) || isAmbientPathNotAllowed(path)) { + if (!isPathValid(path) || isAmbientPathNotAllowed(path) || + isSeaPenPathNotAllowed(path)) { // Reset the path to root. this.setProperties({path_: Paths.ROOT, queryParams_: {}}); }
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/index.ts b/ash/webui/personalization_app/resources/js/wallpaper/index.ts index 5900fe8..e72bf05 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/index.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/index.ts
@@ -17,7 +17,6 @@ import './wallpaper_preview_element.js'; import './wallpaper_selected_element.js'; import './wallpaper_subpage_element.js'; -import './wallpaper_subpage_top_element.js'; import './sea_pen/sea_pen_images_element.js'; import './sea_pen/sea_pen_input_query_element.js'; import './sea_pen/sea_pen_recent_wallpapers_element.js';
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.ts index 7a6cc7c98..8a72613 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.ts
@@ -18,12 +18,13 @@ import {assert} from 'chrome://resources/js/assert.js'; import {MAXIMUM_SEARCH_WALLPAPER_TEXT_BYTES, SeaPenQuery} from '../../../sea_pen.mojom-webui.js'; -import {Paths, PersonalizationRouterElement} from '../../personalization_router_element.js'; import {QUERY} from './constants.js'; +import {isSeaPenTextInputEnabled} from './load_time_booleans.js'; import {searchSeaPenThumbnails} from './sea_pen_controller.js'; import {getTemplate} from './sea_pen_input_query_element.html.js'; import {getSeaPenProvider} from './sea_pen_interface_provider.js'; +import {SeaPenPaths, SeaPenRouterElement} from './sea_pen_router_element.js'; import {WithSeaPenStore} from './sea_pen_store.js'; export class SeaPenInputQueryElement extends WithSeaPenStore { @@ -54,6 +55,7 @@ path: string; override connectedCallback() { + assert(isSeaPenTextInputEnabled(), 'sea pen text input must be enabled'); super.connectedCallback(); this.watch<SeaPenInputQueryElement['thumbnailsLoading_']>( 'thumbnailsLoading_', state => state.loading.thumbnails); @@ -62,22 +64,33 @@ private onClickInputQuerySearchButton_() { assert(this.textValue_, 'input query should not be empty.'); - const query = { + const query: SeaPenQuery = { textQuery: this.textValue_, - } as SeaPenQuery; + }; searchSeaPenThumbnails(query, getSeaPenProvider(), this.getStore()); - PersonalizationRouterElement.instance().goToRoute( - Paths.SEA_PEN_RESULTS, {seaPenTemplateId: QUERY}); + SeaPenRouterElement.instance().goToRoute( + SeaPenPaths.RESULTS, {seaPenTemplateId: QUERY}); } - private getSearchButtonText_(path: string): string { + private getSearchButtonText_(path: string|null): string { // TODO(b/308200616) Add finalized text. - return path === Paths.SEA_PEN_COLLECTION ? 'Search' : 'Search again'; + switch (path) { + case SeaPenPaths.RESULTS: + return 'Search again'; + case SeaPenPaths.ROOT: + default: + return 'Search'; + } } - private getSearchButtonIcon_(path: string): string { - return path === Paths.SEA_PEN_COLLECTION ? 'sea-pen:photo-spark' : - 'personalization:refresh'; + private getSearchButtonIcon_(path: string|null): string { + switch (path) { + case SeaPenPaths.RESULTS: + return 'personalization:refresh'; + case SeaPenPaths.ROOT: + default: + return 'sea-pen:photo-spark'; + } } } customElements.define(SeaPenInputQueryElement.is, SeaPenInputQueryElement);
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_router_element.html b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_router_element.html new file mode 100644 index 0000000..3c80ad5e --- /dev/null +++ b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_router_element.html
@@ -0,0 +1,21 @@ +<div id="seaPenContainer"> + <iron-location path="{{path_}}" query="{{query_}}" dwell-time="200"> + </iron-location> + <iron-query-params params-object="{{queryParams_}}" params-string="{{query_}}"> + </iron-query-params> + <template is="dom-if" if="[[shouldShowTextInputQuery_(relativePath_, queryParams_.seaPenTemplateId)]]"> + <sea-pen-input-query path="[[relativePath_]]"></sea-pen-input-query> + </template> + <template is="dom-if" if="[[shouldShowTemplateQuery_(relativePath_, queryParams_.seaPenTemplateId)]]"> + <sea-pen-template-query template-id="[[queryParams_.seaPenTemplateId]]" path="[[relativePath_]]"> + </sea-pen-template-query> + </template> + <template is="dom-if" if="[[shouldShowSeaPenRoot_(relativePath_)]]"> + <sea-pen-templates></sea-pen-templates> + <sea-pen-recent-wallpapers></sea-pen-recent-wallpapers> + </template> + <template is="dom-if" if="[[shouldShowSeaPenImages_(relativePath_)]]"> + <sea-pen-images template-id="[[queryParams.seaPenTemplateId]]"> + </sea-pen-images> + </template> +</div>
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_router_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_router_element.ts new file mode 100644 index 0000000..32df1d45 --- /dev/null +++ b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_router_element.ts
@@ -0,0 +1,144 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/polymer/v3_0/iron-location/iron-location.js'; +import 'chrome://resources/polymer/v3_0/iron-location/iron-query-params.js'; +import './sea_pen_input_query_element.js'; +import './sea_pen_template_query_element.js'; +import './sea_pen_templates_element.js'; +import './sea_pen_images_element.js'; + +import {assert} from 'chrome://resources/js/assert.js'; +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {QUERY} from './constants.js'; +import {isSeaPenEnabled, isSeaPenTextInputEnabled} from './load_time_booleans.js'; +import {getTemplate} from './sea_pen_router_element.html.js'; + +export enum SeaPenPaths { + ROOT = '', + RESULTS = '/results', +} + +export interface SeaPenQueryParams { + seaPenTemplateId?: string; +} + +let instance: SeaPenRouterElement|null = null; + +export class SeaPenRouterElement extends PolymerElement { + static get is() { + return 'sea-pen-router'; + } + static get template() { + return getTemplate(); + } + static get properties() { + return { + basePath: String, + path_: String, + + query_: String, + + queryParams_: Object, + + relativePath_: { + type: String, + computed: 'computeRelativePath_(path_, basePath)', + }, + }; + } + + static instance(): SeaPenRouterElement { + assert(instance, 'sea pen router does not exist'); + return instance; + } + + basePath: string; + private path_: string; + private query_: string; + private queryParams_: SeaPenQueryParams; + private relativePath_: string|null; + + override connectedCallback() { + assert(isSeaPenEnabled(), 'sea pen must be enabled'); + super.connectedCallback(); + instance = this; + } + + override disconnectedCallback() { + super.disconnectedCallback(); + instance = null; + } + + selectSeaPenTemplate(templateId: string) { + this.goToRoute(SeaPenPaths.ROOT, {seaPenTemplateId: templateId}); + } + + goToRoute(path: SeaPenPaths, queryParams: SeaPenQueryParams = {}) { + assert(typeof this.basePath === 'string', 'basePath must be set'); + this.setProperties( + {path_: this.basePath + path, queryParams_: queryParams}); + } + + /** + * Compute the relative path compared to the SeaPen base path. + * @param path the absolute path of the current route + * @param basePath the absolute path of the base seapen route + * @returns path relative to basePath, or null if path is not relative to + * basePath + * @example + * computeRelativePath_('/wallpaper/sea_pen', '/wallpaper/sea_pen') => '' + * computeRelativePath_('/wallpaper/sea_pen/results', '/wallpaper/sea_pen') => + * '/results' + * computeRelativePath_('/wallpaper', '/wallpaper/sea_pen') => null + */ + private computeRelativePath_(path: string|null, basePath: string|null): string + |null { + if (typeof path !== 'string' || typeof basePath !== 'string') { + return null; + } + if (!path.startsWith(basePath)) { + return null; + } + return path.substring(basePath.length); + } + + private shouldShowTextInputQuery_( + relativePath: string|null, templateId: string|null): boolean { + return isSeaPenTextInputEnabled() && + (relativePath === SeaPenPaths.ROOT || + relativePath === SeaPenPaths.RESULTS) && + (templateId === QUERY || !templateId); + } + + private shouldShowTemplateQuery_( + relativePath: string|null, templateId: string|null): boolean { + return (relativePath === SeaPenPaths.ROOT || + relativePath === SeaPenPaths.RESULTS) && + (!!templateId && templateId !== QUERY); + } + + private shouldShowSeaPenRoot_(relativePath: string|null): boolean { + if (typeof relativePath !== 'string') { + return false; + } + return relativePath === SeaPenPaths.ROOT; + } + + private shouldShowSeaPenImages_(relativePath: string|null): boolean { + if (typeof relativePath !== 'string') { + return false; + } + return relativePath === SeaPenPaths.RESULTS; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'sea-pen-router': SeaPenRouterElement; + } +} + +customElements.define(SeaPenRouterElement.is, SeaPenRouterElement);
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_template_query_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_template_query_element.ts index 2f95284..342225d 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_template_query_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_template_query_element.ts
@@ -13,11 +13,11 @@ import {assert} from 'chrome://resources/js/assert.js'; import {SeaPenQuery, SeaPenTemplateChip, SeaPenTemplateId, SeaPenTemplateOption} from '../../../sea_pen.mojom-webui.js'; -import {Paths, PersonalizationRouterElement} from '../../personalization_router_element.js'; import {getSeaPenTemplates, parseTemplateText, SeaPenOption, SeaPenTemplate} from './constants.js'; import {searchSeaPenThumbnails} from './sea_pen_controller.js'; import {getSeaPenProvider} from './sea_pen_interface_provider.js'; +import {SeaPenPaths, SeaPenRouterElement} from './sea_pen_router_element.js'; import {WithSeaPenStore} from './sea_pen_store.js'; import {getTemplate} from './sea_pen_template_query_element.html.js'; @@ -240,18 +240,29 @@ private onClickSearchButton_() { searchSeaPenThumbnails( this.getTemplateRequest_(), getSeaPenProvider(), this.getStore()); - PersonalizationRouterElement.instance().goToRoute( - Paths.SEA_PEN_RESULTS, {seaPenTemplateId: this.templateId!.toString()}); + SeaPenRouterElement.instance().goToRoute( + SeaPenPaths.RESULTS, {seaPenTemplateId: this.templateId!.toString()}); } - private getSearchButtonText_(path: string): string { + private getSearchButtonText_(path: string|null): string { // TODO(b/308200616) Add finalized text. - return path === Paths.SEA_PEN_COLLECTION ? 'Search' : 'Search again'; + switch (path) { + case SeaPenPaths.RESULTS: + return 'Search again'; + case SeaPenPaths.ROOT: + default: + return 'Search'; + } } - private getSearchButtonIcon_(path: string): string { - return path === Paths.SEA_PEN_COLLECTION ? 'sea-pen:photo-spark' : - 'personalization:refresh'; + private getSearchButtonIcon_(path: string|null): string { + switch (path) { + case SeaPenPaths.RESULTS: + return 'personalization:refresh'; + case SeaPenPaths.ROOT: + default: + return 'sea-pen:photo-spark'; + } } }
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_templates_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_templates_element.ts index 52f5484..5179cde6 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_templates_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_templates_element.ts
@@ -11,9 +11,8 @@ import {assert} from 'chrome://resources/js/assert.js'; -import {PersonalizationRouterElement} from '../../personalization_router_element.js'; - import {getSeaPenTemplates, SeaPenTemplate} from './constants.js'; +import {SeaPenRouterElement} from './sea_pen_router_element.js'; import {WithSeaPenStore} from './sea_pen_store.js'; import {getTemplate} from './sea_pen_templates_element.html.js'; @@ -29,7 +28,9 @@ return { seaPenTemplates_: { type: Array, - computed: 'computeSeaPenTemplates_()', + value() { + return getSeaPenTemplates(); + }, }, selected_: Object, @@ -39,10 +40,6 @@ private seaPenTemplates_: SeaPenTemplate[]; private selected_: SeaPenTemplate; - private computeSeaPenTemplates_(): SeaPenTemplate[] { - return getSeaPenTemplates(); - } - private getAriaIndex_(i: number): number { return i + 1; } @@ -53,7 +50,7 @@ const template = this.seaPenTemplates_.find( template => template.id === this.selected_.id); if (template) { - PersonalizationRouterElement.instance().selectSeaPenTemplate(template.id); + SeaPenRouterElement.instance().selectSeaPenTemplate(template.id); } } }
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_element.html b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_element.html index 79412b1..c4a3c6a1 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_element.html
@@ -12,7 +12,7 @@ width: 100%; } - wallpaper-subpage-top { + wallpaper-selected { background-color: var(--cros-bg-color); grid-area: selected; position: sticky; @@ -23,9 +23,7 @@ wallpaper-collections, wallpaper-images, google-photos-collection, - local-images, - sea-pen-images, - .sea-pen-collections { + local-images { grid-area: imagegrid; padding: 10px 0; background-color: var(--cros-bg-color); @@ -37,16 +35,14 @@ z-index: 1; } - :host-context(body.jelly-enabled) wallpaper-subpage-top { + :host-context(body.jelly-enabled) wallpaper-selected { background-color: var(--cros-sys-app_base_shaded); } :host-context(body.jelly-enabled) wallpaper-collections, wallpaper-images, google-photos-collection, - local-images, - sea-pen-images, - .sea-pen-collections { + local-images { background-color: var(--cros-bg-color); } </style> @@ -54,11 +50,10 @@ <!-- Prevent left margin from collapsing on narrow window in RTL --> <div class="leftspacertop"></div> <div class="leftspacerbottom"></div> - <wallpaper-subpage-top path="[[path]]" collection-id="[[queryParams.id]]" - google-photos-album-id="[[queryParams.googlePhotosAlbumId]]" - is-google-photos-album-shared="[[isGooglePhotosAlbumShared_]]" - template-id="[[queryParams.seaPenTemplateId]]"> - </wallpaper-subpage-top> + <wallpaper-selected path="[[path]]" collection-id="[[queryParams.id]]" + google-photos-album-id="[[queryParams.googlePhotosAlbumId]]" + is-google-photos-album-shared="[[isGooglePhotosAlbumShared_]]"> + </wallpaper-selected> <!-- do not use hidden$ here - need to listen on property change in these elements. --> <wallpaper-collections hidden="[[!shouldShowCollections_(path)]]"> @@ -75,15 +70,6 @@ <template is="dom-if" if="[[shouldShowLocalCollection_(path)]]" restamp> <local-images></local-images> </template> - <template is="dom-if" if="[[shouldShowSeaPenCollection_(path)]]" restamp> - <div class="sea-pen-collections"> - <sea-pen-templates></sea-pen-templates> - <sea-pen-recent-wallpapers></sea-pen-recent-wallpapers> - </div> - </template> - <template is="dom-if" if="[[shouldShowSeaPenResults_(path)]]"> - <sea-pen-images template-id="[[queryParams.seaPenTemplateId]]"></sea-pen-images> - </template> <!-- Prevent the right margin from collapsing when window gets very narrow --> <div class="rightspacertop"></div>
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_element.ts index 914fa95..4c32148 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_element.ts
@@ -76,12 +76,6 @@ return !!queryParams && queryParams.googlePhotosAlbumIsShared === 'true'; } - - private shouldShowWallpaperSelected_(path: string): boolean { - return !this.shouldShowSeaPenCollection_(path) || - !this.shouldShowSeaPenResults_(path); - } - private shouldShowCollections_(path: string): boolean { return path === Paths.COLLECTIONS; } @@ -98,14 +92,6 @@ private shouldShowLocalCollection_(path: string): boolean { return path === Paths.LOCAL_COLLECTION; } - - private shouldShowSeaPenCollection_(path: string): boolean { - return this.isSeaPenEnabled_ && path === Paths.SEA_PEN_COLLECTION; - } - - private shouldShowSeaPenResults_(path: string): boolean { - return this.isSeaPenEnabled_ && path === Paths.SEA_PEN_RESULTS; - } } customElements.define(WallpaperSubpageElement.is, WallpaperSubpageElement);
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_top_element.html b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_top_element.html deleted file mode 100644 index 7ebc2b5..0000000 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_top_element.html +++ /dev/null
@@ -1,12 +0,0 @@ -<template is="dom-if" if="[[shouldShowWallpaperSelectedElement_(path, templateId)]]"> - <wallpaper-selected path="[[path]]" collection-id="[[collectionId]]" - google-photos-album-id="[[googlePhotosAlbumId]]" - is-google-photos-album-shared="[[isGooglePhotosAlbumShared]]"> - </wallpaper-selected> -</template> -<template is="dom-if" if="[[shouldShowInputQuery_(path, templateId)]]"> - <sea-pen-input-query path="[[path]]"></sea-pen-input-query> -</template> -<template is="dom-if" if="[[shouldShowTemplateQuery_(path, templateId)]]" restamp> - <sea-pen-template-query template-id="[[templateId]]" path="[[path]]"></sea-pen-template-query> -</template>
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_top_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_top_element.ts deleted file mode 100644 index 3ec0be3..0000000 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_subpage_top_element.ts +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview A polymer component that shows the top element of the wallpaper - * subpage. - */ - -import {Paths} from '../personalization_router_element.js'; -import {WithPersonalizationStore} from '../personalization_store.js'; - -import {QUERY} from './sea_pen/constants.js'; -import {isSeaPenEnabled, isSeaPenTextInputEnabled} from './sea_pen/load_time_booleans.js'; -import {getTemplate} from './wallpaper_subpage_top_element.html.js'; - -export class WallpaperSubpageTopElement extends WithPersonalizationStore { - static get is() { - return 'wallpaper-subpage-top'; - } - static get template() { - return getTemplate(); - } - - static get properties() { - return { - /** - * The current collection id to display. - */ - collectionId: String, - /** - * The current Google Photos Album id to display. - */ - googlePhotosAlbumId: String, - /** - * Whether the Google Photos album is shared. - */ - isGooglePhotosAlbumShared: { - type: Boolean, - value: false, - }, - /** - * The current path of the page. - */ - path: String, - /** - * The sea pen template id. - */ - templateId: { - type: String, - }, - }; - } - - collectionId: string|undefined; - googlePhotosAlbumId: string|undefined; - isGooglePhotosAlbumShared: boolean; - path: string; - templateId: string|null; - - private shouldShowInputQuery_(path: string, templateId: string|null): - boolean { - return isSeaPenTextInputEnabled() && - (path === Paths.SEA_PEN_COLLECTION || path === Paths.SEA_PEN_RESULTS) && - (templateId === QUERY || !templateId); - } - - private shouldShowTemplateQuery_(path: string, templateId: string|null): - boolean { - return isSeaPenEnabled() && - (path === Paths.SEA_PEN_COLLECTION || path === Paths.SEA_PEN_RESULTS) && - templateId !== QUERY && !!templateId; - } - - private shouldShowWallpaperSelectedElement_( - path: string, templateId: string|null): boolean { - return !this.shouldShowInputQuery_(path, templateId) && - !this.shouldShowTemplateQuery_(path, templateId); - } -} -customElements.define( - WallpaperSubpageTopElement.is, WallpaperSubpageTopElement);
diff --git a/base/BUILD.gn b/base/BUILD.gn index e54d9ff..c8d85276 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -750,6 +750,8 @@ "task/sequence_manager/work_queue.h", "task/sequence_manager/work_queue_sets.cc", "task/sequence_manager/work_queue_sets.h", + "task/sequence_manager/work_tracker.cc", + "task/sequence_manager/work_tracker.h", "task/sequenced_task_runner.cc", "task/sequenced_task_runner.h", "task/sequenced_task_runner_helpers.h", @@ -3354,6 +3356,7 @@ "task/sequence_manager/work_deduplicator_unittest.cc", "task/sequence_manager/work_queue_sets_unittest.cc", "task/sequence_manager/work_queue_unittest.cc", + "task/sequence_manager/work_tracker_unittest.cc", "task/sequenced_task_runner_unittest.cc", "task/single_thread_task_executor_unittest.cc", "task/single_thread_task_runner_unittest.cc",
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc index 04d41195..17b0ad1 100644 --- a/base/task/sequence_manager/sequence_manager_impl.cc +++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -424,7 +424,9 @@ &TaskQueueImpl::ReloadEmptyImmediateWorkQueue, Unretained(task_queue))); } -void SequenceManagerImpl::ReloadEmptyWorkQueues() const { +void SequenceManagerImpl::ReloadEmptyWorkQueues() { + work_tracker_.WillReloadImmediateWorkQueues(); + // There are two cases where a queue needs reloading. First, it might be // completely empty and we've just posted a task (this method handles that // case). Secondly if the work queue becomes empty when calling @@ -515,12 +517,21 @@ #endif // BUILDFLAG(ENABLE_BASE_TRACING) } +void SequenceManagerImpl::SetRunTaskSynchronouslyAllowed( + bool can_run_tasks_synchronously) { + work_tracker_.SetRunTaskSynchronouslyAllowed(can_run_tasks_synchronously); +} + absl::optional<SequenceManagerImpl::SelectedTask> SequenceManagerImpl::SelectNextTask(LazyNow& lazy_now, SelectTaskOption option) { absl::optional<SelectedTask> selected_task = SelectNextTaskImpl(lazy_now, option); + if (selected_task.has_value()) { + work_tracker_.AssertHasWork(); + } + return selected_task; } @@ -652,6 +663,8 @@ } void SequenceManagerImpl::DidRunTask(LazyNow& lazy_now) { + work_tracker_.AssertHasWork(); + ExecutingTask& executing_task = *main_thread_only().task_execution_stack.rbegin(); @@ -763,6 +776,10 @@ return main_thread_only().wake_up_queue->has_pending_high_resolution_tasks(); } +void SequenceManagerImpl::OnBeginWork() { + work_tracker_.OnBeginWork(); +} + bool SequenceManagerImpl::OnIdle() { bool have_work_to_do = false; if (main_thread_only().time_domain) { @@ -772,12 +789,24 @@ } if (!have_work_to_do) { MaybeReclaimMemory(); - if (main_thread_only().on_next_idle_callback) + if (main_thread_only().on_next_idle_callback) { std::move(main_thread_only().on_next_idle_callback).Run(); + } + if (main_thread_only().task_execution_stack.empty()) { + work_tracker_.OnIdle(); + } } return have_work_to_do; } +void SequenceManagerImpl::WillRequestReloadImmediateWorkQueue() { + work_tracker_.WillRequestReloadImmediateWorkQueue(); +} + +SyncWorkAuthorization SequenceManagerImpl::TryAcquireSyncWorkAuthorization() { + return work_tracker_.TryAcquireSyncWorkAuthorization(); +} + void SequenceManagerImpl::WillQueueTask(Task* pending_task) { controller_->WillQueueTask(pending_task); } @@ -1004,6 +1033,10 @@ ScheduleWork(); } +void SequenceManagerImpl::OnWorkAvailable() { + work_tracker_.OnBeginWork(); +} + void SequenceManagerImpl::MaybeReclaimMemory() { if (!main_thread_only().memory_reclaim_scheduled) return;
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h index 68ac0dd..10b8f680 100644 --- a/base/task/sequence_manager/sequence_manager_impl.h +++ b/base/task/sequence_manager/sequence_manager_impl.h
@@ -37,6 +37,7 @@ #include "base/task/sequence_manager/task_queue_impl.h" #include "base/task/sequence_manager/task_queue_selector.h" #include "base/task/sequence_manager/thread_controller.h" +#include "base/task/sequence_manager/work_tracker.h" #include "base/task/sequenced_task_runner.h" #include "base/task/single_thread_task_runner.h" #include "base/threading/thread_checker.h" @@ -133,6 +134,8 @@ TaskQueue::QueuePriority GetPriorityCount() const override; // SequencedTaskSource implementation: + void SetRunTaskSynchronouslyAllowed( + bool can_run_tasks_synchronously) override; absl::optional<SelectedTask> SelectNextTask( LazyNow& lazy_now, SelectTaskOption option = SelectTaskOption::kDefault) override; @@ -141,6 +144,7 @@ LazyNow* lazy_now, SelectTaskOption option = SelectTaskOption::kDefault) override; bool HasPendingHighResolutionTasks() override; + void OnBeginWork() override; bool OnIdle() override; void MaybeEmitTaskDetails( perfetto::EventContext& ctx, @@ -351,6 +355,7 @@ // TaskQueueSelector::Observer: void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) override; + void OnWorkAvailable() override; // RunLoop::NestingObserver: void OnBeginNestedRunLoop() override; @@ -361,9 +366,16 @@ // class was created on. void SetNextWakeUp(LazyNow* lazy_now, absl::optional<WakeUp> wake_up); - // Called by the task queue to inform this SequenceManager of a task that's - // about to be queued. This SequenceManager may use this opportunity to add - // metadata to |pending_task| before it is moved into the queue. + // Called before TaskQueue requests to reload its empty immediate work queue. + void WillRequestReloadImmediateWorkQueue(); + + // Returns a valid `SyncWorkAuthorization` if a call to `RunOrPostTask` on a + // `SequencedTaskRunner` bound to this `SequenceManager` may run its task + // synchronously. + SyncWorkAuthorization TryAcquireSyncWorkAuthorization(); + + // Called when a task is about to be queued. May add metadata to the task and + // emit trace events. void WillQueueTask(Task* pending_task); // Enqueues onto delayed WorkQueues all delayed tasks which must run now @@ -396,7 +408,7 @@ // Calls |TakeImmediateIncomingQueueTasks| on all queues with their reload // flag set in |empty_queues_to_reload_|. - void ReloadEmptyWorkQueues() const; + void ReloadEmptyWorkQueues(); std::unique_ptr<internal::TaskQueueImpl> CreateTaskQueueImpl( const TaskQueue::Spec& spec); @@ -457,6 +469,8 @@ const MetricRecordingSettings metric_recording_settings_; + WorkTracker work_tracker_; + // Whether to add the queue time to tasks. base::subtle::Atomic32 add_queue_time_to_tasks_;
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc index e4aa5f1..049c5fa 100644 --- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc +++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -41,6 +41,7 @@ #include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h" #include "base/task/sequence_manager/work_queue.h" #include "base/task/sequence_manager/work_queue_sets.h" +#include "base/task/sequenced_task_runner.h" #include "base/task/single_thread_task_runner.h" #include "base/task/task_features.h" #include "base/test/bind.h" @@ -51,6 +52,8 @@ #include "base/test/task_environment.h" #include "base/test/test_mock_time_task_runner.h" #include "base/test/test_simple_task_runner.h" +#include "base/test/test_timeouts.h" +#include "base/threading/platform_thread.h" #include "base/threading/sequence_local_storage_slot.h" #include "base/threading/thread.h" #include "base/time/time.h" @@ -5393,6 +5396,396 @@ EXPECT_EQ(2, counter2); } +// `RunOrPostTask` is tightly integrated with `ThreadControllerWithMessagePump` +// and `RunLoop` so its tests can't use `SequenceManagerTest`. +class SequenceManagerRunOrPostTaskTest : public testing::Test { + public: + SequenceManagerRunOrPostTaskTest() { + auto settings = SequenceManager::Settings::Builder().Build(); + auto thread_controller = + std::make_unique<ThreadControllerWithMessagePumpImpl>( + std::make_unique<MessagePumpDefault>(), settings); + sequence_manager_ = SequenceManagerForTest::Create( + std::move(thread_controller), std::move(settings)); + queue_ = + sequence_manager_->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST_TQ)); + other_queue_ = + sequence_manager_->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST_TQ)); + sequence_manager_->SetDefaultTaskRunner(queue_->task_runner()); + + thread_.Start(); + } + + SequenceManagerImpl* sequence_manager() { return sequence_manager_.get(); } + TaskQueue* queue() { return queue_.get(); } + TaskQueue* other_queue() { return other_queue_.get(); } + SequencedTaskRunner* task_runner() { return queue_->task_runner().get(); } + SequencedTaskRunner* other_task_runner() { + return other_queue_->task_runner().get(); + } + SequencedTaskRunner* other_thread_task_runner() { + return thread_.task_runner().get(); + } + + void FlushOtherThread() { thread_.FlushForTesting(); } + + // Allow tasks to run synchronously. This imitates being inside a `RunLoop`, + // but allows the test's body to keep running. + void SimulateInsideRunLoop() { + sequence_manager_->SetRunTaskSynchronouslyAllowed(true); + } + + private: + std::unique_ptr<SequenceManagerForTest> sequence_manager_; + TaskQueue::Handle queue_; + TaskQueue::Handle other_queue_; + Thread thread_{"OtherThread"}; +}; + +// Verify that `RunOrPostTask` from the bound thread does not run the task +// synchronously if there is no active `RunLoop`. +TEST_F(SequenceManagerRunOrPostTaskTest, FromBoundThreadOutsideRunLoop) { + bool did_run = false; + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_run = true; }))); + EXPECT_FALSE(did_run); + RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_run); +} + +// Verify that `RunOrPostTask` from another thread does not run the task +// synchronously if there is no active `RunLoop`. +TEST_F(SequenceManagerRunOrPostTaskTest, FromOtherThreadOutsideRunLoop) { + bool did_run = false; + other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_run = true; }))); + })); + + FlushOtherThread(); + EXPECT_FALSE(did_run); + RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_run); +} + +// Verify that `RunOrPostTask` from a task running on the bound thread does not +// run the task synchronously. +TEST_F(SequenceManagerRunOrPostTaskTest, FromInsideTask) { + bool did_run = false; + EXPECT_TRUE(task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_run = true; }))); + EXPECT_FALSE(did_run); + }))); + RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_run); +} + +// Verify that `RunOrPostTask` from another thread does not run the task +// synchronously if there is a queued task. +TEST_F(SequenceManagerRunOrPostTaskTest, FromOtherThreadWithQueuedTask) { + SimulateInsideRunLoop(); + EXPECT_TRUE(task_runner()->PostTask(FROM_HERE, DoNothing())); + + bool did_run = false; + EXPECT_TRUE(other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_run = true; }))); + EXPECT_FALSE(did_run); + }))); + + FlushOtherThread(); + EXPECT_FALSE(did_run); + RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_run); +} + +// Verify that `RunOrPostTask` from another thread does not run the task +// synchronously if there is a queued task in a different queue from the same +// `SequenceManager`. +TEST_F(SequenceManagerRunOrPostTaskTest, + FromOtherThreadWithQueuedTaskOtherQueue) { + SimulateInsideRunLoop(); + EXPECT_TRUE(other_task_runner()->PostTask(FROM_HERE, DoNothing())); + + bool did_run = false; + EXPECT_TRUE(other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_run = true; }))); + EXPECT_FALSE(did_run); + }))); + + FlushOtherThread(); + EXPECT_FALSE(did_run); + RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_run); +} + +// Verify that `RunOrPostTask` from another thread runs the task synchronously +// if there is no queued or running task. +TEST_F(SequenceManagerRunOrPostTaskTest, FromOtherThreadNoQueuedOrRunningTask) { + SimulateInsideRunLoop(); + + bool did_run = false; + EXPECT_TRUE(other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_run = true; }))); + EXPECT_TRUE(did_run); + }))); + + FlushOtherThread(); + EXPECT_TRUE(did_run); +} + +// Verify that `RunOrPostTask` from another thread does not run the task +// synchronously when "internal work" is simulated. +TEST_F(SequenceManagerRunOrPostTaskTest, FromOtherThreadInternalWork) { + SimulateInsideRunLoop(); + + // Simulate internal work execution in the message pump. + sequence_manager()->OnBeginWork(); + + bool did_run = false; + EXPECT_TRUE(other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_run = true; }))); + EXPECT_FALSE(did_run); + }))); + FlushOtherThread(); + EXPECT_FALSE(did_run); + RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_run); +} + +// Verify that `RunOrPostTask` from another thread runs the task synchronously +// if there is no running task and the only queued task is in a different queue +// which is disabled. +TEST_F(SequenceManagerRunOrPostTaskTest, FromOtherThreadDisabledQueue) { + auto voter = queue()->CreateQueueEnabledVoter(); + voter->SetVoteToEnable(false); + // Reload empty work queues (tasks can't run synchronously when there are + // pending requests to reload empty work queues). + RunLoop().RunUntilIdle(); + SimulateInsideRunLoop(); + + bool did_run = false; + EXPECT_TRUE(other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_run = true; }))); + EXPECT_FALSE(did_run); + }))); + + FlushOtherThread(); + EXPECT_FALSE(did_run); + RunLoop().RunUntilIdle(); + EXPECT_FALSE(did_run); + voter.reset(); + RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_run); +} + +// Verify that `RunOrPostTask` from another thread runs the task synchronously +// if there is no running task and the only queued task is in a different queue +// which is disabled. +TEST_F(SequenceManagerRunOrPostTaskTest, + FromOtherThreadQueuedTaskInDisabledOtherQueue) { + bool did_run_other_task = false; + EXPECT_TRUE(other_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { did_run_other_task = true; }))); + auto voter = other_queue()->CreateQueueEnabledVoter(); + voter->SetVoteToEnable(false); + // Reload empty work queues (tasks can't run synchronously when there are + // pending requests to reload empty work queues). + RunLoop().RunUntilIdle(); + EXPECT_FALSE(did_run_other_task); + SimulateInsideRunLoop(); + + bool did_run = false; + EXPECT_TRUE(other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_run = true; }))); + EXPECT_TRUE(did_run); + }))); + + FlushOtherThread(); + EXPECT_TRUE(did_run); +} + +// Verify that `RunOrPostTask` from another thread does not run the task +// synchronously if there is a running task. +TEST_F(SequenceManagerRunOrPostTaskTest, FromOtherThreadWithRunningTask) { + WaitableEvent main_thread_task_running; + WaitableEvent run_or_post_task_done; + task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() { + main_thread_task_running.Signal(); + run_or_post_task_done.Wait(); + })); + + bool did_run = false; + EXPECT_TRUE(other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + main_thread_task_running.Wait(); + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_run = true; }))); + EXPECT_FALSE(did_run); + run_or_post_task_done.Signal(); + }))); + + RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_run); +} + +// Verify that `RunOrPostTask` from another thread does not run the task +// synchronously if there is a running task blocked in a nested loop. +TEST_F(SequenceManagerRunOrPostTaskTest, + FromOtherThreadWithRunningTaskInNestedLoop) { + WaitableEvent main_thread_task_running; + RunLoop nested_run_loop(RunLoop::Type::kNestableTasksAllowed); + auto nested_run_loop_quit_closure = nested_run_loop.QuitClosure(); + task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() { + main_thread_task_running.Signal(); + nested_run_loop.Run(); + })); + + thread_local bool is_main_thread = false; + is_main_thread = true; + + EXPECT_TRUE(other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_FALSE(is_main_thread); + main_thread_task_running.Wait(); + // Wait to increase chances of posting while the main thread task is in + // a nested `RunLoop`. + PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { + // Should not run synchronously on the other thread. + EXPECT_TRUE(is_main_thread); + std::move(nested_run_loop_quit_closure).Run(); + }))); + }))); + + RunLoop().RunUntilIdle(); + FlushOtherThread(); +} + +// Verify that `RunOrPostTask` from another thread does not run the task +// synchronously if there is a running task in a different queue from the same +// `SequenceManager`. +TEST_F(SequenceManagerRunOrPostTaskTest, + FromOtherThreadWithRunningTaskOtherQueue) { + WaitableEvent main_thread_task_running; + WaitableEvent run_or_post_task_done; + other_task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() { + main_thread_task_running.Signal(); + run_or_post_task_done.Wait(); + })); + + bool did_run = false; + EXPECT_TRUE(other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + main_thread_task_running.Wait(); + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_run = true; }))); + EXPECT_FALSE(did_run); + run_or_post_task_done.Signal(); + }))); + + RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_run); +} + +// Verify that a task run synchronously inside `RunOrPostTask` prevents another +// task from starting on the bound thread. +TEST_F(SequenceManagerRunOrPostTaskTest, + MainThreadCantStartTaskDuringRunOrPostTask) { + SimulateInsideRunLoop(); + WaitableEvent sync_task_started; + bool sync_task_done = true; + + EXPECT_TRUE(other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { + sync_task_started.Signal(); + // Wait to increase chances that the main thread will attempt to + // schedule its task. + PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + sync_task_done = true; + }))); + EXPECT_TRUE(sync_task_done); + }))); + + sync_task_started.Wait(); + RunLoop run_loop; + task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() { + // Must deterministically run after the sync task. + EXPECT_TRUE(sync_task_done); + run_loop.Quit(); + })); + run_loop.Run(); + FlushOtherThread(); +} + +// Verify that when `RunOrPostTask` is called concurrently from multiple +// threads, only one can execute its task synchronously. +TEST_F(SequenceManagerRunOrPostTaskTest, ConcurrentCalls) { + SimulateInsideRunLoop(); + + WaitableEvent did_start_task_1; + WaitableEvent did_post_task_2; + + EXPECT_TRUE(other_thread_task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { + did_start_task_1.Signal(); + did_post_task_2.Wait(); + }))); + }))); + + Thread other_thread_2{"OtherThread2"}; + other_thread_2.Start(); + + bool did_complete_task_2 = false; + EXPECT_TRUE(other_thread_2.task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + did_start_task_1.Wait(); + EXPECT_TRUE(task_runner()->RunOrPostTask( + subtle::RunOrPostTaskPassKeyForTesting(), FROM_HERE, + BindLambdaForTesting([&]() { did_complete_task_2 = true; }))); + EXPECT_FALSE(did_complete_task_2); + did_post_task_2.Signal(); + }))); + + FlushOtherThread(); + EXPECT_FALSE(did_complete_task_2); + RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_complete_task_2); +} + TEST( SequenceManagerTest, CanAccessSingleThreadTaskRunnerCurrentDefaultHandleHandleDuringSequenceLocalStorageSlotDestruction) {
diff --git a/base/task/sequence_manager/sequenced_task_source.h b/base/task/sequence_manager/sequenced_task_source.h index 22f535b..7aca158 100644 --- a/base/task/sequence_manager/sequenced_task_source.h +++ b/base/task/sequence_manager/sequenced_task_source.h
@@ -51,6 +51,15 @@ virtual ~SequencedTaskSource() = default; + // Controls whether a `SequencedTaskRunner` associated with this source can + // run a task synchronously in `RunOrPostTask`. Enable this to indicate that + // there isn't any pending or running work that has mutual exclusion or + // ordering expectations with tasks from this source, outside of + // `SelectNextTask()` or `OnBeginWork()` -> `OnIdle()` (those prevent tasks + // from running synchronously, irrespective of the state set here). + virtual void SetRunTaskSynchronouslyAllowed( + bool can_run_tasks_synchronously) = 0; + // Returns the next task to run from this source or nullopt if // there're no more tasks ready to run. If a task is returned, // DidRunTask() must be invoked before the next call to SelectNextTask(). @@ -75,6 +84,10 @@ // high resolution timing. virtual bool HasPendingHighResolutionTasks() = 0; + // Indicates that work that has mutual exclusion expectations with tasks from + // this `SequencedTaskSource` will start running. + virtual void OnBeginWork() = 0; + // Called when we have run out of immediate work. If more immediate work // becomes available as a result of any processing done by this callback, // return true to schedule a future DoWork.
diff --git a/base/task/sequence_manager/task_queue_impl.cc b/base/task/sequence_manager/task_queue_impl.cc index 4ecc604..6e888b49 100644 --- a/base/task/sequence_manager/task_queue_impl.cc +++ b/base/task/sequence_manager/task_queue_impl.cc
@@ -93,6 +93,24 @@ return DelayedTaskHandle(std::move(delayed_task_handle_delegate)); } +bool TaskQueueImpl::GuardedTaskPoster::RunOrPostTask(PostedTask task) { + auto token = operations_controller_.TryBeginOperation(); + if (!token) { + return false; + } + + auto sync_work_auth = + outer_->sequence_manager_->TryAcquireSyncWorkAuthorization(); + // The queue may be disabled immediately after checking + // `IsQueueEnabledFromAnyThread()`. That won't prevent the task from running. + if (sync_work_auth.IsValid() && outer_->IsQueueEnabledFromAnyThread()) { + std::move(task.callback).Run(); + return true; + } + + return PostTask(std::move(task)); +} + TaskQueueImpl::TaskRunner::TaskRunner( scoped_refptr<GuardedTaskPoster> task_poster, scoped_refptr<const AssociatedThreadId> associated_thread, @@ -152,6 +170,14 @@ task_type_)); } +bool TaskQueueImpl::TaskRunner::RunOrPostTask(subtle::RunOrPostTaskPassKey, + const Location& location, + OnceClosure callback) { + return task_poster_->RunOrPostTask( + PostedTask(this, std::move(callback), location, TimeDelta(), + Nestable::kNestable, task_type_)); +} + bool TaskQueueImpl::TaskRunner::RunsTasksInCurrentSequence() const { return associated_thread_->IsBoundToCurrentThread(); } @@ -399,6 +425,7 @@ // addition it may need to schedule a DoWork if this queue isn't blocked. if (was_immediate_incoming_queue_empty && any_thread_.immediate_work_queue_empty) { + sequence_manager_->WillRequestReloadImmediateWorkQueue(); empty_queues_to_reload_handle_.SetActive(true); should_schedule_work = any_thread_.post_immediate_task_should_schedule_work; @@ -1079,7 +1106,7 @@ UpdateCrossThreadQueueStateLocked(); // Copy over the task-reporting related state. - any_thread_.tracing_only.is_enabled = enabled; + any_thread_.is_enabled = enabled; any_thread_.tracing_only.disabled_time = main_thread_only().disabled_time; any_thread_.tracing_only.should_report_posted_tasks_when_disabled = main_thread_only().should_report_posted_tasks_when_disabled; @@ -1125,6 +1152,7 @@ void TaskQueueImpl::UpdateCrossThreadQueueStateLocked() { any_thread_.immediate_work_queue_empty = main_thread_only().immediate_work_queue->Empty(); + any_thread_.is_enabled = main_thread_only().is_enabled; if (main_thread_only().throttler) { // If there's a Throttler, always ScheduleWork() when immediate work is @@ -1378,7 +1406,7 @@ if (!any_thread_.tracing_only.disabled_time) return false; - if (any_thread_.tracing_only.is_enabled || + if (any_thread_.is_enabled || any_thread_.tracing_only.should_report_posted_tasks_when_disabled) { return false; } @@ -1517,6 +1545,11 @@ return sequence_manager()->settings().priority_settings.default_priority(); } +bool TaskQueueImpl::IsQueueEnabledFromAnyThread() const { + base::internal::CheckedAutoLock lock(any_thread_lock_); + return any_thread_.is_enabled; +} + TaskQueueImpl::DelayedIncomingQueue::DelayedIncomingQueue() = default; TaskQueueImpl::DelayedIncomingQueue::~DelayedIncomingQueue() = default;
diff --git a/base/task/sequence_manager/task_queue_impl.h b/base/task/sequence_manager/task_queue_impl.h index ad91189..abd306a 100644 --- a/base/task/sequence_manager/task_queue_impl.h +++ b/base/task/sequence_manager/task_queue_impl.h
@@ -33,6 +33,7 @@ #include "base/task/sequence_manager/lazily_deallocated_deque.h" #include "base/task/sequence_manager/sequenced_task_source.h" #include "base/task/sequence_manager/task_queue.h" +#include "base/task/sequence_manager/tasks.h" #include "base/threading/thread_checker.h" #include "base/time/time_override.h" #include "base/trace_event/base_tracing_forward.h" @@ -291,6 +292,7 @@ bool PostTask(PostedTask task); DelayedTaskHandle PostCancelableTask(PostedTask task); + bool RunOrPostTask(PostedTask task); void StartAcceptingOperations() { operations_controller_.StartAcceptingOperations(); @@ -342,6 +344,9 @@ bool PostNonNestableDelayedTask(const Location& location, OnceClosure callback, TimeDelta delay) final; + bool RunOrPostTask(subtle::RunOrPostTaskPassKey, + const Location& from_here, + OnceClosure task) final; bool RunsTasksInCurrentSequence() const final; private: @@ -539,6 +544,9 @@ main_thread_only().voter_count; } + // Returns whether the queue is enabled. May be invoked from any thread. + bool IsQueueEnabledFromAnyThread() const; + QueueName name_; const raw_ptr<SequenceManagerImpl, AcrossTasksDanglingUntriaged> sequence_manager_; @@ -555,7 +563,6 @@ TracingOnly(); ~TracingOnly(); - bool is_enabled = true; absl::optional<TimeTicks> disabled_time; bool should_report_posted_tasks_when_disabled = false; }; @@ -565,12 +572,10 @@ TaskDeque immediate_incoming_queue; - // True if main_thread_only().immediate_work_queue is empty. bool immediate_work_queue_empty = true; - bool post_immediate_task_should_schedule_work = true; - bool unregistered = false; + bool is_enabled = true; base::flat_map<raw_ptr<OnTaskPostedCallbackHandleImpl>, OnTaskPostedHandler> on_task_posted_handlers;
diff --git a/base/task/sequence_manager/task_queue_selector.cc b/base/task/sequence_manager/task_queue_selector.cc index 2a7fee1..0e364db 100644 --- a/base/task/sequence_manager/task_queue_selector.cc +++ b/base/task/sequence_manager/task_queue_selector.cc
@@ -144,9 +144,13 @@ // There is now a delayed or an immediate task for |set_index|, so add to // |active_priority_tracker_|. if (non_empty_set_counts_[set_index] == 1) { + bool had_active_priority = active_priority_tracker_.HasActivePriority(); TaskQueue::QueuePriority priority = static_cast<TaskQueue::QueuePriority>(set_index); active_priority_tracker_.SetActive(priority, true); + if (!had_active_priority && task_queue_selector_observer_) { + task_queue_selector_observer_->OnWorkAvailable(); + } } }
diff --git a/base/task/sequence_manager/task_queue_selector.h b/base/task/sequence_manager/task_queue_selector.h index 50176a0..0bcc9af3 100644 --- a/base/task/sequence_manager/task_queue_selector.h +++ b/base/task/sequence_manager/task_queue_selector.h
@@ -77,6 +77,9 @@ // Called when |queue| transitions from disabled to enabled. virtual void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) = 0; + + // Called when work becomes available. + virtual void OnWorkAvailable() = 0; }; // Called once to set the Observer. This function is called
diff --git a/base/task/sequence_manager/task_queue_selector_unittest.cc b/base/task/sequence_manager/task_queue_selector_unittest.cc index 5a6e42a7..5fc46f9 100644 --- a/base/task/sequence_manager/task_queue_selector_unittest.cc +++ b/base/task/sequence_manager/task_queue_selector_unittest.cc
@@ -53,6 +53,7 @@ ~MockObserver() override = default; MOCK_METHOD1(OnTaskQueueEnabled, void(internal::TaskQueueImpl*)); + MOCK_METHOD0(OnWorkAvailable, void()); }; class TaskQueueSelectorForTest : public TaskQueueSelector { @@ -198,11 +199,18 @@ ElementsAre(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)); } +TEST_F(TaskQueueSelectorTest, TestObserverWorkAvailableOnPushTask) { + testing::StrictMock<MockObserver> mock_observer; + selector_.SetTaskQueueSelectorObserver(&mock_observer); + EXPECT_CALL(mock_observer, OnWorkAvailable()); + PushTask(/* queue_index=*/0, /* enqueue_order=*/4); +} + TEST_F(TaskQueueSelectorTest, TestObserverWithEnabledQueue) { task_queues_[1]->SetQueueEnabled(false); selector_.DisableQueue(task_queues_[1].get()); { - MockObserver mock_observer; + testing::StrictMock<MockObserver> mock_observer; selector_.SetTaskQueueSelectorObserver(&mock_observer); EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(1); task_queues_[1]->SetQueueEnabled(true); @@ -217,7 +225,7 @@ TestObserverWithSetQueuePriorityAndQueueAlreadyEnabled) { selector_.SetQueuePriority(task_queues_[1].get(), kHighPriority); { - MockObserver mock_observer; + testing::StrictMock<MockObserver> mock_observer; selector_.SetTaskQueueSelectorObserver(&mock_observer); EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(0); selector_.SetQueuePriority(task_queues_[1].get(), kDefaultPriority); @@ -228,11 +236,16 @@ } TEST_F(TaskQueueSelectorTest, TestDisableEnable) { - MockObserver mock_observer; + testing::StrictMock<MockObserver> mock_observer; selector_.SetTaskQueueSelectorObserver(&mock_observer); - size_t queue_order[] = {0, 1, 2, 3, 4}; - PushTasks(queue_order, 5); + { + // Work is available when a task is pushed to an enabled queue (all queues + // were previously empty). + EXPECT_CALL(mock_observer, OnWorkAvailable()); + PushTasks(queue_order, 5); + testing::Mock::VerifyAndClearExpectations(&mock_observer); + } task_queues_[2]->SetQueueEnabled(false); selector_.DisableQueue(task_queues_[2].get()); task_queues_[4]->SetQueueEnabled(false); @@ -241,14 +254,26 @@ EXPECT_EQ(kDefaultPriority, task_queues_[2]->GetQueuePriority()); EXPECT_EQ(kDefaultPriority, task_queues_[4]->GetQueuePriority()); EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(0, 1, 3)); - - EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(2); task_queues_[2]->SetQueueEnabled(true); - selector_.EnableQueue(task_queues_[2].get()); + { + EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)); + // Work is available when a non-empty queue is enabled (all queues were + // previously disabled). + EXPECT_CALL(mock_observer, OnWorkAvailable()); + selector_.EnableQueue(task_queues_[2].get()); + testing::Mock::VerifyAndClearExpectations(&mock_observer); + } selector_.SetQueuePriority(task_queues_[2].get(), kPriorityCount - 1); EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(2)); task_queues_[4]->SetQueueEnabled(true); - selector_.EnableQueue(task_queues_[4].get()); + { + EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)); + // Work is available when a non-empty queue is enabled (all queues were + // previously disabled). + EXPECT_CALL(mock_observer, OnWorkAvailable()); + selector_.EnableQueue(task_queues_[4].get()); + testing::Mock::VerifyAndClearExpectations(&mock_observer); + } EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(4)); // Clear observer before it goes out of scope. @@ -470,12 +495,10 @@ } TEST_F(TaskQueueSelectorTest, TestObserverWithOneBlockedQueue) { - MockObserver mock_observer; // Must outlive `selector` + testing::StrictMock<MockObserver> mock_observer; // Must outlive `selector` TaskQueueSelectorForTest selector(associated_thread_); selector.SetTaskQueueSelectorObserver(&mock_observer); - EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(1); - std::unique_ptr<TaskQueueImpl> task_queue(NewTaskQueueWithBlockReporting()); selector.AddQueue(task_queue.get(), kDefaultPriority); @@ -489,13 +512,18 @@ EXPECT_EQ(nullptr, selector.SelectWorkQueueToService()); task_queue->SetQueueEnabled(true); - selector.EnableQueue(task_queue.get()); + { + EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)); + EXPECT_CALL(mock_observer, OnWorkAvailable()); + selector.EnableQueue(task_queue.get()); + testing::Mock::VerifyAndClearExpectations(&mock_observer); + } selector.RemoveQueue(task_queue.get()); task_queue->UnregisterTaskQueue(); } TEST_F(TaskQueueSelectorTest, TestObserverWithTwoBlockedQueues) { - MockObserver mock_observer; // Must outlive `selector` + testing::StrictMock<MockObserver> mock_observer; // Must outlive `selector` TaskQueueSelectorForTest selector(associated_thread_); selector.SetTaskQueueSelectorObserver(&mock_observer); @@ -520,19 +548,26 @@ task_queue->immediate_work_queue()->Push(std::move(task1)); task_queue2->immediate_work_queue()->Push(std::move(task2)); EXPECT_EQ(nullptr, selector.SelectWorkQueueToService()); - testing::Mock::VerifyAndClearExpectations(&mock_observer); - EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(2); - - task_queue->SetQueueEnabled(true); - selector.EnableQueue(task_queue.get()); + { + EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)); + EXPECT_CALL(mock_observer, OnWorkAvailable()); + task_queue->SetQueueEnabled(true); + selector.EnableQueue(task_queue.get()); + testing::Mock::VerifyAndClearExpectations(&mock_observer); + } selector.RemoveQueue(task_queue.get()); task_queue->UnregisterTaskQueue(); EXPECT_EQ(nullptr, selector.SelectWorkQueueToService()); - task_queue2->SetQueueEnabled(true); - selector.EnableQueue(task_queue2.get()); + { + EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)); + EXPECT_CALL(mock_observer, OnWorkAvailable()); + task_queue2->SetQueueEnabled(true); + selector.EnableQueue(task_queue2.get()); + testing::Mock::VerifyAndClearExpectations(&mock_observer); + } selector.RemoveQueue(task_queue2.get()); task_queue2->UnregisterTaskQueue(); }
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc index 58456dd..094d1ac3 100644 --- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc +++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
@@ -288,6 +288,7 @@ hang_watch_scope_.emplace(); work_id_provider_->IncrementWorkId(); run_level_tracker_.OnWorkStarted(lazy_now); + main_thread_only().task_source->OnBeginWork(); } void ThreadControllerWithMessagePumpImpl::OnEndWorkItem(int run_level_depth) { @@ -611,6 +612,11 @@ TimeDelta timeout) { DCHECK(RunsTasksInCurrentSequence()); + // Inside a `RunLoop`, all work that has mutual exclusion or ordering + // expectations with the task source is tracked, so it's safe to allow running + // tasks synchronously in `RunOrPostTask()`. + main_thread_only().task_source->SetRunTaskSynchronouslyAllowed(true); + LazyNow lazy_now_run_loop_start(time_source_); // RunLoops can be nested so we need to restore the previous value of @@ -651,6 +657,13 @@ hang_watch_scope_.reset(); } work_id_provider_->IncrementWorkId(); + + // Work outside of a `RunLoop` may have mutual exclusion or ordering + // guarantees with the task source, so disallow running tasks synchronously in + // `RunOrPostTask()`. + if (run_level_tracker_.num_run_levels() == 0) { + main_thread_only().task_source->SetRunTaskSynchronouslyAllowed(false); + } } void ThreadControllerWithMessagePumpImpl::OnBeginNestedRunLoop() {
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc index 529a3c5..8b90fbf 100644 --- a/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc +++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc
@@ -122,6 +122,9 @@ explicit FakeSequencedTaskSource(TickClock* clock) : clock_(clock) {} ~FakeSequencedTaskSource() override = default; + void SetRunTaskSynchronouslyAllowed( + bool can_run_tasks_synchronously) override {} + absl::optional<SelectedTask> SelectNextTask( LazyNow& lazy_now, SelectTaskOption option) override { @@ -177,6 +180,8 @@ return has_pending_high_resolution_tasks; } + void OnBeginWork() override {} + void SetHasPendingHighResolutionTasks(bool state) { has_pending_high_resolution_tasks = state; }
diff --git a/base/task/sequence_manager/work_queue_sets.cc b/base/task/sequence_manager/work_queue_sets.cc index 564baf17..803bb6b 100644 --- a/base/task/sequence_manager/work_queue_sets.cc +++ b/base/task/sequence_manager/work_queue_sets.cc
@@ -68,10 +68,14 @@ work_queue_heaps_[old_set].erase(work_queue->heap_handle()); bool was_empty = work_queue_heaps_[set_index].empty(); work_queue_heaps_[set_index].insert({*key, work_queue}); - if (work_queue_heaps_[old_set].empty()) - observer_->WorkQueueSetBecameEmpty(old_set); + // Invoke `WorkQueueSetBecameNonEmpty()` before `WorkQueueSetBecameEmpty()` so + // `observer_` doesn't momentarily observe that all work queue sets are empty. + // TaskQueueSelectorTest.TestDisableEnable will fail if the order changes. if (was_empty) observer_->WorkQueueSetBecameNonEmpty(set_index); + if (work_queue_heaps_[old_set].empty()) { + observer_->WorkQueueSetBecameEmpty(old_set); + } } void WorkQueueSets::OnQueuesFrontTaskChanged(WorkQueue* work_queue) {
diff --git a/base/task/sequence_manager/work_tracker.cc b/base/task/sequence_manager/work_tracker.cc new file mode 100644 index 0000000..b7660f9 --- /dev/null +++ b/base/task/sequence_manager/work_tracker.cc
@@ -0,0 +1,137 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/task/sequence_manager/work_tracker.h" + +#include "base/check.h" +#include "base/threading/thread_restrictions.h" + +namespace base::sequence_manager::internal { + +SyncWorkAuthorization::SyncWorkAuthorization(SyncWorkAuthorization&& other) + : tracker_(other.tracker_) { + other.tracker_ = nullptr; +} + +SyncWorkAuthorization& SyncWorkAuthorization::operator=( + SyncWorkAuthorization&& other) { + tracker_ = other.tracker_; + other.tracker_ = nullptr; + return *this; +} + +SyncWorkAuthorization::~SyncWorkAuthorization() { + if (!tracker_) { + return; + } + + { + base::internal::CheckedAutoLock auto_lock(tracker_->active_sync_work_lock_); + uint32_t prev = tracker_->state_.fetch_and( + ~WorkTracker::kActiveSyncWork, WorkTracker::kMemoryReleaseAllowWork); + DCHECK(prev & WorkTracker::kActiveSyncWork); + } + + tracker_->active_sync_work_cv_->Signal(); +} + +SyncWorkAuthorization::SyncWorkAuthorization(WorkTracker* state) + : tracker_(state) {} + +WorkTracker::WorkTracker() { + DETACH_FROM_THREAD(thread_checker_); +} + +WorkTracker::~WorkTracker() = default; + +void WorkTracker::SetRunTaskSynchronouslyAllowed( + bool can_run_tasks_synchronously) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + if (can_run_tasks_synchronously) { + state_.fetch_or(kSyncWorkSupported, kMemoryReleaseAllowWork); + } else { + // After this returns, non-sync work may run without being tracked by + // `this`. Ensures that such work is correctly sequenced with sync work by: + // - Waiting until sync work is complete. + // - Acquiring memory written by sync work (`kMemoryAcquireBeforeWork` here + // is paired with `kMemoryReleaseAllowWork` in `~SyncWorkAuthorization`). + uint32_t prev = + state_.fetch_and(~kSyncWorkSupported, kMemoryAcquireBeforeWork); + if (prev & kActiveSyncWork) { + WaitNoSyncWork(); + } + } +} + +void WorkTracker::WaitNoSyncWork() { + // `std::memory_order_relaxed` instead of `kMemoryAcquireBeforeWork` because + // the lock implicitly acquires memory released by `~SyncWorkAuthorization`. + base::internal::CheckedAutoLock auto_lock(active_sync_work_lock_); + uint32_t prev = state_.load(std::memory_order_relaxed); + while (prev & kActiveSyncWork) { + active_sync_work_cv_->Wait(); + prev = state_.load(std::memory_order_relaxed); + } +} + +void WorkTracker::WillRequestReloadImmediateWorkQueue() { + // May be called from any thread. + + // Sync work is disallowed until `WillReloadImmediateWorkQueues()` and + // `OnIdle()` are called. + state_.fetch_or(kImmediateWorkQueueNeedsReload, + kMemoryRelaxedNotAllowOrBeforeWork); +} + +void WorkTracker::WillReloadImmediateWorkQueues() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // Sync work is disallowed until `OnIdle()` is called. + state_.fetch_and( + ~(kImmediateWorkQueueNeedsReload | kWorkQueuesEmptyAndNoWorkRunning), + kMemoryRelaxedNotAllowOrBeforeWork); +} + +void WorkTracker::OnBeginWork() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + uint32_t prev = state_.fetch_and(~kWorkQueuesEmptyAndNoWorkRunning, + kMemoryAcquireBeforeWork); + if (prev & kActiveSyncWork) { + DCHECK(prev & kSyncWorkSupported); + WaitNoSyncWork(); + } +} + +void WorkTracker::OnIdle() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // This may allow sync work. "release" so that sync work that runs after this + // sees all writes issued by previous sequenced work. + state_.fetch_or(kWorkQueuesEmptyAndNoWorkRunning, std::memory_order_release); +} + +SyncWorkAuthorization WorkTracker::TryAcquireSyncWorkAuthorization() { + // May be called from any thread. + + uint32_t state = state_.load(std::memory_order_relaxed); + // "acquire" so that sync work sees writes issued by sequenced work that + // precedes it. + if (state == (kSyncWorkSupported | kWorkQueuesEmptyAndNoWorkRunning) && + state_.compare_exchange_strong(state, state | kActiveSyncWork, + std::memory_order_acquire, + std::memory_order_relaxed)) { + return SyncWorkAuthorization(this); + } + + return SyncWorkAuthorization(nullptr); +} + +void WorkTracker::AssertHasWork() { + CHECK(!(state_.load(std::memory_order_relaxed) & + kWorkQueuesEmptyAndNoWorkRunning)); +} + +} // namespace base::sequence_manager::internal
diff --git a/base/task/sequence_manager/work_tracker.h b/base/task/sequence_manager/work_tracker.h new file mode 100644 index 0000000..31ef6227 --- /dev/null +++ b/base/task/sequence_manager/work_tracker.h
@@ -0,0 +1,134 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_TASK_SEQUENCE_MANAGER_WORK_TRACKER_H_ +#define BASE_TASK_SEQUENCE_MANAGER_WORK_TRACKER_H_ + +#include <atomic> +#include <cstdint> +#include <memory> + +#include "base/base_export.h" +#include "base/memory/raw_ptr.h" +#include "base/synchronization/condition_variable.h" +#include "base/task/common/checked_lock.h" +#include "base/threading/thread_checker.h" + +namespace base::sequence_manager::internal { + +class WorkTracker; + +// When `IsValid()`, this represents an authorization to execute work +// synchronously inside `RunOrPostTask`. +class BASE_EXPORT SyncWorkAuthorization { + public: + SyncWorkAuthorization(SyncWorkAuthorization&&); + SyncWorkAuthorization& operator=(SyncWorkAuthorization&&); + ~SyncWorkAuthorization(); + + bool IsValid() const { return !!tracker_; } + + private: + friend class WorkTracker; + + explicit SyncWorkAuthorization(WorkTracker* state); + + raw_ptr<WorkTracker> tracker_ = nullptr; +}; + +// Tracks queued and running work to support `RunOrPostTask`. +class BASE_EXPORT WorkTracker { + public: + WorkTracker(); + ~WorkTracker(); + + // Controls whether `RunOrPostTask()` can run its callback synchronously when + // no work is tracked by this. Don't allow this when work that is sequenced + // with `RunOrPostTask()` may run without being tracked by methods below. + void SetRunTaskSynchronouslyAllowed(bool can_run_tasks_synchronously); + + // Invoked before requesting to reload an empty immediate work queue. After + // this, `RunOrPostTask()` can't run tasks synchronously until + // `WillReloadImmediateWorkQueues()` and `OnIdle()` have been called in + // sequence. + void WillRequestReloadImmediateWorkQueue(); + + // Invoked before reloading empty immediate work queues. + void WillReloadImmediateWorkQueues(); + + // Invoked before doing work. After this `RunOrPostTask()` can't run tasks + // until `OnIdle()` is called. Work may begin even if immediate work queues + // haven't be reloaded since the last `OnIdle()`, e.g. when a task queue is + // enabled, when tasks are moved from the delayed incoming queue to the + // delayed work queue or when the pump performs internal work. + void OnBeginWork(); + + // Invoked when the thread is out of work. + void OnIdle(); + + // Returns a valid `SyncWorkAuthorization` iff all these conditions are true: + // - Explicitly allowed by `SetRunTaskSynchronouslyAllowed()` + // - `WillReloadImmediateWorkQueues()` and `OnIdle()` were called in + // sequence after the last call to `WillRequestReloadImmediateWorkQueue()` + // - `OnIdle()` was called after the last call to `OnBeginWork()` + SyncWorkAuthorization TryAcquireSyncWorkAuthorization(); + + // Asserts that there is work tracked by this, i.e. + // `TryAcquireSyncWorkAuthorization()` would not grant a sync work + // authorization even if allowed by `SetRunTaskSynchronouslyAllowed()`. + void AssertHasWork(); + + private: + friend class SyncWorkAuthorization; + + void WaitNoSyncWork(); + + // An atomic variable to track: + // - Whether there is an unfulfilled request to reload immediate work queues. + static constexpr uint32_t kImmediateWorkQueueNeedsReload = 1 << 0; + // - Whether all work queues are empty and no work is running. + static constexpr uint32_t kWorkQueuesEmptyAndNoWorkRunning = 1 << 1; + // - Whether a valid `SyncWorkAuthorization` exists. + static constexpr uint32_t kActiveSyncWork = 1 << 2; + // - Whether a valid `SyncWorkAuthorization` can be granted when no work is + // tracked by `this`. + static constexpr uint32_t kSyncWorkSupported = 1 << 3; + std::atomic_uint32_t state_{kWorkQueuesEmptyAndNoWorkRunning}; + + // Memory order for `state_`: + // + // Sync work must see all memory written before it was allowed. Similarly, + // non-sync work must see all memory written by sync work. As a result: + // + // Operations that may allow sync work are std::memory_order_release: + // - Set `kWorkQueuesEmptyAndNoWorkRunning` + // - Set `kSyncWorkSupported` + // + // Operations that may allow non-sync work are `std::memory_order_release`: + // - Clear `kActiveSyncWork` + // + // Operations that precede sync work are `std::memory_order_acquire`: + // - Set `kActiveSyncWork` + // + // Operations that precede non-sync work are `std::memory_order_acquire`: + // - Check that `kActiveSyncWork` is not set. + static constexpr std::memory_order kMemoryReleaseAllowWork = + std::memory_order_release; + static constexpr std::memory_order kMemoryAcquireBeforeWork = + std::memory_order_acquire; + static constexpr std::memory_order kMemoryRelaxedNotAllowOrBeforeWork = + std::memory_order_relaxed; + + // Allows `OnBeginWork()` to wait until there is no more valid + // `SyncWorkAuthorization`. + base::internal::CheckedLock active_sync_work_lock_; + std::unique_ptr<ConditionVariable> active_sync_work_cv_ = + active_sync_work_lock_.CreateConditionVariable(); + + THREAD_CHECKER(thread_checker_); +}; + +} // namespace base::sequence_manager::internal + +#endif // BASE_TASK_SEQUENCE_MANAGER_WORK_TRACKER_H_
diff --git a/base/task/sequence_manager/work_tracker_unittest.cc b/base/task/sequence_manager/work_tracker_unittest.cc new file mode 100644 index 0000000..cc8ce41 --- /dev/null +++ b/base/task/sequence_manager/work_tracker_unittest.cc
@@ -0,0 +1,153 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/task/sequence_manager/work_tracker.h" + +#include "base/test/bind.h" +#include "base/test/test_timeouts.h" +#include "base/threading/platform_thread.h" +#include "base/threading/thread.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace base::sequence_manager::internal { + +// Verify that no sync work authorization is granted unless allowed by +// `SetRunTaskSynchronouslyAllowed()`. +TEST(SequenceManagerWorkTrackerTest, SetRunTaskSynchronouslyAllowed) { + WorkTracker tracker; + EXPECT_FALSE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); + + tracker.OnBeginWork(); + tracker.OnIdle(); + EXPECT_FALSE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); + + tracker.WillRequestReloadImmediateWorkQueue(); + tracker.WillReloadImmediateWorkQueues(); + tracker.OnIdle(); + EXPECT_FALSE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); + + tracker.SetRunTaskSynchronouslyAllowed(true); + EXPECT_TRUE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); + tracker.SetRunTaskSynchronouslyAllowed(false); + EXPECT_FALSE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); +} + +// Verify that `SetRunTaskSynchronouslyAllowed(false)` blocks until there is no +// valid sync work authorization. +TEST(SequenceManagerWorkTrackerTest, SetRunTaskSynchronouslyAllowedBlocks) { + WorkTracker tracker; + tracker.SetRunTaskSynchronouslyAllowed(true); + + WaitableEvent did_acquire_sync_work_auth; + bool will_release_sync_work_auth = false; + Thread other_thread("OtherThread"); + other_thread.Start(); + other_thread.task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + absl::optional<SyncWorkAuthorization> auth = + tracker.TryAcquireSyncWorkAuthorization(); + EXPECT_TRUE(auth->IsValid()); + did_acquire_sync_work_auth.Signal(); + PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + will_release_sync_work_auth = true; + auth.reset(); + })); + + did_acquire_sync_work_auth.Wait(); + + tracker.SetRunTaskSynchronouslyAllowed(false); + // `will_release_sync_work_auth` must be true (with no data race detected by + // TSAN) when the call above returns. + EXPECT_TRUE(will_release_sync_work_auth); + + other_thread.FlushForTesting(); +} + +// Verify that after `WillRequestReloadImmediateWorkQueue()`, +// `WillReloadImmediateWorkQueues()` and `OnIdle()` must be called in sequence +// for a sync work authorization to be granted. +TEST(SequenceManagerWorkTrackerTest, WillRequestReloadImmediateWorkQueue) { + WorkTracker tracker; + tracker.SetRunTaskSynchronouslyAllowed(true); + EXPECT_TRUE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); + + tracker.WillRequestReloadImmediateWorkQueue(); + EXPECT_FALSE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); + tracker.WillReloadImmediateWorkQueues(); + EXPECT_FALSE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); + tracker.OnIdle(); + EXPECT_TRUE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); + + tracker.WillRequestReloadImmediateWorkQueue(); + EXPECT_FALSE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); + // `OnIdle()` without `WillReloadImmediateWorkQueues()` is not sufficient for + // a sync work authorization to be granted. + tracker.OnIdle(); + EXPECT_FALSE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); +} + +// Verify that after `OnBeginWork()`, `OnIdle()` must be called for a sync +// work authorization to be granted. +TEST(SequenceManagerWorkTrackerTest, OnBeginWork) { + WorkTracker tracker; + tracker.SetRunTaskSynchronouslyAllowed(true); + EXPECT_TRUE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); + + tracker.OnBeginWork(); + EXPECT_FALSE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); + tracker.OnIdle(); + EXPECT_TRUE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); +} + +// Verify that its not possible to simultaneously acquire two sync work +// authorizations. +TEST(SequenceManagerWorkTrackerTest, TwoSyncWorkAuthorizations) { + WorkTracker tracker; + tracker.SetRunTaskSynchronouslyAllowed(true); + + absl::optional<SyncWorkAuthorization> first = + tracker.TryAcquireSyncWorkAuthorization(); + EXPECT_TRUE(first->IsValid()); + SyncWorkAuthorization second = tracker.TryAcquireSyncWorkAuthorization(); + EXPECT_FALSE(second.IsValid()); + + first.reset(); + // `second` is invalid so doesn't prevent acquiring another sync work + // authorization. + EXPECT_TRUE(tracker.TryAcquireSyncWorkAuthorization().IsValid()); +} + +// Verify that `OnBeginWork()` blocks until there is no valid sync work +// authorization. +TEST(SequenceManagerWorkTrackerTest, OnBeginWorkBlocks) { + WorkTracker tracker; + tracker.SetRunTaskSynchronouslyAllowed(true); + + WaitableEvent did_acquire_sync_work_auth; + bool will_release_sync_work_auth = false; + Thread other_thread("OtherThread"); + other_thread.Start(); + other_thread.task_runner()->PostTask( + FROM_HERE, BindLambdaForTesting([&]() { + absl::optional<SyncWorkAuthorization> auth = + tracker.TryAcquireSyncWorkAuthorization(); + EXPECT_TRUE(auth->IsValid()); + did_acquire_sync_work_auth.Signal(); + PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + will_release_sync_work_auth = true; + auth.reset(); + })); + + did_acquire_sync_work_auth.Wait(); + + tracker.OnBeginWork(); + // `will_release_sync_work_auth` must be true (with no data race detected by + // TSAN) when the call above returns. + EXPECT_TRUE(will_release_sync_work_auth); + + other_thread.FlushForTesting(); +} + +} // namespace base::sequence_manager::internal
diff --git a/base/task/sequenced_task_runner.cc b/base/task/sequenced_task_runner.cc index 67cf5d1..572b1e8 100644 --- a/base/task/sequenced_task_runner.cc +++ b/base/task/sequenced_task_runner.cc
@@ -77,6 +77,12 @@ : delayed_run_time - TimeTicks::Now()); } +bool SequencedTaskRunner::RunOrPostTask(subtle::RunOrPostTaskPassKey, + const Location& from_here, + OnceClosure task) { + return PostTask(from_here, std::move(task)); +} + // static const scoped_refptr<SequencedTaskRunner>& SequencedTaskRunner::GetCurrentDefault() {
diff --git a/base/task/sequenced_task_runner.h b/base/task/sequenced_task_runner.h index c19f24a..964ef67 100644 --- a/base/task/sequenced_task_runner.h +++ b/base/task/sequenced_task_runner.h
@@ -44,8 +44,7 @@ namespace subtle { -// Used to restrict access to PostCancelableDelayedTaskAt() to authorize -// callers. +// Restricts access to PostCancelableDelayedTask*() to authorized callers. class PostDelayedTaskPassKey { private: // Avoid =default to disallow creation by uniform initialization. @@ -66,7 +65,17 @@ friend class media::FakeAudioWorker; }; +// Restricts access to RunOrPostTask() to authorized callers. +class RunOrPostTaskPassKey { + private: + // Avoid =default to disallow creation by uniform initialization. + RunOrPostTaskPassKey() {} + + friend class RunOrPostTaskPassKeyForTesting; +}; + class PostDelayedTaskPassKeyForTesting : public PostDelayedTaskPassKey {}; +class RunOrPostTaskPassKeyForTesting : public RunOrPostTaskPassKey {}; } // namespace subtle @@ -219,6 +228,19 @@ TimeTicks delayed_run_time, subtle::DelayPolicy delay_policy); + // May run `task` synchronously if no work that has ordering or mutual + // exclusion expectations with tasks from this `SequencedTaskRunner` is + // pending or running (if such work arrives after `task` starts running + // synchronously, it waits until `task` finishes). Otherwise, behaves like + // `PostTask`. Since `task` may run synchronously, it is generally not + // appropriate to invoke this if `task` may take a long time to run. + // + // TODO(crbug.com/1503967): This API is still in development. It doesn't yet + // support SEQUENCE_CHECKER or SequenceLocalStorage. + virtual bool RunOrPostTask(subtle::RunOrPostTaskPassKey, + const Location& from_here, + OnceClosure task); + // Submits a non-nestable task to delete the given object. Returns // true if the object may be deleted at some point in the future, // and false if the object definitely will not be deleted.
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index 67f0ff1..71631ec 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h
@@ -145,6 +145,9 @@ class Environment; class File; class FilePath; +namespace sequence_manager::internal { +class WorkTracker; +} // namespace sequence_manager::internal } // namespace base bool EnsureBrowserStateDirectoriesCreated(const base::FilePath&, @@ -810,6 +813,7 @@ friend class base::StackSamplingProfiler; friend class base::internal::JobTaskSource; friend class base::sequence_manager::internal::TaskQueueImpl; + friend class base::sequence_manager::internal::WorkTracker; friend class base::win::ObjectWatcher; friend class blink::AudioDestination; friend class blink::RTCVideoDecoderAdapter;
diff --git a/base/trace_event/trace_arguments.h b/base/trace_event/trace_arguments.h index 5d000e8..e2790c3 100644 --- a/base/trace_event/trace_arguments.h +++ b/base/trace_event/trace_arguments.h
@@ -267,13 +267,6 @@ private: void Append(unsigned char type, bool as_json, std::string* out) const; - // InnerType<T>::type removes reference, cv-qualifications and decays - // function and arrays into pointers. Only used internally. - template <typename T> - struct InnerType { - using type = std::decay_t<T>; - }; - public: // TraceValue::Helper is used to provide information about initialization // value types and an initialization function. It is a struct that should @@ -285,7 +278,7 @@ // TraceValue value from a given T value. Second parameter type // can also be const T& or T&& to restrict uses. // - // IMPORTANT: The type T must be InnerType<Q>, where Q is the real C++ + // IMPORTANT: The type T must be std::decay_t<Q>, where Q is the real C++ // argument type. I.e. you should not have to deal with reference types // in your specialization. // @@ -316,21 +309,8 @@ struct Helper {}; template <typename T> - struct HasHelperSupport { - private: - using Yes = char[1]; - using No = char[2]; - - template <typename V> - static Yes& check_support( - decltype(TraceValue::Helper<typename InnerType<V>::type>::kType, - int())); - template <typename V> - static No& check_support(...); - - public: - static constexpr bool value = sizeof(Yes) == sizeof(check_support<T>(0)); - }; + static constexpr bool HasHelperSupport = + requires { TraceValue::Helper<std::decay_t<T>>::kType; }; // TraceValue::TypeFor<T>::value returns the TRACE_VALUE_TYPE_XXX // corresponding to initialization values of type T. @@ -338,18 +318,15 @@ struct TypeFor; template <typename T> - struct TypeFor< - T, - std::enable_if_t<HasHelperSupport<typename InnerType<T>::type>::value>> { - using ValueType = typename InnerType<T>::type; + struct TypeFor<T, std::enable_if_t<HasHelperSupport<T>>> { + using ValueType = std::decay_t<T>; static const unsigned char value = Helper<ValueType>::kType; }; template <typename T> - struct TypeFor< - T, - std::enable_if_t<!HasHelperSupport<typename InnerType<T>::type>::value && - perfetto::internal::has_traced_value_support< - typename InnerType<T>::type>::value>> { + struct TypeFor<T, + std::enable_if_t<!HasHelperSupport<T> && + perfetto::internal::has_traced_value_support< + std::decay_t<T>>::value>> { static const unsigned char value = TRACE_VALUE_TYPE_PROTO; }; @@ -357,11 +334,11 @@ // initialize a TraceValue instance. This is useful to restrict template // instantiation to only the appropriate type (see TraceArguments // constructors below). - template <typename T, - class = std::enable_if_t< - HasHelperSupport<typename InnerType<T>::type>::value || - perfetto::internal::has_traced_value_support< - typename InnerType<T>::type>::value>> + template < + typename T, + class = std::enable_if_t< + HasHelperSupport<T> || + perfetto::internal::has_traced_value_support<std::decay_t<T>>::value>> struct TypeCheck { static const bool value = true; }; @@ -380,16 +357,15 @@ // // NOTE: For ConvertableToTraceFormat values, see the notes above. template <class T> - std::enable_if_t<HasHelperSupport<typename InnerType<T>::type>::value> Init( - T&& value) { - using ValueType = typename InnerType<T>::type; + std::enable_if_t<HasHelperSupport<T>> Init(T&& value) { + using ValueType = std::decay_t<T>; Helper<ValueType>::SetValue(this, std::forward<T>(value)); } template <class T> - std::enable_if_t<!HasHelperSupport<typename InnerType<T>::type>::value && - perfetto::internal::has_traced_value_support< - typename InnerType<T>::type>::value> + std::enable_if_t< + !HasHelperSupport<T> && + perfetto::internal::has_traced_value_support<std::decay_t<T>>::value> Init(T&& value) { as_proto = new protozero::HeapBuffered< perfetto::protos::pbzero::DebugAnnotation>();
diff --git a/chrome/VERSION b/chrome/VERSION index c29092c0..2e810774 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=122 MINOR=0 -BUILD=6195 +BUILD=6196 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 8850a15..316fd19 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -391,6 +391,7 @@ "//chrome/browser/profiles/android:java", "//chrome/browser/quick_delete:java", "//chrome/browser/readaloud/android:java", + "//chrome/browser/readaloud/android:metrics_java", "//chrome/browser/recent_tabs:factory_java", "//chrome/browser/recent_tabs:helper_java", "//chrome/browser/recent_tabs:java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java index fa61ea77..b34cf88 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java
@@ -12,7 +12,6 @@ import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.SnackbarActivity; import org.chromium.chrome.browser.back_press.BackPressHelper; -import org.chromium.chrome.browser.back_press.BackPressManager; import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.bookmarks.BookmarkManagerCoordinator; import org.chromium.chrome.browser.bookmarks.BookmarkPage; @@ -53,19 +52,11 @@ if (TextUtils.isEmpty(url)) url = UrlConstants.BOOKMARKS_URL; mBookmarkManagerCoordinator.updateForUrl(url); setContentView(mBookmarkManagerCoordinator.getView()); - if (BackPressManager.isSecondaryActivityEnabled()) { - BackPressHelper.create( - this, - getOnBackPressedDispatcher(), - mBookmarkManagerCoordinator, - SecondaryActivity.BOOKMARK); - } else { - BackPressHelper.create( - this, - getOnBackPressedDispatcher(), - mBookmarkManagerCoordinator::onBackPressed, - SecondaryActivity.BOOKMARK); - } + BackPressHelper.create( + this, + getOnBackPressedDispatcher(), + mBookmarkManagerCoordinator, + SecondaryActivity.BOOKMARK); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java index 39eda2c..42c86e7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkFolderPickerActivity.java
@@ -15,7 +15,6 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.SynchronousInitializationActivity; import org.chromium.chrome.browser.back_press.BackPressHelper; -import org.chromium.chrome.browser.back_press.BackPressManager; import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.bookmarks.BookmarkAddNewFolderCoordinator; import org.chromium.chrome.browser.bookmarks.BookmarkFolderPickerCoordinator; @@ -107,19 +106,11 @@ shoppingService), shoppingService); - if (BackPressManager.isSecondaryActivityEnabled()) { - BackPressHelper.create( - this, - getOnBackPressedDispatcher(), - mCoordinator, - SecondaryActivity.BOOKMARK_FOLDER_PICKER); - } else { - BackPressHelper.create( - this, - getOnBackPressedDispatcher(), - mCoordinator::onBackPressed, - SecondaryActivity.BOOKMARK_FOLDER_PICKER); - } + BackPressHelper.create( + this, + getOnBackPressedDispatcher(), + mCoordinator, + SecondaryActivity.BOOKMARK_FOLDER_PICKER); Toolbar toolbar = mCoordinator.getToolbar(); setSupportActionBar(toolbar);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/download/home/DownloadActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/download/home/DownloadActivity.java index a0b4a91..0f65add 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/download/home/DownloadActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/download/home/DownloadActivity.java
@@ -9,7 +9,6 @@ import org.chromium.chrome.browser.SnackbarActivity; import org.chromium.chrome.browser.back_press.BackPressHelper; -import org.chromium.chrome.browser.back_press.BackPressManager; import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.download.DownloadUtils; import org.chromium.chrome.browser.download.home.DownloadManagerCoordinator; @@ -82,19 +81,11 @@ setContentView(mDownloadCoordinator.getView()); if (!showPrefetchContent) mDownloadCoordinator.updateForUrl(mCurrentUrl); mDownloadCoordinator.addObserver(mUiObserver); - if (BackPressManager.isSecondaryActivityEnabled()) { - BackPressHelper.create( - this, - getOnBackPressedDispatcher(), - mDownloadCoordinator.getBackPressHandlers(), - SecondaryActivity.DOWNLOAD); - } else { - BackPressHelper.create( - this, - getOnBackPressedDispatcher(), - mDownloadCoordinator::onBackPressed, - SecondaryActivity.DOWNLOAD); - } + BackPressHelper.create( + this, + getOnBackPressedDispatcher(), + mDownloadCoordinator.getBackPressHandlers(), + SecondaryActivity.DOWNLOAD); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java index bfb6e81..8b73b25 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java
@@ -352,15 +352,6 @@ mMediator.updateForUrl(url); } - /** - * Called when the user presses the back key. This is only going to be called on Phone. - * - * @return True if manager handles this event, false if it decides to ignore. - */ - public boolean onBackPressed() { - return mMediator.onBackPressed(); - } - /** Opens the given BookmarkId. */ public void openBookmark(BookmarkId bookmarkId) { mMediator.openBookmark(bookmarkId); @@ -403,6 +394,14 @@ } // Private methods. + /** + * Called when the user presses the back key. This is only going to be called on Phone. + * + * @return True if manager handles this event, false if it decides to ignore. + */ + private boolean onBackPressed() { + return mMediator.onBackPressed(); + } private int computeCacheMaxSize() { ActivityManager activityManager =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index e87f7da1..2aaea5a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -359,18 +359,9 @@ imageGroup.add(createListItem(Item.SAVE_IMAGE)); } - // If set, show 'Share Image' before 'Search with Google Lens'. - // IMPORTANT: Must stay consistent with logic after the below Lens block. - boolean addedShareImageAboveLens = false; - if (LensUtils.orderShareImageBeforeLens() && enableShareFromContextMenu()) { - addedShareImageAboveLens = true; - imageGroup.add(createShareListItem(Item.SHARE_IMAGE, Item.DIRECT_SHARE_IMAGE)); - } - if (mMode == ContextMenuMode.CUSTOM_TAB || mMode == ContextMenuMode.NORMAL) { if (checkSupportsGoogleSearchByImage(isSrcDownloadableScheme)) { - // All behavior relating to Lens integration is gated by Feature Flag. - // A map to indicate which image search menu item would be shown. + // Determine which image search menu item would be shown. boolean shouldShowSearchImageWithLens = shouldShowSearchWithLensAndRecordMetrics( mParams.getPageUrl(), mItemDelegate.isIncognito()); @@ -381,17 +372,14 @@ imageGroup.add(createListItem(Item.SEARCH_BY_IMAGE)); maybeRecordUkmSearchByImageShown(); } - } else if (ChromeFeatureList.isEnabled( - ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS)) { + } else { LensMetrics.recordLensSupportStatus( LENS_SUPPORT_STATUS_HISTOGRAM_NAME, LensMetrics.LensSupportStatus.SEARCH_BY_IMAGE_UNAVAILABLE); } } - // By default show 'Share Image' after 'Search with Google Lens'. - // IMPORTANT: Must stay consistent with logic before the above Lens block. - if (!addedShareImageAboveLens && enableShareFromContextMenu()) { + if (enableShareFromContextMenu()) { imageGroup.add(createShareListItem(Item.SHARE_IMAGE, Item.DIRECT_SHARE_IMAGE)); } @@ -819,9 +807,6 @@ return (Integer result) -> { int chipType = result.intValue(); switch (chipType) { - case ChipRenderParams.ChipType.LENS_SHOPPING_CHIP: - recordContextMenuSelection(ContextMenuUma.Action.SHOP_WITH_GOOGLE_LENS_CHIP); - return; case ChipRenderParams.ChipType.LENS_TRANSLATE_CHIP: recordContextMenuSelection( ContextMenuUma.Action.TRANSLATE_WITH_GOOGLE_LENS_CHIP); @@ -867,13 +852,6 @@ return false; } - if (isTabletScreen() && !LensUtils.isGoogleLensFeatureEnabledOnTablet()) { - LensMetrics.recordLensSupportStatus( - LENS_SUPPORT_STATUS_HISTOGRAM_NAME, - LensMetrics.LensSupportStatus.DISABLED_ON_TABLET); - return false; - } - final TemplateUrlService templateUrlServiceInstance = getTemplateUrlService(); String versionName = LensUtils.getLensActivityVersionNameIfAvailable(mContext); if (!templateUrlServiceInstance.isDefaultSearchEngineGoogle()) { @@ -967,22 +945,12 @@ /** If not disabled record a UKM for opening the context menu with the lens item. */ private void maybeRecordUkmLensShown() { - if (LensUtils.shouldLogUkmByFeature( - ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS)) { - maybeRecordBooleanUkm("ContextMenuAndroid.Shown", "SearchWithGoogleLens"); - } + maybeRecordBooleanUkm("ContextMenuAndroid.Shown", "SearchWithGoogleLens"); } private void maybeRecordUkmLensChipShown(int chipType) { String actionName = null; switch (chipType) { - case ChipRenderParams.ChipType.LENS_SHOPPING_CHIP: - if (!LensUtils.shouldLogUkmByFeature( - ChromeFeatureList.CONTEXT_MENU_GOOGLE_LENS_CHIP)) { - return; - } - actionName = "ShopWithGoogleLensChip"; - break; case ChipRenderParams.ChipType.LENS_TRANSLATE_CHIP: if (!LensUtils.shouldLogUkmByFeature( ChromeFeatureList.CONTEXT_MENU_TRANSLATE_WITH_GOOGLE_LENS)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivityBase.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivityBase.java index ef30174..47295704 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivityBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivityBase.java
@@ -25,7 +25,6 @@ import org.chromium.base.supplier.OneshotSupplier; import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.chrome.browser.back_press.BackPressHelper; -import org.chromium.chrome.browser.back_press.BackPressManager; import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.customtabs.CustomTabsConnection; import org.chromium.chrome.browser.init.ActivityProfileProvider; @@ -126,19 +125,7 @@ @Override protected void onPreCreate() { super.onPreCreate(); - if (BackPressManager.isSecondaryActivityEnabled()) { - BackPressHelper.create( - this, getOnBackPressedDispatcher(), this, getSecondaryActivity()); - } else { - BackPressHelper.create( - this, - getOnBackPressedDispatcher(), - () -> { - handleBackPress(); - return true; - }, - getSecondaryActivity()); - } + BackPressHelper.create(this, getOnBackPressedDispatcher(), this, getSecondaryActivity()); } // Activity:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java index f68f1b8..893178f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java
@@ -10,7 +10,6 @@ import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.SnackbarActivity; import org.chromium.chrome.browser.back_press.BackPressHelper; -import org.chromium.chrome.browser.back_press.BackPressManager; import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.history_clusters.HistoryClustersConstants; import org.chromium.chrome.browser.profiles.Profile; @@ -44,16 +43,8 @@ historyClustersQuery, new BrowsingHistoryBridge(profile)); setContentView(mHistoryManager.getView()); - if (BackPressManager.isSecondaryActivityEnabled()) { - BackPressHelper.create( - this, getOnBackPressedDispatcher(), mHistoryManager, SecondaryActivity.HISTORY); - } else { - BackPressHelper.create( - this, - getOnBackPressedDispatcher(), - mHistoryManager::onBackPressed, - SecondaryActivity.HISTORY); - } + BackPressHelper.create( + this, getOnBackPressedDispatcher(), mHistoryManager, SecondaryActivity.HISTORY); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java index dc852dc..48c980a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
@@ -752,21 +752,6 @@ } } - /** - * Called when the user presses the back key. This is only going to be called - * when the history UI is shown in a separate activity rather inside a tab. - * @return True if manager handles this event, false if it decides to ignore. - */ - public boolean onBackPressed() { - if (mIsIncognito || mSelectableListLayout == null) { - // If Incognito placeholder is shown, the back press should handled by HistoryActivity. - return false; - } else if (isHistoryClustersUIShowing()) { - return mHistoryClustersCoordinator.onBackPressed(); - } - return mSelectableListLayout.onBackPressed(); - } - // BackPressHandler implementation. @Override public @BackPressResult int handleBackPress() { @@ -817,6 +802,22 @@ } /** + * Called when the user presses the back key. This is only going to be called when the history + * UI is shown in a separate activity rather inside a tab. + * + * @return True if manager handles this event, false if it decides to ignore. + */ + private boolean onBackPressed() { + if (mIsIncognito || mSelectableListLayout == null) { + // If Incognito placeholder is shown, the back press should handled by HistoryActivity. + return false; + } else if (isHistoryClustersUIShowing()) { + return mHistoryClustersCoordinator.onBackPressed(); + } + return mSelectableListLayout.onBackPressed(); + } + + /** * @param action The user action string to record. */ static void recordUserAction(String action) {
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 97d49200..2c71fc6 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
@@ -186,7 +186,9 @@ protected NativePage buildNewTabPage(Tab tab, String url) { NativePageHost nativePageHost = new TabShim(tab, mBrowserControlsManager, mTabModelSelector); - if (tab.isIncognito()) return new IncognitoNewTabPage(mActivity, nativePageHost); + if (tab.isIncognito()) { + return new IncognitoNewTabPage(mActivity, nativePageHost, tab.getProfile()); + } return new NewTabPage( mActivity,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java index e5e1d0911..f1c5eacb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java
@@ -14,17 +14,22 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareThumbnailProvider; import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncherImpl; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.ntp.IncognitoNewTabPageView.IncognitoNewTabPageManager; +import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.ui.native_page.BasicNativePage; import org.chromium.chrome.browser.ui.native_page.NativePageHost; import org.chromium.components.content_settings.CookieControlsEnforcement; import org.chromium.components.embedder_support.util.UrlConstants; +import org.chromium.components.user_prefs.UserPrefs; /** Provides functionality when the user interacts with the Incognito NTP. */ public class IncognitoNewTabPage extends BasicNativePage implements InvalidationAwareThumbnailProvider { - private Activity mActivity; + private final Activity mActivity; + private final Profile mProfile; + private final int mIncognitoNtpBackgroundColor; private String mTitle; protected IncognitoNewTabPageView mIncognitoNewTabPageView; @@ -35,13 +40,8 @@ private IncognitoCookieControlsManager mCookieControlsManager; private IncognitoCookieControlsManager.Observer mCookieControlsObserver; - private final int mIncognitoNtpBackgroundColor; - private void showIncognitoLearnMore() { - Profile profile = - Profile.getLastUsedRegularProfile() - .getPrimaryOTRProfile(/* createIfNeeded= */ true); - HelpAndFeedbackLauncherImpl.getForProfile(profile) + HelpAndFeedbackLauncherImpl.getForProfile(mProfile) .show( mActivity, mActivity.getString(R.string.help_context_incognito_learn_more), @@ -50,12 +50,19 @@ /** * Constructs an Incognito NewTabPage. + * * @param activity The activity used to create the new tab page's View. + * @param profile The profile associated with this incognito NTP. */ - public IncognitoNewTabPage(Activity activity, NativePageHost host) { + public IncognitoNewTabPage(Activity activity, NativePageHost host, Profile profile) { super(host); mActivity = activity; + mProfile = profile; + if (!mProfile.isOffTheRecord()) { + throw new IllegalStateException( + "Attempting to create an incognito NTP with a normal profile."); + } mIncognitoNtpBackgroundColor = host.getContext().getColor(R.color.ntp_bg_incognito); @@ -97,6 +104,19 @@ } @Override + public boolean shouldShowRevampedIncognitoNtp() { + return ChromeFeatureList.isEnabled(ChromeFeatureList.INCOGNITO_NTP_REVAMP); + } + + @Override + public boolean shouldShowTrackingProtectionNtp() { + return UserPrefs.get(mProfile) + .getBoolean(Pref.TRACKING_PROTECTION3PCD_ENABLED) + || ChromeFeatureList.isEnabled( + ChromeFeatureList.TRACKING_PROTECTION_3PCD); + } + + @Override public void destroy() { if (mCookieControlsManager != null) { mCookieControlsManager.removeObserver(mCookieControlsObserver);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageView.java index ef0c402..8a587f5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageView.java
@@ -13,11 +13,7 @@ import android.widget.FrameLayout; import org.chromium.chrome.R; -import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.preferences.Pref; -import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.content_settings.CookieControlsEnforcement; -import org.chromium.components.user_prefs.UserPrefs; import org.chromium.ui.base.ViewUtils; /** The New Tab Page for use in the incognito profile. */ @@ -38,17 +34,19 @@ /** * Initializes the cookie controls manager for interaction with the cookie controls toggle. - * */ + */ void initCookieControlsManager(); - /** - * Tells the caller whether a new snapshot is required or not. - * */ + /** Tells the caller whether a new snapshot is required or not. */ boolean shouldCaptureThumbnail(); - /** - * Cleans up the manager after it is finished being used. - * */ + /** Whether the new version of the Incognito NTP should be shown. */ + boolean shouldShowRevampedIncognitoNtp(); + + /** Whether to show the tracking protection UI on the NTP. */ + boolean shouldShowTrackingProtectionNtp(); + + /** Cleans up the manager after it is finished being used. */ void destroy(); /** @@ -75,9 +73,11 @@ // FOCUS_BEFORE_DESCENDANTS is needed to support keyboard shortcuts. Otherwise, pressing // any shortcut causes the UrlBar to be focused. See ViewRootImpl.leaveTouchMode(). mScrollView.setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS); + } + private void inflateConditionalLayouts() { ViewStub viewStub = findViewById(R.id.incognito_description_layout_stub); - if (shouldShowRevampedIncognitoNtp()) { + if (mManager.shouldShowRevampedIncognitoNtp()) { viewStub.setLayoutResource(R.layout.revamped_incognito_description_layout); } else { viewStub.setLayoutResource(R.layout.incognito_description_layout); @@ -95,14 +95,14 @@ // Inflate the correct cookie/tracking protection card. ViewStub cardStub = findViewById(R.id.cookie_card_stub); if (cardStub == null) return; - if (shouldShowTrackingProtectionNtp()) { + if (mManager.shouldShowTrackingProtectionNtp()) { cardStub.setLayoutResource( - shouldShowRevampedIncognitoNtp() + mManager.shouldShowRevampedIncognitoNtp() ? R.layout.revamped_incognito_tracking_protection_card : R.layout.incognito_tracking_protection_card); } else { cardStub.setLayoutResource( - shouldShowRevampedIncognitoNtp() + mManager.shouldShowRevampedIncognitoNtp() ? R.layout.revamped_incognito_cookie_controls_card : R.layout.incognito_cookie_controls_card); } @@ -126,6 +126,7 @@ */ void initialize(IncognitoNewTabPageManager manager) { mManager = manager; + inflateConditionalLayouts(); mManager.initCookieControlsManager(); } @@ -147,18 +148,6 @@ || mScrollView.getScrollY() != mSnapshotScrollY; } - boolean shouldShowRevampedIncognitoNtp() { - return ChromeFeatureList.isEnabled(ChromeFeatureList.INCOGNITO_NTP_REVAMP); - } - - boolean shouldShowTrackingProtectionNtp() { - Profile profile = - Profile.getLastUsedRegularProfile() - .getPrimaryOTRProfile(/* createIfNeeded= */ true); - return (UserPrefs.get(profile).getBoolean(Pref.TRACKING_PROTECTION3PCD_ENABLED) - || ChromeFeatureList.isEnabled(ChromeFeatureList.TRACKING_PROTECTION_3PCD)); - } - /** * @see org.chromium.chrome.browser.compositor.layouts.content. * InvalidationAwareThumbnailProvider#captureThumbnail(Canvas)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java index 9d09586..c4abd50a8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
@@ -43,7 +43,6 @@ import org.chromium.chrome.browser.autofill.options.AutofillOptionsFragment; import org.chromium.chrome.browser.autofill.settings.AutofillCreditCardEditor; import org.chromium.chrome.browser.back_press.BackPressHelper; -import org.chromium.chrome.browser.back_press.BackPressManager; import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.browsing_data.ClearBrowsingDataFragmentBasic; import org.chromium.chrome.browser.feedback.FragmentHelpAndFeedbackLauncher; @@ -468,19 +467,11 @@ private void registerMainFragmentBackPressHandler() { Fragment activeFragment = getMainFragment(); - if (BackPressManager.isSecondaryActivityEnabled()) { - if (activeFragment instanceof BackPressHandler) { - BackPressHelper.create( - activeFragment.getViewLifecycleOwner(), - getOnBackPressedDispatcher(), - (BackPressHandler) activeFragment, - SecondaryActivity.SETTINGS); - } - } else if (activeFragment instanceof BackPressHelper.ObsoleteBackPressedHandler) { + if (activeFragment instanceof BackPressHandler) { BackPressHelper.create( activeFragment.getViewLifecycleOwner(), getOnBackPressedDispatcher(), - (BackPressHelper.ObsoleteBackPressedHandler) activeFragment, + (BackPressHandler) activeFragment, SecondaryActivity.SETTINGS); } } @@ -491,19 +482,11 @@ BackPressHandler bottomSheetBackPressHandler = mBottomSheetController.getBottomSheetBackPressHandler(); if (bottomSheetBackPressHandler != null) { - if (BackPressManager.isSecondaryActivityEnabled()) { - BackPressHelper.create( - this, - getOnBackPressedDispatcher(), - bottomSheetBackPressHandler, - SecondaryActivity.SETTINGS); - } else { - BackPressHelper.create( - this, - getOnBackPressedDispatcher(), - mBottomSheetController::handleBackPress, - SecondaryActivity.SETTINGS); - } + BackPressHelper.create( + this, + getOnBackPressedDispatcher(), + bottomSheetBackPressHandler, + SecondaryActivity.SETTINGS); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/LensUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/share/LensUtils.java index 55f548a24..28710fc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/LensUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/LensUtils.java
@@ -6,7 +6,6 @@ import android.content.Context; import android.os.Build; -import android.text.TextUtils; import org.chromium.base.ResettersForTesting; import org.chromium.chrome.browser.IntentHandler; @@ -74,20 +73,7 @@ * @return The minimum version name string or an empty string if not available. */ public static String getMinimumAgsaVersionForLensSupport() { - if (ChromeFeatureList.isEnabled(ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS)) { - final String serverProvidedMinAgsaVersion = - ChromeFeatureList.getFieldTrialParamByFeature( - ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, - MIN_AGSA_VERSION_FEATURE_PARAM_NAME); - if (TextUtils.isEmpty(serverProvidedMinAgsaVersion)) { - // Falls into this block if the user enabled the feature using chrome://flags - // and the param was not set by the server. - return MIN_AGSA_VERSION_NAME_FOR_LENS_POSTCAPTURE; - } - return serverProvidedMinAgsaVersion; - } - // The feature is disabled so no need to return a minimum version. - return ""; + return MIN_AGSA_VERSION_NAME_FOR_LENS_POSTCAPTURE; } /** @@ -120,37 +106,11 @@ } public static boolean isGoogleLensFeatureEnabled(boolean isIncognito) { - return ChromeFeatureList.isEnabled(ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS) - && !(isIncognito - && ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( - ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, - DISABLE_ON_INCOGNITO_PARAM_NAME, - true)); - } - - public static boolean isGoogleLensFeatureEnabledOnTablet() { - return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( - ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, - ENABLE_ON_TABLET_PARAM_NAME, - true); - } - - /** - * Adjust chip ordering slightly. The image chip feature changes the context menu height - * which can result in the final image menu items being hidden in certain contexts. - * @return Whether to list 'Share Image' above 'Search with Google Lens'. - */ - public static boolean orderShareImageBeforeLens() { - return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( - ChromeFeatureList.CONTEXT_MENU_GOOGLE_LENS_CHIP, - ORDER_SHARE_IMAGE_BEFORE_LENS_PARAM_NAME, - false); + return !isIncognito; } public static boolean shouldLogUkmForLensContextMenuFeatures() { - return shouldLogUkmByFeature(ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS) - || shouldLogUkmByFeature(ChromeFeatureList.CONTEXT_MENU_GOOGLE_LENS_CHIP) - || shouldLogUkmByFeature(ChromeFeatureList.CONTEXT_MENU_TRANSLATE_WITH_GOOGLE_LENS); + return shouldLogUkmByFeature(ChromeFeatureList.CONTEXT_MENU_TRANSLATE_WITH_GOOGLE_LENS); } /*
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java index 52e5d94..1534da5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java
@@ -35,7 +35,6 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.SyncFirstSetupCompleteSource; -import org.chromium.chrome.browser.back_press.BackPressHelper; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.settings.ChromeBaseSettingsFragment; @@ -81,7 +80,6 @@ PassphraseTypeDialogFragment.Listener, Preference.OnPreferenceChangeListener, SyncService.SyncStateChangedListener, - BackPressHelper.ObsoleteBackPressedHandler, Listener, SyncErrorCardPreference.SyncErrorCardPreferenceListener { private static final String IS_FROM_SIGNIN_SCREEN = "ManageSyncSettings.isFromSigninScreen"; @@ -283,7 +281,7 @@ return true; } if (item.getItemId() == android.R.id.home) { - return onBackPressed(); + return onBackToHome(); } return false; } @@ -352,6 +350,14 @@ PostTask.postTask(TaskTraits.UI_DEFAULT, this::updateSyncPreferences); } + /** Handles when user clicks home button in menu to get back to home screen. */ + private boolean onBackToHome() { + if (mIsFromSigninScreen) { + RecordUserAction.record("Signin_Signin_BackOnAdvancedSyncSettings"); + } + return false; + } + /** * Gets the current state of data types from {@link SyncService} and updates UI elements * from this state. @@ -656,16 +662,6 @@ } } - @Override - public boolean onBackPressed() { - // TODO(crbug.com/1406012): Remove these metrics or introduce new metrics in other lifecycle - // hooks because this method never consumes back event. - if (mIsFromSigninScreen) { - RecordUserAction.record("Signin_Signin_BackOnAdvancedSyncSettings"); - } - return false; - } - // SyncErrorCardPreferenceListener implementation: @Override public boolean shouldSuppressSyncSetupIncomplete() {
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 73a7b7a9..86e5163 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
@@ -2535,8 +2535,7 @@ // While a hardware keyboard is connected, loading the NTP should cause the URL bar to gain // focus with a blinking cursor and without focus animations. Loading a non-NTP URL should // clear such focus if it exists. - if (mActivity.getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY - && ChromeFeatureList.isEnabled(ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT)) { + if (mActivity.getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY) { if (onNtp) { mLocationBar.showUrlBarCursorWithoutFocusAnimations(); } else { @@ -2548,7 +2547,6 @@ private void maybeShowUrlBarCursorIfHardwareKeyboardAvailable() { if (!DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity)) return; if (!UrlUtilities.isNtpUrl(mLocationBarModel.getCurrentGurl())) return; - if (!ChromeFeatureList.isEnabled(ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT)) return; if (mActivity.getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY) { mLocationBar.showUrlBarCursorWithoutFocusAnimations();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java index 711f68b..57d09630 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
@@ -42,7 +42,6 @@ import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator; import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator.ContextMenuMode; import org.chromium.chrome.browser.firstrun.FirstRunStatus; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.lens.LensEntryPoint; import org.chromium.chrome.browser.lens.LensIntentParams; import org.chromium.chrome.browser.share.ShareDelegate; @@ -103,8 +102,6 @@ FeatureList.setTestCanUseDefaultsForTesting(); HashMap<String, Boolean> features = new HashMap<String, Boolean>(); - features.put(ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, false); - FeatureList.setTestFeatures(features); TestThreadUtils.runOnUiThreadBlocking(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java index a8aac64..06457b44 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -46,7 +46,6 @@ import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; import org.chromium.chrome.browser.download.DownloadTestRule; @@ -79,7 +78,6 @@ import org.chromium.net.test.EmbeddedTestServer; import org.chromium.ui.base.Clipboard; import org.chromium.ui.base.MenuSourceType; -import org.chromium.ui.test.util.UiRestriction; import org.chromium.url.GURL; import java.io.IOException; @@ -417,28 +415,6 @@ @Test @MediumTest @Feature({"Browser"}) - @EnableFeatures({ChromeFeatureList.CONTEXT_MENU_GOOGLE_LENS_CHIP}) - @DisableFeatures({ContentFeatures.TOUCH_DRAG_AND_CONTEXT_MENU}) - public void testLensShoppingChipNotShowingIfNotEnabled() throws Throwable { - // Required to avoid runtime error. - Looper.prepare(); - - Tab tab = mDownloadTestRule.getActivity().getActivityTab(); - hardcodeTestImageForSharing(TEST_JPG_IMAGE_FILE_EXTENSION); - - ContextMenuCoordinator menuCoordinator = ContextMenuUtils.openContextMenu(tab, "testImage"); - // Needs to run on UI thread so creation happens on same thread as dismissal. - TestThreadUtils.runOnUiThreadBlocking( - () -> { - Assert.assertNull( - "Chip popoup was initialized.", - menuCoordinator.getCurrentPopupWindowForTesting()); - }); - } - - @Test - @MediumTest - @Feature({"Browser"}) @DisableFeatures({ContentFeatures.TOUCH_DRAG_AND_CONTEXT_MENU}) public void testSelectLensShoppingChip() throws Throwable { // Required to avoid runtime error. @@ -688,52 +664,7 @@ @Test @SmallTest @Feature({"Browser", "ContextMenu"}) - @DisableFeatures({ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS}) public void testContextMenuRetrievesImageOptions() throws TimeoutException { - Tab tab = mDownloadTestRule.getActivity().getActivityTab(); - ContextMenuCoordinator menu = ContextMenuUtils.openContextMenu(tab, "testImage"); - - Integer[] expectedItems = { - R.id.contextmenu_save_image, - R.id.contextmenu_open_image_in_new_tab, - R.id.contextmenu_search_by_image, - R.id.contextmenu_share_image, - R.id.contextmenu_copy_image - }; - Integer[] featureItems = {R.id.contextmenu_open_image_in_ephemeral_tab}; - expectedItems = - addItemsIf(EphemeralTabCoordinator.isSupported(), expectedItems, featureItems); - assertMenuItemsAreEqual(menu, expectedItems); - } - - @Test - @SmallTest - @Feature({"Browser", "ContextMenu"}) - @DisableFeatures({ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS}) - @EnableFeatures({ChromeFeatureList.CONTEXT_MENU_ENABLE_LENS_SHOPPING_ALLOWLIST}) - public void testContextMenuRetrievesImageOptionsWithLensShoppingAllowlist() - throws TimeoutException { - Tab tab = mDownloadTestRule.getActivity().getActivityTab(); - ContextMenuCoordinator menu = ContextMenuUtils.openContextMenu(tab, "testImage"); - - Integer[] expectedItems = { - R.id.contextmenu_save_image, - R.id.contextmenu_open_image_in_new_tab, - R.id.contextmenu_search_by_image, - R.id.contextmenu_share_image, - R.id.contextmenu_copy_image - }; - Integer[] featureItems = {R.id.contextmenu_open_image_in_ephemeral_tab}; - expectedItems = - addItemsIf(EphemeralTabCoordinator.isSupported(), expectedItems, featureItems); - assertMenuItemsAreEqual(menu, expectedItems); - } - - @Test - @SmallTest - @Feature({"Browser", "ContextMenu"}) - @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) - public void testContextMenuRetrievesImageOptionsLensEnabled() throws TimeoutException { LensUtils.setFakePassableLensEnvironmentForTesting(true); Tab tab = mDownloadTestRule.getActivity().getActivityTab(); @@ -804,38 +735,7 @@ @Test @SmallTest @Feature({"Browser", "ContextMenu"}) - @DisableFeatures({ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS}) public void testContextMenuRetrievesImageLinkOptions() throws TimeoutException { - Tab tab = mDownloadTestRule.getActivity().getActivityTab(); - ContextMenuCoordinator menu = ContextMenuUtils.openContextMenu(tab, "testImageLink"); - - Integer[] expectedItems = { - R.id.contextmenu_open_in_new_tab_in_group, - R.id.contextmenu_open_in_new_tab, - R.id.contextmenu_open_in_incognito_tab, - R.id.contextmenu_copy_link_address, - R.id.contextmenu_save_link_as, - R.id.contextmenu_save_image, - R.id.contextmenu_open_image_in_new_tab, - R.id.contextmenu_search_by_image, - R.id.contextmenu_share_image, - R.id.contextmenu_share_link, - R.id.contextmenu_copy_image - }; - Integer[] featureItems = { - R.id.contextmenu_open_in_ephemeral_tab, R.id.contextmenu_open_image_in_ephemeral_tab - }; - expectedItems = - addItemsIf(EphemeralTabCoordinator.isSupported(), expectedItems, featureItems); - assertMenuItemsAreEqual(menu, expectedItems); - } - - @Test - @SmallTest - @Feature({"Browser", "ContextMenu"}) - @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) - public void testContextMenuRetrievesImageLinkOptionsSearchLensEnabled() - throws TimeoutException { LensUtils.setFakePassableLensEnvironmentForTesting(true); Tab tab = mDownloadTestRule.getActivity().getActivityTab(); @@ -865,42 +765,6 @@ @Test @SmallTest @Feature({"Browser", "ContextMenu"}) - @CommandLineFlags.Add({ - "enable-features=" + ChromeFeatureList.CONTEXT_MENU_GOOGLE_LENS_CHIP + "<FakeStudyName", - "force-fieldtrials=FakeStudyName/Enabled", - "force-fieldtrial-params=FakeStudyName.Enabled:orderShareImageBeforeLens/true" - }) - @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) - public void testContextMenuShareImageStillAddedWhenReordered() throws TimeoutException { - LensUtils.setFakePassableLensEnvironmentForTesting(true); - - Tab tab = mDownloadTestRule.getActivity().getActivityTab(); - ContextMenuCoordinator menu = ContextMenuUtils.openContextMenu(tab, "testImageLink"); - - Integer[] expectedItems = { - R.id.contextmenu_open_in_new_tab_in_group, - R.id.contextmenu_open_in_new_tab, - R.id.contextmenu_open_in_incognito_tab, - R.id.contextmenu_copy_link_address, - R.id.contextmenu_save_link_as, - R.id.contextmenu_save_image, - R.id.contextmenu_open_image_in_new_tab, - R.id.contextmenu_share_image, - R.id.contextmenu_search_with_google_lens, - R.id.contextmenu_share_link, - R.id.contextmenu_copy_image - }; - Integer[] featureItems = { - R.id.contextmenu_open_in_ephemeral_tab, R.id.contextmenu_open_image_in_ephemeral_tab - }; - expectedItems = - addItemsIf(EphemeralTabCoordinator.isSupported(), expectedItems, featureItems); - assertMenuItemsAreEqual(menu, expectedItems); - } - - @Test - @SmallTest - @Feature({"Browser", "ContextMenu"}) public void testContextMenuRetrievesVideoOptions() throws TimeoutException { Tab tab = mDownloadTestRule.getActivity().getActivityTab(); DOMUtils.clickNode( @@ -914,8 +778,6 @@ @Test @SmallTest @Feature({"Browser", "ContextMenu"}) - @EnableFeatures({ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS}) - @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) public void testSearchImageWithGoogleLensMenuItemName() throws Throwable { Tab tab = mDownloadTestRule.getActivity().getActivityTab();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java index f2131b1a..ba80751a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java
@@ -771,7 +771,8 @@ 0, secondFreData.abortFirstRunExperienceCallback.getCallCount()); - secondFreActivity.onBackPressed(); + TestThreadUtils.runOnUiThreadBlocking( + secondFreActivity.getOnBackPressedDispatcher()::onBackPressed); secondFreData.abortFirstRunExperienceCallback.waitForCallback( "Second FirstRunActivity didn't abort", 0); CriteriaHelper.pollInstrumentationThread( @@ -1285,7 +1286,8 @@ protected FirstRunNavigationHelper goBackToPreviousPage() throws Exception { int jumpCallCount = mScopedObserverData.jumpToPageCallback.getCallCount(); - TestThreadUtils.runOnUiThreadBlocking(() -> mFirstRunActivity.onBackPressed()); + TestThreadUtils.runOnUiThreadBlocking( + mFirstRunActivity.getOnBackPressedDispatcher()::onBackPressed); mScopedObserverData.jumpToPageCallback.waitForCallback( "Failed go back to previous page", jumpCallCount);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java index b9abfb0..3395a4f8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java
@@ -12,11 +12,14 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText; import android.app.Dialog; +import android.view.Menu; +import android.view.MenuItem; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.PopupMenu; import androidx.fragment.app.FragmentTransaction; import androidx.preference.CheckBoxPreference; import androidx.preference.Preference; @@ -998,13 +1001,16 @@ @Test @SmallTest @Feature({"Sync"}) - public void testAdvancedSyncFlowFromSyncConsentBackPressDoesNotEnableUKM() throws Exception { + public void testAdvancedSyncFlowFromSyncConsentBackToHomeDoesNotEnableUKM() throws Exception { mSyncTestRule.setUpTestAccountAndSignInWithSyncSetupAsIncomplete(); final ManageSyncSettings fragment = startManageSyncPreferencesFromSyncConsentFlow(); TestThreadUtils.runOnUiThreadBlocking( () -> { - fragment.onBackPressed(); + PopupMenu p = new PopupMenu(mSettingsActivity, null); + Menu menu = p.getMenu(); + MenuItem menuItem = menu.add(0, android.R.id.home, 0, ""); + fragment.onOptionsItemSelected(menuItem); }); verifyUrlKeyedAnonymizedDataCollectionNotSet();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java index edfef36b..79713d72 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java
@@ -184,7 +184,6 @@ @Test @MediumTest - @EnableFeatures(ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT) @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET) public void testNtpOmniboxFocusAndUnfocusWithHardwareKeyboardConnected() { ChromeTabbedActivity activity = mActivityTestRule.getActivity(); @@ -221,7 +220,6 @@ @Test @MediumTest - @EnableFeatures(ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT) @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET) public void testMaybeShowUrlBarFocusIfHardwareKeyboardAvailable_newTabFromTabSwitcher() { ChromeTabbedActivity activity = mActivityTestRule.getActivity();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java b/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java index 6d14049..6f343394 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java
@@ -96,11 +96,7 @@ /** Tests the History UI. */ @RunWith(BaseRobolectricTestRunner.class) -@DisableFeatures({ - ChromeFeatureList.HISTORY_JOURNEYS, - ChromeFeatureList.RENAME_JOURNEYS, - ChromeFeatureList.BACK_GESTURE_REFACTOR_ACTIVITY, -}) +@DisableFeatures({ChromeFeatureList.HISTORY_JOURNEYS, ChromeFeatureList.RENAME_JOURNEYS}) public class HistoryUITest { private static final int PAGE_INCREMENT = 2; private static final String HISTORY_SEARCH_QUERY = "some page"; @@ -201,21 +197,11 @@ Assert.assertEquals(expectedItemCount, mAdapter.getItemCount()); - // Some individual tests may override to enable this feature which is disabled by - // the class by default. - if (ChromeFeatureList.isEnabled(ChromeFeatureList.BACK_GESTURE_REFACTOR_ACTIVITY)) { - BackPressHelper.create( - mLifecycleOwner, - mOnBackPressedDispatcher, - mHistoryManager, - SecondaryActivity.HISTORY); - } else { - BackPressHelper.create( - mLifecycleOwner, - mOnBackPressedDispatcher, - mHistoryManager::onBackPressed, - SecondaryActivity.HISTORY); - } + BackPressHelper.create( + mLifecycleOwner, + mOnBackPressedDispatcher, + mHistoryManager, + SecondaryActivity.HISTORY); } @Test @@ -458,7 +444,6 @@ @Test @SmallTest - @DisableFeatures(ChromeFeatureList.BACK_GESTURE_REFACTOR_ACTIVITY) public void testSearchViewDismissedByBackPress() { final HistoryManagerToolbar toolbar = mHistoryManager.getToolbarForTests(); View toolbarShadow = mHistoryManager.getSelectableListLayout().getToolbarShadowForTests(); @@ -498,13 +483,6 @@ @Test @SmallTest - @EnableFeatures(ChromeFeatureList.BACK_GESTURE_REFACTOR_ACTIVITY) - public void testSearchViewDismissedByBackPress_Refactored() { - testSearchViewDismissedByBackPress(); - } - - @Test - @SmallTest public void testToggleInfoMenuItem() { final HistoryManagerToolbar toolbar = mHistoryManager.getToolbarForTests(); final MenuItem infoMenuItem = toolbar.getItemById(R.id.info_menu_id);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/settings/SettingsActivityUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/settings/SettingsActivityUnitTest.java index 3cf32538..27ed36ce 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/settings/SettingsActivityUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/settings/SettingsActivityUnitTest.java
@@ -33,13 +33,11 @@ import org.chromium.base.ContextUtils; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.R; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.ProfileManagerUtils; import org.chromium.chrome.browser.settings.SettingsActivityUnitTest.ShadowProfileManagerUtils; import org.chromium.chrome.test.util.browser.Features; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.browser_ui.settings.CustomDividerFragment; import org.chromium.components.browser_ui.settings.PaddedItemDecorationWithDivider; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -91,7 +89,6 @@ } @Test - @EnableFeatures(ChromeFeatureList.BACK_GESTURE_REFACTOR_ACTIVITY) public void testBackPress() throws TimeoutException { launchSettingsActivity(TestSettingsFragment.class.getName()); assertTrue(
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/share/LensUtilsTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/share/LensUtilsTest.java index 732ad0e..9f1acdd 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/share/LensUtilsTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/share/LensUtilsTest.java
@@ -51,37 +51,16 @@ } @Test - public void isGoogleLensFeatureEnabled_incognitoParamUnsetIncognitoUser() { - configureFeature(ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS); + public void isGoogleLensFeatureEnabled_incognito() { Assert.assertFalse( - "Feature incorrectly enabled when incognito param is not set", + "Feature incorrectly enabled when incognito", LensUtils.isGoogleLensFeatureEnabled(true)); } @Test - public void isGoogleLensFeatureEnabled_incognitoEnabledIncognitoUser() { - configureFeature( - ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, "disableOnIncognito=false"); + public void isGoogleLensFeatureEnabled_standard() { Assert.assertTrue( - "Feature incorrectly disabled when incognito param is not set", - LensUtils.isGoogleLensFeatureEnabled(true)); - } - - @Test - public void isGoogleLensFeatureEnabled_incognitoDisabledIncognitoUser() { - configureFeature( - ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, "disableOnIncognito=true"); - Assert.assertFalse( - "Feature incorrectly not disabled when incognito param was set", - LensUtils.isGoogleLensFeatureEnabled(true)); - } - - @Test - public void isGoogleLensFeatureEnabled_incognitoDisabledStandardUser() { - configureFeature( - ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, "disableOnIncognito=true"); - Assert.assertTrue( - "Feature incorrectly disabled when user was not incognito", + "Feature incorrectly enabled when non-incognito", LensUtils.isGoogleLensFeatureEnabled(false)); } @@ -106,42 +85,4 @@ LensUtils.shouldLogUkmByFeature( ChromeFeatureList.CONTEXT_MENU_TRANSLATE_WITH_GOOGLE_LENS)); } - - @Test - public void shouldLogUkm_shoppingChipUkmLoggingEnabled() { - configureFeature( - ChromeFeatureList.CONTEXT_MENU_GOOGLE_LENS_CHIP, - "disableOnIncognito=true", - "logUkm=true"); - assertTrue( - LensUtils.shouldLogUkmByFeature(ChromeFeatureList.CONTEXT_MENU_GOOGLE_LENS_CHIP)); - } - - @Test - public void shouldLogUkm_shoppingChipUkmLoggingDisabled() { - configureFeature( - ChromeFeatureList.CONTEXT_MENU_GOOGLE_LENS_CHIP, - "disableOnIncognito=true", - "logUkm=false"); - assertFalse( - LensUtils.shouldLogUkmByFeature(ChromeFeatureList.CONTEXT_MENU_GOOGLE_LENS_CHIP)); - } - - @Test - public void isGoogleLensFeatureEnabled_tabletEnabledByDefault() { - configureFeature(ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS); - Assert.assertTrue( - "Feature incorrectly disabled when Lens on tablet was enabled", - LensUtils.isGoogleLensFeatureEnabledOnTablet()); - } - - @Test - public void isGoogleLensFeatureEnabled_tabletEnabled() { - configureFeature( - ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, - "enableContextMenuSearchOnTablet=true"); - Assert.assertTrue( - "Feature incorrectly disabled when Lens on tablet was enabled", - LensUtils.isGoogleLensFeatureEnabledOnTablet()); - } }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 1440992..b4da2225 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -2858,18 +2858,6 @@ desc="Tooltip label for the button to open full download history"> Show full download history in a new tab </message> - <message name="IDS_DOWNLOAD_BUBBLE_HEADER_TEXT" - desc="Header text in the Download Bubble"> - Recent Downloads - </message> - <message name="IDS_DOWNLOAD_BUBBLE_FOOTER_LINK" - desc="Footer link in the Download Bubble"> - Show all downloads - </message> - <message name="IDS_DOWNLOAD_BUBBLE_FOOTER_TOOLTIP" - desc="Tooltip label for the button to open all downloads"> - Show all downloads in a new tab - </message> <message name="IDS_DOWNLOAD_BUBBLE_ESB_PROMO" desc="Text for the in-product-help bubble shown for the esb promo download bubble."> Chrome just blocked a dangerous file from downloading. Get even stronger security with enhanced protection.
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_FOOTER_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_FOOTER_LINK.png.sha1 deleted file mode 100644 index 764314d..0000000 --- a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_FOOTER_LINK.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e087ca9409ee1b4d3dbf666240c8aae63bd6f0bd \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_FOOTER_TOOLTIP.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_FOOTER_TOOLTIP.png.sha1 deleted file mode 100644 index d1257afe..0000000 --- a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_FOOTER_TOOLTIP.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -c3cd5682d772637c4a87391ba07f9b4e0651ff78 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_HEADER_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_HEADER_TEXT.png.sha1 deleted file mode 100644 index 764314d..0000000 --- a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_HEADER_TEXT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e087ca9409ee1b4d3dbf666240c8aae63bd6f0bd \ No newline at end of file
diff --git a/chrome/app/settings_chromium_strings.grdp b/chrome/app/settings_chromium_strings.grdp index 460c69b..22c3fb546 100644 --- a/chrome/app/settings_chromium_strings.grdp +++ b/chrome/app/settings_chromium_strings.grdp
@@ -154,6 +154,9 @@ <message name="IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_RADIO_SUBLABEL" desc="A description of the benefit/cost of choosing 'Sites can save content on your device. In short, a site will remember your preferences, shopping cart content, etc. during this browser session. But once you close all open windows, and then visit the site again, it's as if you're coming to the site for the first time."> Sites will probably work as you expect but won't remember you after you close all Chromium windows </message> + <message name="IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_WITH_EXCEPTION_RADIO_SUBLABEL" desc="A description of the benefit/cost of choosing 'Sites can save content on your device. In short, a site will remember your preferences, shopping cart content, etc. during this browser session. But once you close all open windows, and then visit the site again, it's as if you're coming to the site for the first time."> + Sites will probably work as expected. You'll be signed out of most sites when you close all Chromium windows, except your Google Account if you're signed in to Chromium. + </message> <message name="IDS_SETTINGS_SITE_DATA_PAGE_DELETE_ON_EXIT_EXCEPTIONS_SUB_HEADING" desc="2 of 3. A label within 'Customized behaviors' that allows for exceptions to the 'On-device site data' setting. This label and the list of sites that can appear beneath it is only relevant if the user has chosen to allow 'on-device site data' as the default value above."> Always delete site data from your device when you close Chromium </message>
diff --git a/chrome/app/settings_chromium_strings_grdp/IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_WITH_EXCEPTION_RADIO_SUBLABEL.png.sha1 b/chrome/app/settings_chromium_strings_grdp/IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_WITH_EXCEPTION_RADIO_SUBLABEL.png.sha1 new file mode 100644 index 0000000..169b441 --- /dev/null +++ b/chrome/app/settings_chromium_strings_grdp/IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_WITH_EXCEPTION_RADIO_SUBLABEL.png.sha1
@@ -0,0 +1 @@ +6573c0c62663acb303f958f120dda05cd0f43da4 \ No newline at end of file
diff --git a/chrome/app/settings_google_chrome_strings.grdp b/chrome/app/settings_google_chrome_strings.grdp index 033e3cf..4bbea90 100644 --- a/chrome/app/settings_google_chrome_strings.grdp +++ b/chrome/app/settings_google_chrome_strings.grdp
@@ -147,6 +147,9 @@ <message name="IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_RADIO_SUBLABEL" desc="A description of the benefit/cost of choosing 'Sites can save content on your device. In short, a site will remember your preferences, shopping cart content, etc. during this browser session. But once you close all open windows, and then visit the site again, it's as if you're coming to the site for the first time."> Sites will probably work as you expect but won't remember you after you close all Chrome windows </message> + <message name="IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_WITH_EXCEPTION_RADIO_SUBLABEL" desc="A description of the benefit/cost of choosing 'Sites can save content on your device. In short, a site will remember your preferences, shopping cart content, etc. during this browser session. But once you close all open windows, and then visit the site again, it's as if you're coming to the site for the first time."> + Sites will probably work as expected. You'll be signed out of most sites when you close all Chrome windows, except your Google Account if you're signed in to Chrome. + </message> <message name="IDS_SETTINGS_SITE_DATA_PAGE_DELETE_ON_EXIT_EXCEPTIONS_SUB_HEADING" desc="2 of 3. A label within 'Customized behaviors' that allows for exceptions to the 'On-device site data' setting. This label and the list of sites that can appear beneath it is only relevant if the user has chosen to allow 'on-device site data' as the default value above."> Always delete site data from your device when you close Chrome </message>
diff --git a/chrome/app/settings_google_chrome_strings_grdp/IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_WITH_EXCEPTION_RADIO_SUBLABEL.png.sha1 b/chrome/app/settings_google_chrome_strings_grdp/IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_WITH_EXCEPTION_RADIO_SUBLABEL.png.sha1 new file mode 100644 index 0000000..d5c5147 --- /dev/null +++ b/chrome/app/settings_google_chrome_strings_grdp/IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_WITH_EXCEPTION_RADIO_SUBLABEL.png.sha1
@@ -0,0 +1 @@ +39973c0cb6b8f2b2e7aba324fa98e81552b06962 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index ea574b1..526fda27 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1095,9 +1095,6 @@ "performance_manager/mechanisms/page_freezer.h", "performance_manager/mechanisms/working_set_trimmer.cc", "performance_manager/mechanisms/working_set_trimmer.h", - "performance_manager/metrics/cpu_probe/cpu_probe.cc", - "performance_manager/metrics/cpu_probe/cpu_probe.h", - "performance_manager/metrics/cpu_probe/pressure_sample.h", "performance_manager/metrics/memory_pressure_metrics.cc", "performance_manager/metrics/memory_pressure_metrics.h", "performance_manager/metrics/metrics_provider_common.cc", @@ -1991,6 +1988,7 @@ "//components/session_proto_db:session_proto_db", "//components/sync", "//components/sync_device_info", + "//components/system_cpu:system_cpu", "//content/public/browser", "//ipc", "//pdf:buildflags", @@ -5843,9 +5841,6 @@ # Needed for _variant_t used in browser_dm_token_storage_win.cc "comsuppw.lib", - - # Needed for cpu_probe_win.cc - "pdh.lib", ] sources += [ "accessibility/caption_settings_dialog.h", @@ -5927,8 +5922,6 @@ "os_crypt/app_bound_encryption_win.h", "password_manager/password_manager_util_win.cc", "password_manager/password_manager_util_win.h", - "performance_manager/metrics/cpu_probe/cpu_probe_win.cc", - "performance_manager/metrics/cpu_probe/cpu_probe_win.h", "performance_monitor/metric_evaluator_helper_win.cc", "performance_monitor/metric_evaluator_helper_win.h", "platform_util_win.cc", @@ -6199,12 +6192,6 @@ "obsolete_system/obsolete_system_mac.cc", "password_manager/password_manager_util_mac.h", "password_manager/password_manager_util_mac.mm", - "performance_manager/metrics/cpu_probe/core_times.cc", - "performance_manager/metrics/cpu_probe/core_times.h", - "performance_manager/metrics/cpu_probe/cpu_probe_mac.cc", - "performance_manager/metrics/cpu_probe/cpu_probe_mac.h", - "performance_manager/metrics/cpu_probe/host_processor_info_scanner.cc", - "performance_manager/metrics/cpu_probe/host_processor_info_scanner.h", "platform_util_mac.mm", "policy/browser_dm_token_storage_mac.h", "policy/browser_dm_token_storage_mac.mm", @@ -6450,12 +6437,6 @@ "memory_details_linux.cc", "metrics/bluetooth_metrics_provider.cc", "metrics/bluetooth_metrics_provider.h", - "performance_manager/metrics/cpu_probe/core_times.cc", - "performance_manager/metrics/cpu_probe/core_times.h", - "performance_manager/metrics/cpu_probe/cpu_probe_linux.cc", - "performance_manager/metrics/cpu_probe/cpu_probe_linux.h", - "performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.cc", - "performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.h", "policy/browser_dm_token_storage_linux.cc", "policy/browser_dm_token_storage_linux.h", ]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 4afc11f..f15b759 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2519,13 +2519,6 @@ std::size(kAddToHomescreen_UseMessage), nullptr}}; #endif -constexpr FeatureEntry::FeatureParam kStorageAccessAPI_WithPrompt[] = { - {"storage_access_api_auto_deny_outside_fps", "false"}}; - -const FeatureEntry::FeatureVariation kStorageAccessAPIVariations[] = { - {"(with prompt)", kStorageAccessAPI_WithPrompt, - std::size(kStorageAccessAPI_WithPrompt), nullptr}}; - #if BUILDFLAG(IS_ANDROID) const FeatureEntry::FeatureParam kLensCameraAssistedSearchLensButtonStart[] = { {"searchBoxStartVariantForLensCameraAssistedSearch", "true"}}; @@ -5158,11 +5151,6 @@ flag_descriptions::kBackGestureRefactorAndroidName, flag_descriptions::kBackGestureRefactorAndroidDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kBackGestureRefactorAndroid)}, - {"back-gesture-refactor-activity-android", - flag_descriptions::kBackGestureRefactorActivityAndroidName, - flag_descriptions::kBackGestureRefactorActivityAndroidDescription, - kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kBackGestureRefactorActivityAndroid)}, {"draw-cutout-edge-to-edge", flag_descriptions::kDrawCutoutEdgeToEdgeName, flag_descriptions::kDrawCutoutEdgeToEdgeDescription, kOsAndroid, FEATURE_VALUE_TYPE(features::kDrawCutoutEdgeToEdge)}, @@ -7674,12 +7662,6 @@ FEATURE_VALUE_TYPE( blink::features::kFencedFramesReportingAttestationsChanges)}, - {"storage-access-api", flag_descriptions::kStorageAccessAPIName, - flag_descriptions::kStorageAccessAPIDescription, kOsAll, - FEATURE_WITH_PARAMS_VALUE_TYPE(blink::features::kStorageAccessAPI, - kStorageAccessAPIVariations, - "kStorageAccessAPI")}, - {"enable-unsafe-webgpu", flag_descriptions::kUnsafeWebGPUName, flag_descriptions::kUnsafeWebGPUDescription, kOsAll, SINGLE_VALUE_TYPE(switches::kEnableUnsafeWebGPU)}, @@ -10482,11 +10464,6 @@ FEATURE_VALUE_TYPE(media::kHideIncognitoMediaMetadata)}, #if BUILDFLAG(IS_ANDROID) - {"advanced-peripherals-support", - flag_descriptions::kAdvancedPeripheralsSupportName, - flag_descriptions::kAdvancedPeripheralsSupportDescription, kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kAdvancedPeripheralsSupport)}, - {"advanced-peripherals-support-tab-strip", flag_descriptions::kAdvancedPeripheralsSupportTabStripName, flag_descriptions::kAdvancedPeripheralsSupportTabStripDescription,
diff --git a/chrome/browser/android/chrome_backup_agent.cc b/chrome/browser/android/chrome_backup_agent.cc index 267b837..41e34dd 100644 --- a/chrome/browser/android/chrome_backup_agent.cc +++ b/chrome/browser/android/chrome_backup_agent.cc
@@ -21,7 +21,7 @@ static_assert(47 == syncer::GetNumModelTypes(), "If the new type has a corresponding pref, add it here"); -const char* backed_up_bool_preferences_[] = { +const char* const kBackedUpBoolPreferences[] = { syncer::prefs::internal::kSyncKeepEverythingSynced, syncer::prefs::internal::kSyncAutofill, syncer::prefs::internal::kSyncBookmarks, @@ -34,9 +34,6 @@ syncer::prefs::internal::kSyncTabs, }; -const char* backed_up_account_settings_preference_ = - syncer::prefs::internal::kSelectedTypesPerAccount; - } // namespace static base::android::ScopedJavaLocalRef<jobjectArray> @@ -52,11 +49,11 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller) { PrefService* prefs = ProfileManager::GetLastUsedProfile()->GetPrefs(); - constexpr int pref_count = std::size(backed_up_bool_preferences_); + constexpr int pref_count = std::size(kBackedUpBoolPreferences); jboolean values[pref_count]; for (int i = 0; i < pref_count; i++) { - values[i] = prefs->GetBoolean(backed_up_bool_preferences_[i]); + values[i] = prefs->GetBoolean(kBackedUpBoolPreferences[i]); } jbooleanArray array = env->NewBooleanArray(pref_count); env->SetBooleanArrayRegion(array, 0, pref_count, values); @@ -73,8 +70,7 @@ std::vector<bool> pref_values; base::android::JavaBooleanArrayToBoolVector(env, values, &pref_values); std::unordered_set<std::string> valid_prefs( - std::begin(backed_up_bool_preferences_), - std::end(backed_up_bool_preferences_)); + std::begin(kBackedUpBoolPreferences), std::end(kBackedUpBoolPreferences)); PrefService* prefs = ProfileManager::GetLastUsedProfile()->GetPrefs(); for (unsigned int i = 0; i < pref_names.size(); i++) { @@ -90,7 +86,7 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller) { return base::android::ConvertUTF8ToJavaString( - env, backed_up_account_settings_preference_); + env, syncer::prefs::internal::kSelectedTypesPerAccount); } static base::android::ScopedJavaLocalRef<jstring> @@ -99,7 +95,7 @@ const base::android::JavaParamRef<jobject>& jcaller) { PrefService* prefs = ProfileManager::GetLastUsedProfile()->GetPrefs(); const base::Value::Dict& account_settings = - prefs->GetDict(backed_up_account_settings_preference_); + prefs->GetDict(syncer::prefs::internal::kSelectedTypesPerAccount); std::string serialized_dict; JSONStringValueSerializer serializer(&serialized_dict); @@ -111,12 +107,12 @@ namespace android { std::vector<std::string> GetBackupBoolPrefNames() { - return std::vector<std::string>(std::begin(backed_up_bool_preferences_), - std::end(backed_up_bool_preferences_)); + return std::vector<std::string>(std::begin(kBackedUpBoolPreferences), + std::end(kBackedUpBoolPreferences)); } std::string GetBackupAccountSettingsPrefName() { - return backed_up_account_settings_preference_; + return syncer::prefs::internal::kSelectedTypesPerAccount; } base::android::ScopedJavaLocalRef<jobjectArray> GetBoolBackupNamesForTesting(
diff --git a/chrome/browser/android/customtabs/tab_interaction_recorder_android.cc b/chrome/browser/android/customtabs/tab_interaction_recorder_android.cc index 51c4075f..3cf1bbc 100644 --- a/chrome/browser/android/customtabs/tab_interaction_recorder_android.cc +++ b/chrome/browser/android/customtabs/tab_interaction_recorder_android.cc
@@ -72,7 +72,7 @@ void AutofillObserverImpl::OnAfterTextFieldDidChange(autofill::AutofillManager&, autofill::FormGlobalId, autofill::FieldGlobalId, - std::u16string) { + const std::u16string&) { OnFormInteraction(); }
diff --git a/chrome/browser/android/customtabs/tab_interaction_recorder_android.h b/chrome/browser/android/customtabs/tab_interaction_recorder_android.h index 49c957e3..9676623 100644 --- a/chrome/browser/android/customtabs/tab_interaction_recorder_android.h +++ b/chrome/browser/android/customtabs/tab_interaction_recorder_android.h
@@ -42,7 +42,7 @@ void OnAfterTextFieldDidChange(autofill::AutofillManager&, autofill::FormGlobalId, autofill::FieldGlobalId, - std::u16string) override; + const std::u16string&) override; void OnAfterTextFieldDidScroll(autofill::AutofillManager&, autofill::FormGlobalId, autofill::FieldGlobalId) override;
diff --git a/chrome/browser/ash/crosapi/browser_launcher.cc b/chrome/browser/ash/crosapi/browser_launcher.cc index 00567705..d78e95c91f 100644 --- a/chrome/browser/ash/crosapi/browser_launcher.cc +++ b/chrome/browser/ash/crosapi/browser_launcher.cc
@@ -10,9 +10,7 @@ #include "ash/constants/ash_switches.h" #include "base/base_switches.h" -#include "base/check_is_test.h" #include "base/command_line.h" -#include "base/containers/contains.h" #include "base/feature_list.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -20,7 +18,6 @@ #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/logging.h" -#include "base/no_destructor.h" #include "base/process/launch.h" #include "base/process/process.h" #include "base/strings/string_split.h" @@ -49,12 +46,6 @@ namespace { -// Returns additional test-only arguments for Lacros. -std::vector<std::string>& GetLacrosTestArguments() { - static base::NoDestructor<std::vector<std::string>> args; - return *args; -} - base::FilePath LacrosPostLoginLogPath() { return browser_util::GetUserDataDir().Append("lacros.log"); } @@ -179,21 +170,6 @@ return LaunchProcessWithParameters(command_line, options); } -// static -void BrowserLauncher::AddLacrosArgumentsForTest( - const std::vector<std::string>& args) { - CHECK_IS_TEST(); - for (const std::string& arg : args) { - CHECK(!base::Contains(arg, switches::kEnableFeatures) && - !base::Contains(arg, switches::kDisableFeatures)) - << "AddLacrosArgumentsForTest() does not support " // IN-TEST - "--enable-features or --disable-features. Use the ash switch " - "kLacrosChromeAdditionalArgs instead."; - } - std::vector<std::string>& test_args = GetLacrosTestArguments(); - test_args.insert(test_args.end(), args.begin(), args.end()); -} - std::vector<std::string> BrowserLauncher::InitializeArgv( const base::FilePath& chrome_path, const LaunchParamsFromBackground& params, @@ -258,10 +234,6 @@ argv.insert(argv.end(), params.lacros_additional_args.begin(), params.lacros_additional_args.end()); - // Provide any test switches. - const auto& test_args = GetLacrosTestArguments(); - argv.insert(argv.end(), test_args.begin(), test_args.end()); - // Forward flag for zero copy video capture to Lacros if it is enabled. if (switches::IsVideoCaptureUseGpuMemoryBufferEnabled()) { argv.emplace_back(
diff --git a/chrome/browser/ash/crosapi/browser_launcher.h b/chrome/browser/ash/crosapi/browser_launcher.h index 17c26a32..2ee5349 100644 --- a/chrome/browser/ash/crosapi/browser_launcher.h +++ b/chrome/browser/ash/crosapi/browser_launcher.h
@@ -109,9 +109,6 @@ bool LaunchProcessForTesting(const base::CommandLine& command_line, const base::LaunchOptions& options); - // Adds command line arguments that will be passed to Lacros. - static void AddLacrosArgumentsForTest(const std::vector<std::string>& args); - private: // Initializes argv for making the command line. // TODO(mayukoaiba): The process of making `command_line` is separated into 2
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.cc b/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.cc index 8be4679..25200dd 100644 --- a/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.cc +++ b/chrome/browser/ash/login/app_mode/test/kiosk_ash_browser_test_starter.cc
@@ -10,7 +10,6 @@ #include "base/check.h" #include "base/command_line.h" #include "base/environment.h" -#include "chrome/browser/ash/crosapi/browser_launcher.h" #include "chrome/browser/ash/crosapi/browser_manager.h" #include "chrome/browser/ash/crosapi/browser_util.h" #include "chrome/browser/ash/crosapi/fake_device_ownership_waiter.h" @@ -44,7 +43,9 @@ // environment. // See details in crbug/1483530. "--disable-gpu-sandbox"}; - crosapi::BrowserLauncher::AddLacrosArgumentsForTest(lacros_args); + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( + ash::switches::kLacrosChromeAdditionalArgs, + base::JoinString(lacros_args, "####")); } void KioskAshBrowserTestStarter::SetLacrosAvailabilityPolicy() {
diff --git a/chrome/browser/back_press/android/BUILD.gn b/chrome/browser/back_press/android/BUILD.gn index c5ae466..37faf1f3 100644 --- a/chrome/browser/back_press/android/BUILD.gn +++ b/chrome/browser/back_press/android/BUILD.gn
@@ -30,10 +30,7 @@ } robolectric_library("junit") { - sources = [ - "java/src/org/chromium/chrome/browser/back_press/BackPressHelperUnitTest.java", - "java/src/org/chromium/chrome/browser/back_press/BackPressManagerUnitTest.java", - ] + sources = [ "java/src/org/chromium/chrome/browser/back_press/BackPressManagerUnitTest.java" ] deps = [ ":java", @@ -45,8 +42,6 @@ "//components/browser_ui/widget/android:java", "//third_party/androidx:androidx_activity_activity_java", "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_runtime_java", "//third_party/junit:junit", "//third_party/mockito:mockito_java", ]
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelperUnitTest.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelperUnitTest.java deleted file mode 100644 index e6ebb05c..0000000 --- a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelperUnitTest.java +++ /dev/null
@@ -1,121 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.back_press; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - -import androidx.activity.OnBackPressedDispatcher; -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.LifecycleOwner; -import androidx.lifecycle.LifecycleRegistry; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; - -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.base.test.util.HistogramWatcher; -import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; - -/** Unit tests for {@link BackPressHelper}. */ -@RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class BackPressHelperUnitTest { - @Mock private BackPressHelper.ObsoleteBackPressedHandler mBackPressedHandler; - @Mock private BackPressHelper.ObsoleteBackPressedHandler mBackPressedHandler2; - @Mock private LifecycleOwner mLifecycleOwner; - private LifecycleRegistry mLifecycle; - @Mock private Runnable mFallbackRunnable; - - private OnBackPressedDispatcher mOnBackPressedDispatcher; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mLifecycle = new LifecycleRegistry(mLifecycleOwner); - mOnBackPressedDispatcher = new OnBackPressedDispatcher(mFallbackRunnable); - doReturn(mLifecycle).when(mLifecycleOwner).getLifecycle(); - mLifecycle.setCurrentState(Lifecycle.State.CREATED); - } - - @Test - public void testNextCallbackNotInvokedIfAlreadyConsumed() { - doReturn(true).when(mBackPressedHandler).onBackPressed(); - - // The last-added one is invoked first: mBackPressedHandler -> mBackPressedHandler2 - BackPressHelper.create( - mLifecycleOwner, - mOnBackPressedDispatcher, - mBackPressedHandler2, - SecondaryActivity.DOWNLOAD); - BackPressHelper.create( - mLifecycleOwner, - mOnBackPressedDispatcher, - mBackPressedHandler, - SecondaryActivity.HISTORY); - - var histogramWatcher = - HistogramWatcher.newSingleRecordWatcher( - "Android.BackPress.SecondaryActivity", SecondaryActivity.HISTORY); - mLifecycle.setCurrentState(Lifecycle.State.STARTED); - mOnBackPressedDispatcher.onBackPressed(); - - verify(mBackPressedHandler).onBackPressed(); - verify(mBackPressedHandler2, never()).onBackPressed(); - verify(mFallbackRunnable, never()).run(); - histogramWatcher.assertExpected(); - } - - @Test - public void testInvokeNextCallbackIfNotConsumed() { - doReturn(false).when(mBackPressedHandler).onBackPressed(); - doReturn(true).when(mBackPressedHandler2).onBackPressed(); - BackPressHelper.create( - mLifecycleOwner, - mOnBackPressedDispatcher, - mBackPressedHandler2, - SecondaryActivity.DOWNLOAD); - BackPressHelper.create( - mLifecycleOwner, - mOnBackPressedDispatcher, - mBackPressedHandler, - SecondaryActivity.HISTORY); - - var histogramWatcher = - HistogramWatcher.newSingleRecordWatcher( - "Android.BackPress.SecondaryActivity", SecondaryActivity.DOWNLOAD); - mLifecycle.setCurrentState(Lifecycle.State.STARTED); - mOnBackPressedDispatcher.onBackPressed(); - - verify(mBackPressedHandler).onBackPressed(); - verify(mBackPressedHandler2).onBackPressed(); - verify(mFallbackRunnable, never()).run(); - histogramWatcher.assertExpected(); - } - - @Test - public void testInvokeFallbackRunnableIfNotHandled() { - doReturn(false).when(mBackPressedHandler).onBackPressed(); - BackPressHelper.create( - mLifecycleOwner, - mOnBackPressedDispatcher, - mBackPressedHandler, - SecondaryActivity.HISTORY); - mLifecycle.setCurrentState(Lifecycle.State.STARTED); - mOnBackPressedDispatcher.onBackPressed(); - - var histogramWatcher = - HistogramWatcher.newBuilder() - .expectNoRecords("Android.BackPress.SecondaryActivity") - .build(); - verify(mFallbackRunnable).run(); - histogramWatcher.assertExpected(); - } -}
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 27dbafb..50e9905 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
@@ -149,13 +149,6 @@ } /** - * @return True if the back gesture refactor is enabled for secondary activities. - */ - public static boolean isSecondaryActivityEnabled() { - return ChromeFeatureList.sBackGestureRefactorActivityAndroid.isEnabled(); - } - - /** * @return True if ActivityTabProvider should replace ChromeTabActivity#getActivityTab */ public static boolean shouldUseActivityTabProvider() {
diff --git a/chrome/browser/chromeos/enterprise/cloud_storage/one_drive_pref_observer.cc b/chrome/browser/chromeos/enterprise/cloud_storage/one_drive_pref_observer.cc index a7e3b0b..cab77b8 100644 --- a/chrome/browser/chromeos/enterprise/cloud_storage/one_drive_pref_observer.cc +++ b/chrome/browser/chromeos/enterprise/cloud_storage/one_drive_pref_observer.cc
@@ -4,14 +4,17 @@ #include "chrome/browser/chromeos/enterprise/cloud_storage/one_drive_pref_observer.h" +#include "base/check_deref.h" #include "base/functional/bind.h" #include "base/values.h" #include "chrome/browser/chromeos/enterprise/cloud_storage/policy_utils.h" #include "chrome/browser/chromeos/extensions/odfs_config_private/odfs_config_private_api.h" +#include "chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_selections.h" #include "chrome/common/extensions/api/odfs_config_private.h" +#include "chrome/common/extensions/extension_constants.h" #include "chrome/common/pref_names.h" #include "chromeos/constants/chromeos_features.h" #include "components/keyed_service/core/keyed_service.h" @@ -22,6 +25,8 @@ #include "extensions/browser/extension_event_histogram_value.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_factory.h" +#include "extensions/browser/extension_system.h" +#include "extensions/browser/extension_system_provider.h" #include "extensions/browser/extensions_browser_client.h" using extensions::api::odfs_config_private::AccountRestrictionsInfo; @@ -55,10 +60,13 @@ void BroadcastModeChanged(Mount mode); void BroadcastAccountRestrictionsChanged(base::Value::List restrictions); + void MaybeUninstallOdfsExtension(Mount mode); + // Keyed services are shut down from the embedder's destruction of the profile // and this pointer is reset in `ShutDown`. Therefore it is safe to use this // raw pointer. raw_ptr<Profile> profile_ = nullptr; + // This keyed service depends on the EventRouter keyed service and will be // destroyed before the EventRouter. Therefore it is safe to use this raw // pointer. @@ -94,6 +102,8 @@ base::BindRepeating(&OneDrivePrefObserver:: OnMicrosoftOneDriveAccountRestrictionsPrefChanged, base::Unretained(this))); + OnMicrosoftOneDriveMountPrefChanged(); + OnMicrosoftOneDriveAccountRestrictionsPrefChanged(); } void OneDrivePrefObserver::Shutdown() { @@ -103,7 +113,9 @@ } void OneDrivePrefObserver::OnMicrosoftOneDriveMountPrefChanged() { - BroadcastModeChanged(GetMicrosoftOneDriveMount(profile_.get())); + const Mount mount = GetMicrosoftOneDriveMount(profile_); + BroadcastModeChanged(mount); + MaybeUninstallOdfsExtension(mount); } void OneDrivePrefObserver::OnMicrosoftOneDriveAccountRestrictionsPrefChanged() { @@ -111,6 +123,18 @@ GetMicrosoftOneDriveAccountRestrictions(profile_.get())); } +void OneDrivePrefObserver::MaybeUninstallOdfsExtension(Mount mount) { + if (cloud_upload::IsMicrosoftOfficeOneDriveIntegrationAllowed(profile_) || + !CHECK_DEREF(extensions::ExtensionRegistry::Get(profile_)) + .GetExtensionById( + extension_misc::kODFSExtensionId, + extensions::ExtensionRegistry::IncludeFlag::ENABLED)) { + return; + } + CHECK_DEREF(extensions::ExtensionSystem::Get(profile_)->extension_service()) + .RemoveComponentExtension(extension_misc::kODFSExtensionId); +} + } // namespace OneDrivePrefObserverFactory* OneDrivePrefObserverFactory::GetInstance() { @@ -123,6 +147,8 @@ ProfileSelections::BuildForRegularProfile()) { DependsOn(extensions::ExtensionRegistryFactory::GetInstance()); DependsOn(extensions::EventRouterFactory::GetInstance()); + DependsOn( + extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); } OneDrivePrefObserverFactory::~OneDrivePrefObserverFactory() = default;
diff --git a/chrome/browser/chromeos/enterprise/cloud_storage/one_drive_pref_observer_browsertest.cc b/chrome/browser/chromeos/enterprise/cloud_storage/one_drive_pref_observer_browsertest.cc index 62b3ba2..c52d726 100644 --- a/chrome/browser/chromeos/enterprise/cloud_storage/one_drive_pref_observer_browsertest.cc +++ b/chrome/browser/chromeos/enterprise/cloud_storage/one_drive_pref_observer_browsertest.cc
@@ -8,10 +8,13 @@ #include <vector> #include "base/containers/contains.h" +#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/policy/policy_test_utils.h" +#include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/extensions/api/odfs_config_private.h" +#include "chrome/common/extensions/extension_constants.h" #include "chrome/common/pref_names.h" #include "chromeos/constants/chromeos_features.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -22,9 +25,15 @@ #include "content/public/test/browser_test.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_event_histogram_value.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_system.h" +#include "extensions/browser/extension_system_provider.h" +#include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/test_event_router_observer.h" +#include "extensions/common/extension_builder.h" #include "testing/gmock/include/gmock/gmock.h" +using extensions::api::odfs_config_private::Mount; using testing::ElementsAreArray; namespace chromeos::cloud_storage { @@ -100,6 +109,18 @@ Profile* profile() { return browser()->profile(); } + const extensions::ExtensionRegistry* extension_registry() { + return extensions::ExtensionRegistry::Get(profile()); + } + + extensions::ExtensionService* extension_service() { + return extensions::ExtensionSystem::Get(profile())->extension_service(); + } + + policy::ProfilePolicyConnector* profile_policy_connector() { + return browser()->profile()->GetProfilePolicyConnector(); + } + private: base::test::ScopedFeatureList feature_list_; }; @@ -122,25 +143,25 @@ extensions::EventRouter::Get(profile()); extensions::TestEventRouterObserver observer(event_router); - SetOneDriveMount("automated"); + SetOneDriveMount(ToString(Mount::kAutomated)); ASSERT_EQ(1u, observer.events().size()); CheckMountChangedEvent(*observer.events().begin()->second, "automated"); observer.ClearEvents(); - SetOneDriveMount("automated"); + SetOneDriveMount(ToString(Mount::kAutomated)); ASSERT_EQ(0u, observer.events().size()); - SetOneDriveMount("allowed"); + SetOneDriveMount(ToString(Mount::kAllowed)); ASSERT_EQ(1u, observer.events().size()); CheckMountChangedEvent(*observer.events().begin()->second, "allowed"); observer.ClearEvents(); - SetOneDriveMount("disallowed"); + SetOneDriveMount(ToString(Mount::kDisallowed)); ASSERT_EQ(1u, observer.events().size()); CheckMountChangedEvent(*observer.events().begin()->second, "disallowed"); observer.ClearEvents(); - SetOneDriveMount("none"); + SetOneDriveMount(ToString(Mount::kNone)); ASSERT_EQ(1u, observer.events().size()); CheckMountChangedEvent(*observer.events().begin()->second, ""); observer.ClearEvents(); @@ -181,4 +202,42 @@ observer.ClearEvents(); } +IN_PROC_BROWSER_TEST_F(OneDrivePrefObserverBrowserTest, + OdfsExtensionUninstalledOnDisallowed) { + profile_policy_connector()->OverrideIsManagedForTesting(true); + SetOneDriveMount(ToString(Mount::kAutomated)); + scoped_refptr<const extensions::Extension> extension = + extensions::ExtensionBuilder("Odfs extension") + .SetID(extension_misc::kODFSExtensionId) + .Build(); + extension_service()->AddExtension(extension.get()); + ASSERT_TRUE(extension_registry()->GetExtensionById( + extension_misc::kODFSExtensionId, + extensions::ExtensionRegistry::IncludeFlag::ENABLED)); + + SetOneDriveMount(ToString(Mount::kDisallowed)); + ASSERT_FALSE(extension_registry()->GetExtensionById( + extension_misc::kODFSExtensionId, + extensions::ExtensionRegistry::IncludeFlag::EVERYTHING)); +} + +IN_PROC_BROWSER_TEST_F(OneDrivePrefObserverBrowserTest, + UnmanagedOdfsExtensionNotUninstalledOnDisallowed) { + profile_policy_connector()->OverrideIsManagedForTesting(false); + SetOneDriveMount(ToString(Mount::kAutomated)); + scoped_refptr<const extensions::Extension> extension = + extensions::ExtensionBuilder("Odfs extension") + .SetID(extension_misc::kODFSExtensionId) + .Build(); + extension_service()->AddExtension(extension.get()); + ASSERT_TRUE(extension_registry()->GetExtensionById( + extension_misc::kODFSExtensionId, + extensions::ExtensionRegistry::IncludeFlag::ENABLED)); + + SetOneDriveMount(ToString(Mount::kDisallowed)); + ASSERT_TRUE(extension_registry()->GetExtensionById( + extension_misc::kODFSExtensionId, + extensions::ExtensionRegistry::IncludeFlag::EVERYTHING)); +} + } // namespace chromeos::cloud_storage
diff --git a/chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.cc b/chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.cc index 425991ad..0917b17 100644 --- a/chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.cc +++ b/chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.cc
@@ -4,13 +4,18 @@ #include "chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.h" +#include "base/containers/contains.h" +#include "chrome/browser/chromeos/enterprise/cloud_storage/policy_utils.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/extensions/api/odfs_config_private.h" #include "chrome/common/pref_names.h" #include "chromeos/constants/chromeos_features.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" +using extensions::api::odfs_config_private::Mount; + namespace chromeos { namespace { @@ -24,9 +29,14 @@ return pref_value == cloud_upload::kCloudUploadPolicyAutomated; } +bool IsMicrosoftOfficeOneDriveIntegrationAutomated(const Profile* profile) { + return chromeos::cloud_storage::GetMicrosoftOneDriveMount(profile) == + Mount::kAutomated; +} + } // namespace -bool IsEligibleAndEnabledUploadOfficeToCloud(Profile* profile) { +bool IsEligibleAndEnabledUploadOfficeToCloud(const Profile* profile) { if (!chromeos::features::IsUploadOfficeToCloudEnabled()) { return false; } @@ -54,11 +64,23 @@ kCloudUploadPolicyAllowed); } +bool IsMicrosoftOfficeOneDriveIntegrationAllowed(const Profile* profile) { + if (profile->GetProfilePolicyConnector()->IsManaged()) { + return chromeos::features:: + IsMicrosoftOneDriveIntegrationForEnterpriseEnabled() && + base::Contains( + std::vector<Mount>{Mount::kAllowed, Mount::kAutomated}, + chromeos::cloud_storage::GetMicrosoftOneDriveMount(profile)); + } + return IsEligibleAndEnabledUploadOfficeToCloud(profile); +} + bool IsMicrosoftOfficeCloudUploadAllowed(Profile* profile) { if (!chromeos::features::IsUploadOfficeToCloudForEnterpriseEnabled()) { return IsEligibleAndEnabledUploadOfficeToCloud(profile); } return IsEligibleAndEnabledUploadOfficeToCloud(profile) && + IsMicrosoftOfficeOneDriveIntegrationAllowed(profile) && IsPrefValueSetToAllowed(profile->GetPrefs()->GetString( prefs::kMicrosoftOfficeCloudUpload)); } @@ -68,6 +90,7 @@ return false; } return IsEligibleAndEnabledUploadOfficeToCloud(profile) && + IsMicrosoftOfficeOneDriveIntegrationAutomated(profile) && IsPrefValueSetToAutomated(profile->GetPrefs()->GetString( prefs::kMicrosoftOfficeCloudUpload)); }
diff --git a/chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.h b/chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.h index fd0f5ea6..96f28215 100644 --- a/chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.h +++ b/chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.h
@@ -14,7 +14,7 @@ // the user of the `profile`. A user is eligible if they are not managed. // If `kUploadOfficeToCloudForEnterprise` is enabled too, the condition is // loosened and the user becomes eligible if they're not a child profile. -bool IsEligibleAndEnabledUploadOfficeToCloud(Profile* profile); +bool IsEligibleAndEnabledUploadOfficeToCloud(const Profile* profile); namespace cloud_upload { @@ -24,6 +24,10 @@ void RegisterProfilePrefs(PrefRegistrySimple* registry); +// Returns true if the MicrosoftOneDriveMount policy is set to `allowed` or +// `automated` and false otherwise. +bool IsMicrosoftOfficeOneDriveIntegrationAllowed(const Profile* profile); + // If `kUploadOfficeToCloudForEnterprise` is disabled, returns true if // IsEligibleAndEnabledUploadOfficeToCloud() is true. // Otherwise returns true if IsEligibleAndEnabledUploadOfficeToCloud() is true
diff --git a/chrome/browser/compose/compose_session.cc b/chrome/browser/compose/compose_session.cc index 5276c55..06e378c 100644 --- a/chrome/browser/compose/compose_session.cc +++ b/chrome/browser/compose/compose_session.cc
@@ -253,10 +253,10 @@ void ComposeSession::Rewrite(compose::mojom::StyleModifiersPtr style) { optimization_guide::proto::ComposeRequest request; - if (style->is_tone()) { + if (style && style->is_tone()) { request.mutable_rewrite_params()->set_tone( optimization_guide::proto::ComposeTone(style->get_tone())); - } else if (style->is_length()) { + } else if (style && style->is_length()) { request.mutable_rewrite_params()->set_length( optimization_guide::proto::ComposeLength(style->get_length())); } else {
diff --git a/chrome/browser/compose/compose_text_usage_logger.cc b/chrome/browser/compose/compose_text_usage_logger.cc index 2e9da22..ba7b168 100644 --- a/chrome/browser/compose/compose_text_usage_logger.cc +++ b/chrome/browser/compose/compose_text_usage_logger.cc
@@ -74,7 +74,7 @@ autofill::AutofillManager& manager, autofill::FormGlobalId form, autofill::FieldGlobalId field, - std::u16string text_value) { + const std::u16string& text_value) { autofill::FormType form_type = autofill::FormType::kUnknownFormType; int64_t form_control_type = -1; autofill::FormStructure* form_structure = manager.FindCachedFormById(form);
diff --git a/chrome/browser/compose/compose_text_usage_logger.h b/chrome/browser/compose/compose_text_usage_logger.h index 8dea8a6f..520450cd 100644 --- a/chrome/browser/compose/compose_text_usage_logger.h +++ b/chrome/browser/compose/compose_text_usage_logger.h
@@ -22,7 +22,7 @@ void OnAfterTextFieldDidChange(autofill::AutofillManager& manager, autofill::FormGlobalId form, autofill::FieldGlobalId field, - std::u16string text_value) override; + const std::u16string& text_value) override; private: // No public constructors to force going through static methods of
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc index 4fcfcc92..8a267ac 100644 --- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc +++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -2435,3 +2435,26 @@ ContentSetting::CONTENT_SETTING_ALLOW); EXPECT_EQ(CONTENT_SETTING_ASK, otr_map->GetContentSetting(host, host, type)); } + +// File access is not implemented on Android. Luckily we don't need it for DevTools. +#if !BUILDFLAG(IS_ANDROID) +TEST_F(HostContentSettingsMapTest, DevToolsFileAccess) { + TestingProfile profile; + HostContentSettingsMap* host_content_settings_map = + HostContentSettingsMapFactory::GetForProfile(&profile); + + GURL devtools_host("devtools://devtools/bundled/devtools_app.html"); + GURL example_host("https://example.com"); + + host_content_settings_map->SetDefaultContentSetting( + ContentSettingsType::FILE_SYSTEM_WRITE_GUARD, CONTENT_SETTING_BLOCK); + EXPECT_EQ(CONTENT_SETTING_ALLOW, + host_content_settings_map->GetContentSetting( + devtools_host, devtools_host, + ContentSettingsType::FILE_SYSTEM_WRITE_GUARD)); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + host_content_settings_map->GetContentSetting( + example_host, example_host, + ContentSettingsType::FILE_SYSTEM_WRITE_GUARD)); +} +#endif // !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ChipRenderParams.java b/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ChipRenderParams.java index 58c9919..9a49de0 100644 --- a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ChipRenderParams.java +++ b/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ChipRenderParams.java
@@ -35,10 +35,9 @@ public boolean isRemoveIconHidden; /** Defines the types of chips that can be rendered. */ - @IntDef({ChipType.LENS_SHOPPING_CHIP, ChipType.LENS_TRANSLATE_CHIP}) + @IntDef({ChipType.LENS_TRANSLATE_CHIP}) @Retention(RetentionPolicy.SOURCE) public @interface ChipType { - int LENS_SHOPPING_CHIP = 0; int LENS_TRANSLATE_CHIP = 1; } }
diff --git a/chrome/browser/devtools/protocol/autofill_handler.cc b/chrome/browser/devtools/protocol/autofill_handler.cc index 7cd6e57..c20011ad 100644 --- a/chrome/browser/devtools/protocol/autofill_handler.cc +++ b/chrome/browser/devtools/protocol/autofill_handler.cc
@@ -27,6 +27,7 @@ #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/render_frame_host.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/features.h" using autofill::AutofillField; using autofill::AutofillTriggerSource; @@ -277,6 +278,10 @@ ? protocol::Autofill::FillingStrategyEnum::AutofillInferred : protocol::Autofill::FillingStrategyEnum:: AutocompleteAttribute) + .SetFieldId(base::FeatureList::IsEnabled( + blink::features::kAutofillUseDomNodeIdForRendererId) + ? field->unique_renderer_id.value() + : 0) .Build()); }
diff --git a/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc b/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc index 8324989..f71c118b 100644 --- a/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc +++ b/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc
@@ -465,7 +465,7 @@ std::vector<const FormFieldData* const> filled_fields_by_autofill = { {&form.fields[0], &form.fields[1]}}; - // Enabled events and emit event about forming being filled. + // Enabled events and emit event about form being filled. SendCommandSync("Autofill.enable"); main_autofill_manager().NotifyObservers( &autofill::AutofillManager::Observer::OnFillOrPreviewDataModelForm, @@ -512,6 +512,8 @@ af->form_control_type)))); EXPECT_THAT(ff, FilledFieldHasAttributeWithValue16("name", af->name_attribute)); + EXPECT_EQ(*ff.GetDict().FindIntByDottedPath("fieldId"), + (int)(ffd->unique_renderer_id.value())); } // The first filled field uses autocomplete attribute as filling strategy.
diff --git a/chrome/browser/dips/dips_service_unittest.cc b/chrome/browser/dips/dips_service_unittest.cc index 7034146..23d5d3f 100644 --- a/chrome/browser/dips/dips_service_unittest.cc +++ b/chrome/browser/dips/dips_service_unittest.cc
@@ -550,7 +550,6 @@ std::vector<base::test::FeatureRefAndParams> enabled_features; enabled_features.push_back( {features::kDIPS, {{"delete", "true"}, {"triggering_action", "bounce"}}}); - enabled_features.push_back({blink::features::kStorageAccessAPI, {}}); base::test::ScopedFeatureList feature_list; feature_list.InitWithFeaturesAndParameters(enabled_features, {});
diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinator.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinator.java index ad1c0a4..fc3408e8 100644 --- a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinator.java +++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinator.java
@@ -26,12 +26,6 @@ void destroy(); /** - * To be called when the back button is pressed. - * @return Whether or not the back event has been consumed by this coordinator. - */ - boolean onBackPressed(); - - /** * Handlers interested in intercepting back events. The first handler has the top priority * and the last one has the least. * @return Handlers which are interested in consuming back press event.
diff --git a/chrome/browser/download/download_item_model_unittest.cc b/chrome/browser/download/download_item_model_unittest.cc index 6d7ab4d5..e5a5132 100644 --- a/chrome/browser/download/download_item_model_unittest.cc +++ b/chrome/browser/download/download_item_model_unittest.cc
@@ -547,73 +547,6 @@ #endif } -TEST_F(DownloadItemModelTest, CompletedBubbleWarningStatusText_Old) { - // TODO(crbug.com/1465966): Clean up after the base::Feature is removed. - base::test::ScopedFeatureList features; - features.InitAndDisableFeature( - safe_browsing::kImprovedDownloadBubbleWarnings); - - SetupCompletedDownloadItem(base::Hours(1)); - SetStatusTextBuilder(/*for_bubble=*/true); - - const struct InsecureDownloadStatusTestCase { - download::DownloadItem::InsecureDownloadStatus mixed_content_status; - std::string expected_bubble_status_msg; - } kInsecureDownloadStatusTestCases[] = { - {download::DownloadItem::InsecureDownloadStatus::BLOCK, - "Insecure download blocked"}, - {download::DownloadItem::InsecureDownloadStatus::WARN, - "Insecure download blocked"}, - }; - for (const auto& test_case : kInsecureDownloadStatusTestCases) { - SetupDownloadItemDefaults(); - ON_CALL(item(), GetInsecureDownloadStatus()) - .WillByDefault(Return(test_case.mixed_content_status)); - EXPECT_EQ(base::UTF16ToUTF8(model().GetStatusText()), - test_case.expected_bubble_status_msg); -#if !BUILDFLAG(IS_ANDROID) - // Android doesn't have BubbleUI info. - EXPECT_EQ(model().GetBubbleUIInfo().primary_button_command.value(), - DownloadCommands::Command::KEEP); -#endif // !BUILDFLAG(IS_ANDROID) - } - - const struct DangerTypeTestCase { - download::DownloadDangerType danger_type; - std::string expected_bubble_status_msg; - } kDangerTypeTestCases[] = { - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, - "Blocked \xE2\x80\xA2 Dangerous"}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT, - "Blocked \xE2\x80\xA2 Dangerous"}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST, - "Blocked \xE2\x80\xA2 Dangerous"}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE, - "Blocked \xE2\x80\xA2 Dangerous"}, - {download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED, - "Blocked \xE2\x80\xA2 Dangerous"}, - {download::DOWNLOAD_DANGER_TYPE_BLOCKED_PASSWORD_PROTECTED, - "Blocked \xE2\x80\xA2 Encrypted"}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, - "Blocked \xE2\x80\xA2 Malware"}, - {download::DOWNLOAD_DANGER_TYPE_BLOCKED_TOO_LARGE, - "Blocked \xE2\x80\xA2 Too big"}, - {download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING, - "Sensitive content"}, - {download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK, - "Blocked by your organization"}, - {download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING, - "Scan for malware \xE2\x80\xA2 Suspicious"}, - }; - for (const auto& test_case : kDangerTypeTestCases) { - SetupDownloadItemDefaults(); - ON_CALL(item(), GetDangerType()) - .WillByDefault(Return(test_case.danger_type)); - EXPECT_EQ(base::UTF16ToUTF8(model().GetStatusText()), - test_case.expected_bubble_status_msg); - } -} - TEST_F(DownloadItemModelTest, CompletedBubbleWarningStatusText) { SetupCompletedDownloadItem(base::Hours(1)); SetStatusTextBuilder(/*for_bubble=*/true); @@ -756,66 +689,6 @@ EXPECT_FALSE(bubble_ui_info.primary_button_command.has_value()); } -TEST_F(DownloadItemModelTest, DangerousWarningBubbleUIInfo_Old) { - // TODO(crbug.com/1465966): Clean up after the base::Feature is removed. - base::test::ScopedFeatureList features; - features.InitAndDisableFeature( - safe_browsing::kImprovedDownloadBubbleWarnings); - SetupCompletedDownloadItem(base::Hours(1)); - const struct DangerTypeTestCase { - download::DownloadDangerType danger_type; - absl::optional<DownloadCommands::Command> primary_button_command; - std::vector<DownloadCommands::Command> subpage_button_commands; - } kDangerTypeTestCases[] = { - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, - DownloadCommands::Command::KEEP, - {DownloadCommands::Command::DISCARD, DownloadCommands::Command::KEEP}}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT, - DownloadCommands::Command::DISCARD, - {DownloadCommands::Command::DISCARD}}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST, - DownloadCommands::Command::DISCARD, - {DownloadCommands::Command::DISCARD}}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE, - DownloadCommands::Command::DISCARD, - {DownloadCommands::Command::DISCARD}}, - {download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED, - DownloadCommands::Command::DISCARD, - {DownloadCommands::Command::DISCARD}}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, - DownloadCommands::Command::DISCARD, - {DownloadCommands::Command::DISCARD}}, - {download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING, - DownloadCommands::Command::DISCARD, - {DownloadCommands::Command::DISCARD, DownloadCommands::Command::KEEP}}, - {download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING, - absl::nullopt, - {DownloadCommands::Command::DEEP_SCAN, - DownloadCommands::Command::BYPASS_DEEP_SCANNING}}, - {download::DOWNLOAD_DANGER_TYPE_ASYNC_SCANNING, - absl::nullopt, - {DownloadCommands::Command::DISCARD, - DownloadCommands::Command::CANCEL_DEEP_SCAN}}, - }; - for (const auto& test_case : kDangerTypeTestCases) { - SCOPED_TRACE(testing::Message() - << "Failed for danger type " - << download::GetDownloadDangerTypeString(test_case.danger_type) - << std::endl); - SetupDownloadItemDefaults(); - ON_CALL(item(), GetDangerType()) - .WillByDefault(Return(test_case.danger_type)); - DownloadUIModel::BubbleUIInfo bubble_ui_info = model().GetBubbleUIInfo(); - EXPECT_EQ(bubble_ui_info.primary_button_command, - test_case.primary_button_command); - std::vector<DownloadCommands::Command> subpage_commands; - for (auto button : bubble_ui_info.subpage_buttons) { - subpage_commands.push_back(button.command); - } - EXPECT_EQ(subpage_commands, test_case.subpage_button_commands); - } -} - TEST_F(DownloadItemModelTest, DangerousWarningBubbleUIInfo) { SetupCompletedDownloadItem(base::Hours(1)); const struct DangerTypeTestCase { @@ -1047,31 +920,11 @@ } #if BUILDFLAG(FULL_SAFE_BROWSING) -// TODO(chlily): Add more tests for kImprovedDownloadBubbleWarnings. At the -// moment, these only include tests for the file type warnings. -class DownloadItemModelImprovedDownloadBubbleWarningsTest - : public DownloadItemModelTest { - public: - DownloadItemModelImprovedDownloadBubbleWarningsTest() { - scoped_feature_list_.InitAndEnableFeature( - safe_browsing::kImprovedDownloadBubbleWarnings); - } - - void SetUp() override { - DownloadItemModelTest::SetUp(); - SetupDownloadItemDefaults(); - SetupCompletedDownloadItem(base::Minutes(30)); - SetStatusTextBuilder(/*for_bubble=*/true); - } - ~DownloadItemModelImprovedDownloadBubbleWarningsTest() override = default; - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - // Test file type warning where verdict was obtained. -TEST_F(DownloadItemModelImprovedDownloadBubbleWarningsTest, - FileTypeWarning_HasSafeBrowsingVerdict) { +TEST_F(DownloadItemModelTest, FileTypeWarning_HasSafeBrowsingVerdict) { + SetupDownloadItemDefaults(); + SetupCompletedDownloadItem(base::Minutes(30)); + SetStatusTextBuilder(/*for_bubble=*/true); for (auto sb_state : {safe_browsing::SafeBrowsingState::STANDARD_PROTECTION, safe_browsing::SafeBrowsingState::ENHANCED_PROTECTION, // This can happen if the user subsequently turned off @@ -1111,8 +964,10 @@ } // Test file type warning where SB is on but no SB verdict was obtained. -TEST_F(DownloadItemModelImprovedDownloadBubbleWarningsTest, - FileTypeWarning_SafeBrowsingOn_NoVerdict) { +TEST_F(DownloadItemModelTest, FileTypeWarning_SafeBrowsingOn_NoVerdict) { + SetupDownloadItemDefaults(); + SetupCompletedDownloadItem(base::Minutes(30)); + SetStatusTextBuilder(/*for_bubble=*/true); for (auto sb_state : {safe_browsing::SafeBrowsingState::STANDARD_PROTECTION, safe_browsing::SafeBrowsingState::ENHANCED_PROTECTION}) { @@ -1147,8 +1002,10 @@ } // Test file type warning where SB is disabled by pref and can be turned on. -TEST_F(DownloadItemModelImprovedDownloadBubbleWarningsTest, - FileTypeWarning_NoSafeBrowsing_DisabledByPref) { +TEST_F(DownloadItemModelTest, FileTypeWarning_NoSafeBrowsing_DisabledByPref) { + SetupDownloadItemDefaults(); + SetupCompletedDownloadItem(base::Minutes(30)); + SetStatusTextBuilder(/*for_bubble=*/true); SetSafeBrowsingState(profile()->GetPrefs(), safe_browsing::SafeBrowsingState::NO_SAFE_BROWSING); EXPECT_CALL(item(), GetDangerType()) @@ -1180,8 +1037,10 @@ // Test file type warning where SB is disabled by enterprise controls and cannot // be turned on. -TEST_F(DownloadItemModelImprovedDownloadBubbleWarningsTest, - FileTypeWarning_NoSafeBrowsing_DisabledManaged) { +TEST_F(DownloadItemModelTest, FileTypeWarning_NoSafeBrowsing_DisabledManaged) { + SetupDownloadItemDefaults(); + SetupCompletedDownloadItem(base::Minutes(30)); + SetStatusTextBuilder(/*for_bubble=*/true); SetSafeBrowsingState(profile()->GetPrefs(), safe_browsing::SafeBrowsingState::NO_SAFE_BROWSING); testing_profile()->GetTestingPrefService()->SetManagedPref(
diff --git a/chrome/browser/download/download_ui_model.cc b/chrome/browser/download/download_ui_model.cc index f600c95..2d3164fd 100644 --- a/chrome/browser/download/download_ui_model.cc +++ b/chrome/browser/download/download_ui_model.cc
@@ -31,7 +31,6 @@ #include "components/enterprise/common/proto/connectors.pb.h" #include "components/google/core/common/google_util.h" #include "components/safe_browsing/buildflags.h" -#include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/safe_browsing/core/common/safebrowsing_referral_methods.h" #include "components/vector_icons/vector_icons.h" @@ -1141,135 +1140,42 @@ switch (GetDangerType()) { case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: if (IsExtensionDownload()) { - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - return DownloadUIModel::BubbleUIInfo::SuspiciousUiPattern( - l10n_util::GetStringFUTF16( - IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_UNKNOWN_SOURCE, - l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)), - l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_CONTINUE_SUSPICIOUS_FILE)); - } - return DownloadUIModel::BubbleUIInfo() - .AddSubpageSummary(l10n_util::GetStringFUTF16( + return DownloadUIModel::BubbleUIInfo::SuspiciousUiPattern( + l10n_util::GetStringFUTF16( IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_UNKNOWN_SOURCE, - l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE))) - .AddIconAndColor(features::IsChromeRefresh2023() - ? kDownloadWarningIcon - : vector_icons::kNotSecureWarningIcon, - kColorDownloadItemIconWarning) - .AddSecondaryTextColor(kColorDownloadItemTextWarning) - .AddPrimarySubpageButton( - l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE), - DownloadCommands::Command::DISCARD) - .AddSecondarySubpageButton( - l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE), - DownloadCommands::Command::KEEP, kColorDownloadItemTextWarning); - } else { - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - if (WasSafeBrowsingVerdictObtained(GetDownloadItem())) { - return DownloadUIModel::BubbleUIInfo::SuspiciousUiPattern( - l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_WARNING_DANGEROUS_FILE_TYPE), - l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_CONTINUE_SUSPICIOUS_FILE)); - } - if (ShouldShowWarningForNoSafeBrowsing(profile())) { - return GetBubbleUIInfoForFileTypeWarningNoSafeBrowsing(); - } - return DownloadUIModel::BubbleUIInfo::SuspiciousUiPattern( - l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_WARNING_DANGEROUS_FILE_TYPE), - l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_CONTINUE_UNVERIFIED_FILE)); - } - return DownloadUIModel::BubbleUIInfo() - .AddSubpageSummary( - l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DANGEROUS_FILE)) - .AddIconAndColor(features::IsChromeRefresh2023() - ? kDownloadWarningIcon - : vector_icons::kNotSecureWarningIcon, - ui::kColorSecondaryForeground) - .AddPrimaryButton(DownloadCommands::Command::KEEP) - .AddPrimarySubpageButton( - l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE), - DownloadCommands::Command::DISCARD) - .AddSecondarySubpageButton( - l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE), - DownloadCommands::Command::KEEP, ui::kColorSecondaryForeground); + l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)), + l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_CONTINUE_SUSPICIOUS_FILE)); } + if (WasSafeBrowsingVerdictObtained(GetDownloadItem())) { + return DownloadUIModel::BubbleUIInfo::SuspiciousUiPattern( + l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_WARNING_DANGEROUS_FILE_TYPE), + l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_CONTINUE_SUSPICIOUS_FILE)); + } + if (ShouldShowWarningForNoSafeBrowsing(profile())) { + return GetBubbleUIInfoForFileTypeWarningNoSafeBrowsing(); + } + return DownloadUIModel::BubbleUIInfo::SuspiciousUiPattern( + l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_WARNING_DANGEROUS_FILE_TYPE), + l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_CONTINUE_UNVERIFIED_FILE)); + case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE: - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - return DownloadUIModel::BubbleUIInfo::DangerousUiPattern( - l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_WARNING_DANGEROUS)); - } else { - ui_info - .AddSubpageSummary(l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_MALICIOUS_URL_BLOCKED)) - .AddIconAndColor(features::IsChromeRefresh2023() - ? vector_icons::kDangerousChromeRefreshIcon - : vector_icons::kDangerousIcon, - kColorDownloadItemIconDangerous) - .AddPrimaryButton(DownloadCommands::Command::DISCARD) - .AddPrimarySubpageButton( - l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE), - DownloadCommands::Command::DISCARD); - return ui_info; - } + case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: + return DownloadUIModel::BubbleUIInfo::DangerousUiPattern( + l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_WARNING_DANGEROUS)); case download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - return DownloadUIModel::BubbleUIInfo::DangerousUiPattern( - l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_WARNING_DECEPTIVE)); - } else { - ui_info = - DownloadUIModel::BubbleUIInfo() - .AddSubpageSummary(l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_MALICIOUS_URL_BLOCKED)) - .AddIconAndColor(features::IsChromeRefresh2023() - ? kDownloadWarningIcon - : vector_icons::kNotSecureWarningIcon, - kColorDownloadItemIconWarning) - .AddSecondaryTextColor(kColorDownloadItemTextWarning) - .AddPrimaryButton(DownloadCommands::Command::DISCARD) - .AddPrimarySubpageButton( - l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE), - DownloadCommands::Command::DISCARD); - return ui_info; - } + return DownloadUIModel::BubbleUIInfo::DangerousUiPattern( + l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_WARNING_DECEPTIVE)); - case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - // This is the same as the message for - // DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT, etc. - // TODO(chlily): Combine these cases after other conditionals are - // removed. - return DownloadUIModel::BubbleUIInfo::DangerousUiPattern( - l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_WARNING_DANGEROUS)); - } else { - ui_info = - DownloadUIModel::BubbleUIInfo() - .AddSubpageSummary(l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_MALWARE)) - .AddIconAndColor(features::IsChromeRefresh2023() - ? kDownloadWarningIcon - : vector_icons::kNotSecureWarningIcon, - kColorDownloadItemIconDangerous) - .AddPrimaryButton(DownloadCommands::Command::DISCARD) - .AddPrimarySubpageButton( - l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE), - DownloadCommands::Command::DISCARD); - return ui_info; - } case download::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: { bool request_ap_verdicts = false; #if BUILDFLAG(FULL_SAFE_BROWSING) @@ -1293,31 +1199,12 @@ .AddSecondarySubpageButton( l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE), DownloadCommands::Command::KEEP, kColorDownloadItemTextWarning); - } else { - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - return DownloadUIModel::BubbleUIInfo::SuspiciousUiPattern( - l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_WARNING_UNCOMMON_FILE), - l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_CONTINUE_SUSPICIOUS_FILE)); - } - return DownloadUIModel::BubbleUIInfo() - .AddSubpageSummary(l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_UNCOMMON_FILE)) - .AddIconAndColor(features::IsChromeRefresh2023() - ? kDownloadWarningIcon - : vector_icons::kNotSecureWarningIcon, - kColorDownloadItemIconWarning) - .AddSecondaryTextColor(kColorDownloadItemTextWarning) - .AddPrimaryButton(DownloadCommands::Command::DISCARD) - .AddPrimarySubpageButton( - l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE), - DownloadCommands::Command::DISCARD) - .AddSecondarySubpageButton( - l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE), - DownloadCommands::Command::KEEP, kColorDownloadItemTextWarning); } + return DownloadUIModel::BubbleUIInfo::SuspiciousUiPattern( + l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_WARNING_UNCOMMON_FILE), + l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_CONTINUE_SUSPICIOUS_FILE)); } case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING: return DownloadUIModel::BubbleUIInfo() @@ -1713,43 +1600,25 @@ // "Blocked • Unknown source" return get_blocked_warning(IDS_DOWNLOAD_BUBBLE_STATUS_UNKNOWN_SOURCE); } - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - if (WasSafeBrowsingVerdictObtained(model_->GetDownloadItem())) { - // "Suspicious download blocked" - return l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_STATUS_WARNING_SUSPICIOUS); - } - // "Unverified download blocked" + if (WasSafeBrowsingVerdictObtained(model_->GetDownloadItem())) { + // "Suspicious download blocked" return l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_STATUS_WARNING_UNVERIFIED); + IDS_DOWNLOAD_BUBBLE_STATUS_WARNING_SUSPICIOUS); } - [[fallthrough]]; + // "Unverified download blocked" + return l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_STATUS_WARNING_UNVERIFIED); case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE: case download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - // "Dangerous download blocked" - return l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_STATUS_WARNING_DANGEROUS); - } - // "Blocked • Dangerous" - return get_blocked_warning(IDS_DOWNLOAD_BUBBLE_STATUS_DANGEROUS); - + case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: + // "Dangerous download blocked" + return l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_STATUS_WARNING_DANGEROUS); case download::DOWNLOAD_DANGER_TYPE_BLOCKED_PASSWORD_PROTECTED: // "Blocked • Encrypted" return get_blocked_warning(IDS_DOWNLOAD_BUBBLE_STATUS_ENCRYPTED); - case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - // "Dangerous download blocked" - return l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_STATUS_WARNING_DANGEROUS); - } - // "Blocked • Malware" - return get_blocked_warning(IDS_DOWNLOAD_BUBBLE_STATUS_MALWARE); case download::DOWNLOAD_DANGER_TYPE_BLOCKED_TOO_LARGE: // "Blocked • Too big" return get_blocked_warning(IDS_DOWNLOAD_BUBBLE_STATUS_TOO_BIG); @@ -1761,17 +1630,12 @@ model_->profile()) ->IsUnderAdvancedProtection(); #endif - // "Blocked by Advanced Protection" or ("Suspicious download blocked" or - // "Blocked • Uncommon file" depending on feature state). + // "Blocked by Advanced Protection" or "Suspicious download blocked" return request_ap_verdicts ? l10n_util::GetStringUTF16( IDS_DOWNLOAD_BUBBLE_STATUS_ADVANCED_PROTECTION) - : (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings) - ? l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_STATUS_WARNING_SUSPICIOUS) - : get_blocked_warning( - IDS_DOWNLOAD_BUBBLE_STATUS_UNCOMMON_FILE)); + : l10n_util::GetStringUTF16( + IDS_DOWNLOAD_BUBBLE_STATUS_WARNING_SUSPICIOUS); } case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING:
diff --git a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java index 77a82f07..2ae4a66 100644 --- a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java +++ b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java
@@ -57,19 +57,15 @@ import org.chromium.base.test.util.HistogramWatcher; import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.browser.back_press.BackPressHelper; -import org.chromium.chrome.browser.back_press.BackPressManager; import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.download.home.list.ListUtils; import org.chromium.chrome.browser.download.home.list.holder.ListItemViewHolder; import org.chromium.chrome.browser.download.home.rename.RenameUtils; import org.chromium.chrome.browser.download.home.toolbar.DownloadHomeToolbar; import org.chromium.chrome.browser.download.internal.R; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.test.AutomotiveContextWrapperTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.browser_ui.modaldialog.AppModalPresenter; import org.chromium.components.browser_ui.util.date.StringUtils; import org.chromium.components.embedder_support.util.UrlConstants; @@ -208,19 +204,11 @@ mStubbedOfflineContentProvider, mDiscardableReferencePool); getActivity().setContentView(mDownloadCoordinator.getView()); - if (BackPressManager.isSecondaryActivityEnabled()) { - BackPressHelper.create( - getActivity(), - getActivity().getOnBackPressedDispatcher(), - mDownloadCoordinator.getBackPressHandlers(), - SecondaryActivity.DOWNLOAD); - } else { - BackPressHelper.create( - getActivity(), - getActivity().getOnBackPressedDispatcher(), - mDownloadCoordinator::onBackPressed, - SecondaryActivity.DOWNLOAD); - } + BackPressHelper.create( + getActivity(), + getActivity().getOnBackPressedDispatcher(), + mDownloadCoordinator.getBackPressHandlers(), + SecondaryActivity.DOWNLOAD); mDownloadCoordinator.updateForUrl(UrlConstants.DOWNLOADS_URL); } @@ -602,8 +590,6 @@ @Test @MediumTest - @DisableFeatures({ChromeFeatureList.BACK_GESTURE_REFACTOR_ACTIVITY}) - @DisabledTest(message = "https://crbug.com/1416712") public void testDismissSearchViewByBackPress() { TestThreadUtils.runOnUiThreadBlocking( () -> { @@ -645,13 +631,6 @@ }); } - @Test - @MediumTest - @EnableFeatures({ChromeFeatureList.BACK_GESTURE_REFACTOR_ACTIVITY}) - public void testDismissSearchViewByBackPress_BackPressRefactor() { - testDismissSearchViewByBackPress(); - } - /** * @param items The list (unsorted) of OfflineItems that could be displayed. * @param expectations Whether or not each item (1:1 with {@code items}) is visible.
diff --git a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java index d428e82b..6625a17 100644 --- a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java +++ b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadManagerCoordinatorImpl.java
@@ -165,12 +165,6 @@ } @Override - public boolean onBackPressed() { - if (mListCoordinator.handleBackPressed()) return true; - return mToolbarCoordinator.handleBackPressed(); - } - - @Override public BackPressHandler[] getBackPressHandlers() { return mBackPressHandlers; }
diff --git a/chrome/browser/first_party_sets/first_party_sets_navigation_throttle_unittest.cc b/chrome/browser/first_party_sets/first_party_sets_navigation_throttle_unittest.cc index 4c19956..f0e3cbda 100644 --- a/chrome/browser/first_party_sets/first_party_sets_navigation_throttle_unittest.cc +++ b/chrome/browser/first_party_sets/first_party_sets_navigation_throttle_unittest.cc
@@ -40,7 +40,7 @@ kWaitForFirstPartySetsInitNavigationThrottleTimeout.name, "2s"}}}, }, - {{blink::features::kStorageAccessAPI}}); + {}); } void SetUp() override {
diff --git a/chrome/browser/first_party_sets/first_party_sets_policy_browsertest.cc b/chrome/browser/first_party_sets/first_party_sets_policy_browsertest.cc index 58c4380..c41482eb 100644 --- a/chrome/browser/first_party_sets/first_party_sets_policy_browsertest.cc +++ b/chrome/browser/first_party_sets/first_party_sets_policy_browsertest.cc
@@ -54,11 +54,8 @@ public: EnabledPolicyBrowsertest() : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { - std::vector<base::test::FeatureRef> enabled_features = { - blink::features::kStorageAccessAPI}; - std::vector<base::test::FeatureRef> disabled_features = { - content_settings::features::kTrackingProtection3pcd}; - scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features); + scoped_feature_list_.InitWithFeatures( + {}, {content_settings::features::kTrackingProtection3pcd}); } void SetBlockThirdPartyCookies(bool value) {
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 0adac21..141a0a6 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -82,11 +82,6 @@ "expiry_milestone": 124 }, { - "name": "advanced-peripherals-support", - "owners": [ "aishwaryarj@google.com", "zheliooo@google.com", "skavuluru@google.com", "clank-app-team@google.com" ], - "expiry_milestone": 124 - }, - { "name": "advanced-peripherals-support-tab-strip", "owners": [ "aishwaryarj@google.com", "zheliooo@google.com", "skavuluru@google.com", "clank-app-team@google.com" ], "expiry_milestone": 124 @@ -782,11 +777,6 @@ "expiry_milestone": 130 }, { - "name": "back-gesture-refactor-activity-android", - "owners": ["lazzzis@google.com", "jinsukkim@chromium.org", "twellington@chromium.org"], - "expiry_milestone": 130 - }, - { "name": "back-gesture-refactor-android", "owners": ["lazzzis@google.com", "jinsukkim@chromium.org", "twellington@chromium.org"], "expiry_milestone": 130 @@ -4861,6 +4851,11 @@ "expiry_milestone": 130 }, { + "name": "ios-external-action-urls", + "owners": ["nicolasmacbeth@google.com", "bling-mony-pod@google.com"], + "expiry_milestone": 125 + }, + { "name": "ios-hide-feed-with-search-choice", "owners": ["scottyoder@google.com", "bling-get-set-up@google.com"], "expiry_milestone": 123
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 886096e..d909f39 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -57,11 +57,6 @@ "renderer choice is controlled by an enterprise policy."; #endif -const char kAdvancedPeripheralsSupportName[] = - "Advanced peripherals support on Android."; -const char kAdvancedPeripheralsSupportDescription[] = - "Advanced keyboard, mouse and trackpad support for increased productivity."; - const char kAdvancedPeripheralsSupportTabStripName[] = "Advanced peripherals support for the tab strip on Android."; const char kAdvancedPeripheralsSupportTabStripDescription[] = @@ -3211,11 +3206,6 @@ "Controls whether site isolation should use origins instead of scheme and " "eTLD+1."; -const char kStorageAccessAPIName[] = "Storage Access API"; -const char kStorageAccessAPIDescription[] = - "Enables the Storage Access API, allowing websites to request storage " - "access when it would otherwise be restricted."; - const char kSupportTool[] = "Support Tool"; const char kSupportToolDescription[] = "Support Tool collects and exports logs to help debugging the issues. It's" @@ -3867,12 +3857,6 @@ "get current tab, rather than getActivityTab if predictive back gesture" "is disabled."; -const char kBackGestureRefactorActivityAndroidName[] = - "Back Gesture Refactor (Secondary Activities)"; -const char kBackGestureRefactorActivityAndroidDescription[] = - "Enable Back Gesture Refactor for Secondary Activities to support in-app " - "activity-to-activity predictive back gestures"; - const char kBackGestureRefactorAndroidName[] = "Back Gesture Refactor"; const char kBackGestureRefactorAndroidDescription[] = "Enable Back Gesture Refactor."; @@ -4018,10 +4002,6 @@ const char kEnablePixDetectionDescription[] = "Enables PIX code detection on allow-listed merchant websites."; -const char kExploreSitesName[] = "Explore websites"; -const char kExploreSitesDescription[] = - "Enables portal from new tab page to explore websites."; - const char kExternalNavigationDebugLogsName[] = "External Navigation Debug Logs"; const char kExternalNavigationDebugLogsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index b247d3cf..47ec959 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -53,9 +53,6 @@ extern const char kAcceleratedVideoEncodeName[]; extern const char kAcceleratedVideoEncodeDescription[]; -extern const char kAdvancedPeripheralsSupportName[]; -extern const char kAdvancedPeripheralsSupportDescription[]; - extern const char kAdvancedPeripheralsSupportTabStripName[]; extern const char kAdvancedPeripheralsSupportTabStripDescription[]; @@ -1822,9 +1819,6 @@ extern const char kSkiaRendererName[]; extern const char kSkiaRendererDescription[]; -extern const char kStorageAccessAPIName[]; -extern const char kStorageAccessAPIDescription[]; - extern const char kIsolateOriginsName[]; extern const char kIsolateOriginsDescription[]; @@ -2238,9 +2232,6 @@ extern const char kBackGestureActivityTabProviderName[]; extern const char kBackGestureActivityTabProviderDescription[]; -extern const char kBackGestureRefactorActivityAndroidName[]; -extern const char kBackGestureRefactorActivityAndroidDescription[]; - extern const char kBackGestureRefactorAndroidName[]; extern const char kBackGestureRefactorAndroidDescription[]; @@ -2333,9 +2324,6 @@ extern const char kEnablePixDetectionName[]; extern const char kEnablePixDetectionDescription[]; -extern const char kExploreSitesName[]; -extern const char kExploreSitesDescription[]; - extern const char kExternalNavigationDebugLogsName[]; extern const char kExternalNavigationDebugLogsDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index f9936d23..ac3f5986 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -153,7 +153,6 @@ &kAdaptiveButtonInTopToolbarAddToBookmarks, &kAdaptiveButtonInTopToolbarCustomizationV2, &kAddToHomescreenIPH, - &kAdvancedPeripheralsSupport, &kAdvancedPeripheralsSupportTabStrip, &kRedirectExplicitCTAIntentsToExistingActivity, &kAllowNewIncognitoTabIntents, @@ -168,7 +167,6 @@ &kAuxiliarySearchDonation, &kAvoidSelectedTabFocusOnLayoutDoneShowing, &kBackGestureActivityTabProvider, - &kBackGestureRefactorActivityAndroid, &kBackGestureRefactorAndroid, &kBackgroundThreadPool, &kBlockIntentsWhileLocked, @@ -193,11 +191,6 @@ &kCacheDeprecatedSystemLocationSetting, &kChromeSurveyNextAndroid, &kCommandLineOnNonRooted, - &kContextMenuEnableLensShoppingAllowlist, - &kContextMenuGoogleLensChip, - &kContextMenuSearchWithGoogleLens, - &kContextMenuShopWithGoogleLens, - &kContextMenuSearchAndShopWithGoogleLens, &kContextMenuTranslateWithGoogleLens, &kContextMenuPopupForAllScreenSizes, &kContextualSearchDisableOnlineDetection, @@ -215,7 +208,6 @@ &kDynamicTopChrome, &kEarlyInitializeStartupMetrics, &kExperimentsForAgsa, - &kExploreSites, &kFocusOmniboxInIncognitoTabIntents, &kGridTabSwitcherAndroidAnimations, &kHideTabOnTabSwitcher, @@ -397,10 +389,6 @@ "AddToHomescreenIPH", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kAdvancedPeripheralsSupport, - "AdvancedPeripheralsSupport", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kAdvancedPeripheralsSupportTabStrip, "AdvancedPeripheralsSupportTabStrip", base::FEATURE_ENABLED_BY_DEFAULT); @@ -542,30 +530,10 @@ "CommandLineOnNonRooted", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kContextMenuEnableLensShoppingAllowlist, - "ContextMenuEnableLensShoppingAllowlist", - base::FEATURE_DISABLED_BY_DEFAULT); - -BASE_FEATURE(kContextMenuGoogleLensChip, - "ContextMenuGoogleLensChip", - base::FEATURE_DISABLED_BY_DEFAULT); - BASE_FEATURE(kContextMenuPopupForAllScreenSizes, "ContextMenuPopupForAllScreenSizes", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kContextMenuSearchWithGoogleLens, - "ContextMenuSearchWithGoogleLens", - base::FEATURE_ENABLED_BY_DEFAULT); - -BASE_FEATURE(kContextMenuShopWithGoogleLens, - "ContextMenuShopWithGoogleLens", - base::FEATURE_DISABLED_BY_DEFAULT); - -BASE_FEATURE(kContextMenuSearchAndShopWithGoogleLens, - "ContextMenuSearchAndShopWithGoogleLens", - base::FEATURE_DISABLED_BY_DEFAULT); - BASE_FEATURE(kContextMenuTranslateWithGoogleLens, "ContextMenuTranslateWithGoogleLens", base::FEATURE_DISABLED_BY_DEFAULT); @@ -642,8 +610,6 @@ "ExperimentsForAgsa", base::FEATURE_ENABLED_BY_DEFAULT); -BASE_FEATURE(kExploreSites, "ExploreSites", base::FEATURE_DISABLED_BY_DEFAULT); - BASE_FEATURE(kGridTabSwitcherAndroidAnimations, "GridTabSwitcherAndroidAnimations", base::FEATURE_DISABLED_BY_DEFAULT); @@ -697,10 +663,6 @@ "BackGestureActivityTabProvider", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kBackGestureRefactorActivityAndroid, - "BackGestureRefactorActivityAndroid", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kBackGestureRefactorAndroid, "BackGestureRefactorAndroid", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index a3055000..2ba96d52 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -19,7 +19,6 @@ BASE_DECLARE_FEATURE(kAdaptiveButtonInTopToolbarAddToBookmarks); BASE_DECLARE_FEATURE(kAdaptiveButtonInTopToolbarCustomizationV2); BASE_DECLARE_FEATURE(kAddToHomescreenIPH); -BASE_DECLARE_FEATURE(kAdvancedPeripheralsSupport); BASE_DECLARE_FEATURE(kAdvancedPeripheralsSupportTabStrip); BASE_DECLARE_FEATURE(kAllowNewIncognitoTabIntents); BASE_DECLARE_FEATURE(kAndroidAppIntegration); @@ -33,7 +32,6 @@ BASE_DECLARE_FEATURE(kAuxiliarySearchDonation); BASE_DECLARE_FEATURE(kAvoidSelectedTabFocusOnLayoutDoneShowing); BASE_DECLARE_FEATURE(kBackGestureActivityTabProvider); -BASE_DECLARE_FEATURE(kBackGestureRefactorActivityAndroid); BASE_DECLARE_FEATURE(kBackGestureRefactorAndroid); BASE_DECLARE_FEATURE(kBackgroundThreadPool); BASE_DECLARE_FEATURE(kBlockIntentsWhileLocked); @@ -62,12 +60,7 @@ BASE_DECLARE_FEATURE(kChromeSharingHubLaunchAdjacent); BASE_DECLARE_FEATURE(kChromeSurveyNextAndroid); BASE_DECLARE_FEATURE(kCommandLineOnNonRooted); -BASE_DECLARE_FEATURE(kContextMenuEnableLensShoppingAllowlist); -BASE_DECLARE_FEATURE(kContextMenuGoogleLensChip); BASE_DECLARE_FEATURE(kContextMenuPopupForAllScreenSizes); -BASE_DECLARE_FEATURE(kContextMenuSearchWithGoogleLens); -BASE_DECLARE_FEATURE(kContextMenuShopWithGoogleLens); -BASE_DECLARE_FEATURE(kContextMenuSearchAndShopWithGoogleLens); BASE_DECLARE_FEATURE(kContextMenuTranslateWithGoogleLens); BASE_DECLARE_FEATURE(kContextualSearchDisableOnlineDetection); BASE_DECLARE_FEATURE(kContextualSearchSuppressShortView); @@ -86,7 +79,6 @@ BASE_DECLARE_FEATURE(kDynamicTopChrome); BASE_DECLARE_FEATURE(kEarlyInitializeStartupMetrics); BASE_DECLARE_FEATURE(kExperimentsForAgsa); -BASE_DECLARE_FEATURE(kExploreSites); BASE_DECLARE_FEATURE(kFocusOmniboxInIncognitoTabIntents); BASE_DECLARE_FEATURE(kGridTabSwitcherAndroidAnimations); BASE_DECLARE_FEATURE(kHideTabOnTabSwitcher);
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 8c66150..b184fc1 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
@@ -109,7 +109,6 @@ public static final String ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION_V2 = "AdaptiveButtonInTopToolbarCustomizationV2"; public static final String ADD_TO_HOMESCREEN_IPH = "AddToHomescreenIPH"; - public static final String ADVANCED_PERIPHERALS_SUPPORT = "AdvancedPeripheralsSupport"; public static final String ADVANCED_PERIPHERALS_SUPPORT_TAB_STRIP = "AdvancedPeripheralsSupportTabStrip"; public static final String ALLOW_NEW_INCOGNITO_TAB_INTENTS = "AllowNewIncognitoTabIntents"; @@ -159,8 +158,6 @@ public static final String BACK_GESTURE_ACTIVITY_TAB_PROVIDER = "BackGestureActivityTabProvider"; public static final String BACK_GESTURE_REFACTOR = "BackGestureRefactorAndroid"; - public static final String BACK_GESTURE_REFACTOR_ACTIVITY = - "BackGestureRefactorActivityAndroid"; public static final String BLOCK_INTENTS_WHILE_LOCKED = "BlockIntentsWhileLocked"; public static final String BOARDING_PASS_DETECTOR = "BoardingPassDetector"; public static final String CACHE_ACTIVITY_TASKID = "CacheActivityTaskID"; @@ -203,13 +200,8 @@ "ContextualSearchSuppressShortView"; public static final String CONTEXTUAL_SEARCH_THIN_WEB_VIEW_IMPLEMENTATION = "ContextualSearchThinWebViewImplementation"; - public static final String CONTEXT_MENU_ENABLE_LENS_SHOPPING_ALLOWLIST = - "ContextMenuEnableLensShoppingAllowlist"; - public static final String CONTEXT_MENU_GOOGLE_LENS_CHIP = "ContextMenuGoogleLensChip"; public static final String CONTEXT_MENU_POPUP_FOR_ALL_SCREEN_SIZES = "ContextMenuPopupForAllScreenSizes"; - public static final String CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS = - "ContextMenuSearchWithGoogleLens"; public static final String CONTEXT_MENU_TRANSLATE_WITH_GOOGLE_LENS = "ContextMenuTranslateWithGoogleLens"; public static final String CORMORANT = "Cormorant"; @@ -470,8 +462,6 @@ public static final CachedFlag sArchiveTabService = new CachedFlag(ARCHIVE_TAB_SERVICE, false); public static final CachedFlag sBackGestureActivityTabProvider = new CachedFlag(BACK_GESTURE_ACTIVITY_TAB_PROVIDER, false); - public static final CachedFlag sBackGestureRefactorActivityAndroid = - new CachedFlag(BACK_GESTURE_REFACTOR_ACTIVITY, false); public static final CachedFlag sBackGestureRefactorAndroid = new CachedFlag(BACK_GESTURE_REFACTOR, false); public static final CachedFlag sBlockIntentsWhileLocked = @@ -595,7 +585,6 @@ sAndroidHub, sArchiveTabService, sBackGestureActivityTabProvider, - sBackGestureRefactorActivityAndroid, sBackGestureRefactorAndroid, sBlockIntentsWhileLocked, sCctAutoTranslate,
diff --git a/chrome/browser/metrics/chrome_feature_list_creator.cc b/chrome/browser/metrics/chrome_feature_list_creator.cc index 7e1b542..ca7f431 100644 --- a/chrome/browser/metrics/chrome_feature_list_creator.cc +++ b/chrome/browser/metrics/chrome_feature_list_creator.cc
@@ -94,9 +94,6 @@ std::cref(safe_browsing::kDownloadTailoredWarnings), base::FeatureList::OVERRIDE_ENABLE_FEATURE}, {switches::kEnableDownloadWarningImprovements, - std::cref(safe_browsing::kImprovedDownloadBubbleWarnings), - base::FeatureList::OVERRIDE_ENABLE_FEATURE}, - {switches::kEnableDownloadWarningImprovements, std::cref(safe_browsing::kImprovedDownloadPageWarnings), base::FeatureList::OVERRIDE_ENABLE_FEATURE}, {switches::kEnableDownloadWarningImprovements,
diff --git a/chrome/browser/net/cert_verifier_service_browsertest.cc b/chrome/browser/net/cert_verifier_service_browsertest.cc index 1ab5c88..fdcd0ba 100644 --- a/chrome/browser/net/cert_verifier_service_browsertest.cc +++ b/chrome/browser/net/cert_verifier_service_browsertest.cc
@@ -68,6 +68,7 @@ net::EmbeddedTestServer::TYPE_HTTPS); https_test_server.SetSSLConfig( net::test_server::EmbeddedTestServer::CERT_AUTO); + https_test_server.ServeFilesFromSourceDirectory("chrome/test/data"); ASSERT_TRUE(https_test_server.Start()); // Clear test roots so that cert validation only happens with @@ -84,6 +85,97 @@ CertVerifierServiceCACertificatesPolicyTest, ::testing::Bool()); +// Testing the CADistrutedCertificates policy +class CertVerifierServiceCADistrustedCertificatesPolicyTest + : public policy::PolicyTest { + public: + void SetUpInProcessBrowserTestFixture() override { + policy::PolicyTest::SetUpInProcessBrowserTestFixture(); + + scoped_refptr<net::X509Certificate> root_cert = + net::ImportCertFromFile(net::EmbeddedTestServer::GetRootCertPemPath()); + ASSERT_TRUE(root_cert); + + std::string b64_cert = base::Base64Encode( + net::x509_util::CryptoBufferAsStringPiece(root_cert->cert_buffer())); + base::Value certs_value(base::Value::Type::LIST); + certs_value.GetList().Append(b64_cert); + policy::PolicyMap policies; + // Distrust the test server certificate + SetPolicy(&policies, policy::key::kCADistrustedCertificates, + absl::make_optional(std::move(certs_value))); + UpdateProviderPolicy(policies); + } +}; + +IN_PROC_BROWSER_TEST_F(CertVerifierServiceCADistrustedCertificatesPolicyTest, + TestPolicy) { + net::EmbeddedTestServer https_test_server( + net::EmbeddedTestServer::TYPE_HTTPS); + https_test_server.SetSSLConfig( + net::test_server::EmbeddedTestServer::CERT_AUTO); + https_test_server.ServeFilesFromSourceDirectory("chrome/test/data"); + ASSERT_TRUE(https_test_server.Start()); + + // We don't clear the test roots but the cert should still be distrusted based + // on the enterprise policy. + + ASSERT_TRUE(NavigateToUrl(https_test_server.GetURL("/simple.html"), this)); + + EXPECT_TRUE(chrome_browser_interstitials::IsShowingInterstitial( + chrome_test_utils::GetActiveWebContents(this))); +} + +class CertVerifierServiceCATrustedDistrustedCertificatesPolicyTest + : public policy::PolicyTest { + public: + void SetUpInProcessBrowserTestFixture() override { + policy::PolicyTest::SetUpInProcessBrowserTestFixture(); + + scoped_refptr<net::X509Certificate> root_cert = + net::ImportCertFromFile(net::EmbeddedTestServer::GetRootCertPemPath()); + ASSERT_TRUE(root_cert); + + std::string b64_cert = base::Base64Encode( + net::x509_util::CryptoBufferAsStringPiece(root_cert->cert_buffer())); + policy::PolicyMap policies; + // Distrust the test server certificate + { + base::Value certs_value(base::Value::Type::LIST); + certs_value.GetList().Append(b64_cert); + SetPolicy(&policies, policy::key::kCADistrustedCertificates, + absl::make_optional(std::move(certs_value))); + } + // Trust the test server certificate + { + base::Value certs_value(base::Value::Type::LIST); + certs_value.GetList().Append(b64_cert); + SetPolicy(&policies, policy::key::kCACertificates, + absl::make_optional(std::move(certs_value))); + } + UpdateProviderPolicy(policies); + } +}; + +IN_PROC_BROWSER_TEST_F( + CertVerifierServiceCATrustedDistrustedCertificatesPolicyTest, + TestDistrustOverridesTrust) { + net::EmbeddedTestServer https_test_server( + net::EmbeddedTestServer::TYPE_HTTPS); + https_test_server.SetSSLConfig( + net::test_server::EmbeddedTestServer::CERT_AUTO); + https_test_server.ServeFilesFromSourceDirectory("chrome/test/data"); + ASSERT_TRUE(https_test_server.Start()); + + // We don't clear the test roots but the cert should still be distrusted based + // on the enterprise policy. + + ASSERT_TRUE(NavigateToUrl(https_test_server.GetURL("/simple.html"), this)); + + EXPECT_TRUE(chrome_browser_interstitials::IsShowingInterstitial( + chrome_test_utils::GetActiveWebContents(this))); +} + #endif // BUILDFLAG(CHROME_CERTIFICATE_POLICIES_SUPPORTED) #if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL)
diff --git a/chrome/browser/net/cookie_policy_browsertest.cc b/chrome/browser/net/cookie_policy_browsertest.cc index 705b02f..7f50c28 100644 --- a/chrome/browser/net/cookie_policy_browsertest.cc +++ b/chrome/browser/net/cookie_policy_browsertest.cc
@@ -53,9 +53,8 @@ } bool ThirdPartyPartitionedStorageAllowedByStorageAccessAPI() { - return base::FeatureList::IsEnabled(blink::features::kStorageAccessAPI) && - base::FeatureList::IsEnabled( - net::features::kThirdPartyStoragePartitioning); + return base::FeatureList::IsEnabled( + net::features::kThirdPartyStoragePartitioning); } class CookiePolicyBrowserTest : public InProcessBrowserTest {
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index ef3a0c1..b2767c4 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -84,6 +84,10 @@ #include "services/network/public/mojom/network_service.mojom.h" #include "third_party/blink/public/common/features.h" +#if BUILDFLAG(CHROME_CERTIFICATE_POLICIES_SUPPORTED) +#include "net/cert/asn1_util.h" +#endif + #if BUILDFLAG(IS_CHROMEOS) #include "chrome/browser/certificate_provider/certificate_provider.h" #include "chrome/browser/certificate_provider/certificate_provider_service.h" @@ -211,27 +215,16 @@ }); } -// `kPermissionStorageAccessAPI` enables feature: Storage Access API with -// Prompts (https://chromestatus.com/feature/5085655327047680). StorageAccessAPI -// is considered enabled when either feature is enabled (by different field -// trial studies). -bool StorageAccessAPIEnabled() { - return base::FeatureList::IsEnabled(blink::features::kStorageAccessAPI) || - base::FeatureList::IsEnabled( - permissions::features::kPermissionStorageAccessAPI); -} - // TODO(crbug.com/1385156): Separate the two flags entirely. bool TopLevelStorageAccessAPIEnabled() { - return base::FeatureList::IsEnabled(blink::features::kStorageAccessAPI) && - base::FeatureList::IsEnabled( - blink::features::kStorageAccessAPIForOriginExtension); + return base::FeatureList::IsEnabled( + blink::features::kStorageAccessAPIForOriginExtension); } bool IsContentSettingsTypeEnabled(ContentSettingsType type) { switch (type) { case ContentSettingsType::STORAGE_ACCESS: - return StorageAccessAPIEnabled(); + return true; case ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS: return TopLevelStorageAccessAPIEnabled(); default: @@ -307,6 +300,11 @@ &ProfileNetworkContextService::ScheduleUpdateCertificatePolicy, base::Unretained(this))); + pref_change_registrar_.Add( + prefs::kCADistrustedCertificates, + base::BindRepeating( + &ProfileNetworkContextService::ScheduleUpdateCertificatePolicy, + base::Unretained(this))); #endif pref_change_registrar_.Add( @@ -380,6 +378,7 @@ registry->RegisterListPref(prefs::kHSTSPolicyBypassList); #if BUILDFLAG(CHROME_CERTIFICATE_POLICIES_SUPPORTED) registry->RegisterListPref(prefs::kCACertificates); + registry->RegisterListPref(prefs::kCADistrustedCertificates); #endif } @@ -535,6 +534,7 @@ ProfileNetworkContextService::GetCertificatePolicy() { net::CertificateList additional_untrusted_anchors; net::CertificateList additional_trust_anchors; + std::vector<std::vector<uint8_t>> additional_distrusted_spkis; auto* prefs = profile_->GetPrefs(); for (const base::Value& cert_b64 : prefs->GetList(prefs::kCACertificates)) { @@ -556,9 +556,24 @@ } } + for (const base::Value& cert_b64 : + prefs->GetList(prefs::kCADistrustedCertificates)) { + std::string decoded; + if (!base::Base64Decode(cert_b64.GetString(), &decoded)) { + continue; + } + base::StringPiece spki_piece; + bool success = net::asn1::ExtractSPKIFromDERCert(decoded, &spki_piece); + if (success) { + additional_distrusted_spkis.push_back( + std::vector<uint8_t>(spki_piece.begin(), spki_piece.end())); + } + } + return cert_verifier::mojom::AdditionalCertificates::New( std::move(additional_untrusted_anchors), - std::move(additional_trust_anchors)); + std::move(additional_trust_anchors), + std::move(additional_distrusted_spkis)); } void ProfileNetworkContextService::UpdateCertificatePolicy() {
diff --git a/chrome/browser/page_load_metrics/observers/third_party_cookie_deprecation_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/third_party_cookie_deprecation_metrics_observer_browsertest.cc index 03413859..7d084b1 100644 --- a/chrome/browser/page_load_metrics/observers/third_party_cookie_deprecation_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/third_party_cookie_deprecation_metrics_observer_browsertest.cc
@@ -966,8 +966,7 @@ scoped_feature_list_.InitWithFeaturesAndParameters( {{features::kCookieDeprecationFacilitatedTesting, {{tpcd::experiment::kDisable3PCookiesName, "true"}}}, - {content_settings::features::kTrackingProtection3pcd, {}}, - {blink::features::kStorageAccessAPI, {}}}, + {content_settings::features::kTrackingProtection3pcd, {}}}, {}); subresource_filter::SubresourceFilterBrowserTest::SetUp(); }
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java index 10fc6878..3e1c0dd 100644 --- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java +++ b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordManagerHelper.java
@@ -6,6 +6,7 @@ import static org.chromium.chrome.browser.flags.ChromeFeatureList.PASSKEY_MANAGEMENT_USING_ACCOUNT_SETTINGS_ANDROID; +import android.app.Activity; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; import android.content.Context; @@ -24,6 +25,7 @@ import com.google.android.gms.common.api.ApiException; import org.chromium.base.Callback; +import org.chromium.base.ContextUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -47,10 +49,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.Optional; -/** - * A helper class for showing PasswordSettings. - * TODO(crbug.com/1345232): Split up this class - **/ +/** A helper class for showing PasswordSettings. TODO(crbug.com/1345232): Split up this class */ public class PasswordManagerHelper { // Key for the argument with which PasswordsSettings will be launched. The value for // this argument should be part of the ManagePasswordsReferrer enum, which contains @@ -119,11 +118,10 @@ "PasswordManager.PasswordCheckup.Launch.Success"; /** - * The identifier of the loading dialog outcome. + * The identifier of the loading dialog outcome. * - * These values are persisted to logs. Entries should not be renumbered and - * numeric values should never be reused. - * Please, keep in sync with tools/metrics/histograms/enums.xml. + * <p>These values are persisted to logs. Entries should not be renumbered and numeric values + * should never be reused. Please, keep in sync with tools/metrics/histograms/enums.xml. */ @VisibleForTesting @IntDef({ @@ -138,7 +136,7 @@ /** The loading dialog was requested but loading finished before it got shown. */ int NOT_SHOWN_LOADED = 0; - /** The loading dialog was shown, loading process finished. */ + /** The loading dialog was shown, loading process finished. */ int SHOWN_LOADED = 1; /** The loading dialog was shown and cancelled by user before loading finished. */ @@ -156,7 +154,7 @@ * * @param context used to show the UI to manage passwords. * @param managePasskeys indicates whether passkey management is needed, which when true will - * attempt to launch the credential manager even without syncing enabled. + * attempt to launch the credential manager even without syncing enabled. */ public static void showPasswordSettings( Context context, @@ -202,7 +200,11 @@ (syncService != null) ? CoreAccountInfo.getEmailFrom(syncService.getAccountInfo()) : ""; - credentialManagerLauncher.getAccountSettingsIntent(accountName, context::startActivity); + // TODO(crbug.com/1507785): Find an alternative to account settings intent. + Activity activity = ContextUtils.activityFromContext(context); + if (activity == null) return; + credentialManagerLauncher.getAccountSettingsIntent( + accountName, (intent) -> activity.startActivityForResult(intent, 0)); return; } @@ -214,15 +216,15 @@ } /** - * Checks the availability and status of the UPM feature. - * All clients should check this before trying to use UPM methods. - * Checks for the UPM to be anabled and downstream backend to be available. + * Checks the availability and status of the UPM feature. All clients should check this before + * trying to use UPM methods. Checks for the UPM to be anabled and downstream backend to be + * available. * - * TODO(crbug.com/1327294): Make sure we rely on the same util in all places that need - * to check whether UPM can be used (for password check as well as for all other cases that - * share the same preconditions, e.g. launching the credential manager). + * <p>TODO(crbug.com/1327294): Make sure we rely on the same util in all places that need to + * check whether UPM can be used (for password check as well as for all other cases that share + * the same preconditions, e.g. launching the credential manager). * - * TODO(crbug.com/1345232): pass syncService and prefService instances as parameters + * <p>TODO(crbug.com/1345232): pass syncService and prefService instances as parameters * * @return True if Unified Password Manager can be used, false otherwise. */ @@ -240,12 +242,12 @@ } /** - * Checks the ability to use an AccountSettings intent to launch the password manager. - * This provides a fallback for users who attempt to manage passkeys when UPM is not - * available. Passkeys cannot be managed from the Chrome password settings page. + * Checks the ability to use an AccountSettings intent to launch the password manager. This + * provides a fallback for users who attempt to manage passkeys when UPM is not available. + * Passkeys cannot be managed from the Chrome password settings page. * - * Since there is not necessarily a signed in Chrome user, the intent might show an - * account chooser before showing the password manager. + * <p>Since there is not necessarily a signed in Chrome user, the intent might show an account + * chooser before showing the password manager. * * @return True if the AccountSettings intent is available for use, false otherwise. */ @@ -289,12 +291,12 @@ } /** - * Asynchronously runs Password Checkup in GMS Core and stores the result in - * PasswordSpecifics then saves it to the ChromeSync module. + * Asynchronously runs Password Checkup in GMS Core and stores the result in PasswordSpecifics + * then saves it to the ChromeSync module. * * @param referrer the place that requested to start a check. * @param accountName the account name that is syncing passwords. If no value was provided, the - * local account will be used + * local account will be used * @param successCallback callback called when password check finishes successfully * @param failureCallback callback called if password check encountered an error */ @@ -335,7 +337,7 @@ * * @param referrer the place that requested number of breached credentials. * @param accountName the account name that is syncing passwords. If no value was provided, the - * local account will be used. + * local account will be used. * @param successCallback callback called with the number of breached passwords. * @param failureCallback callback called if encountered an error. */ @@ -372,8 +374,8 @@ } /** - * Checks whether the sync feature is enabled and the user has chosen to sync passwords. - * Note that this doesn't mean that passwords are actively syncing. + * Checks whether the sync feature is enabled and the user has chosen to sync passwords. Note + * that this doesn't mean that passwords are actively syncing. * * @param syncService the service to query about the sync status. * @return true if syncing passwords is enabled @@ -385,12 +387,11 @@ } /** - * Checks whether the sync feature is enabled, the user has chosen to sync passwords and - * they haven't set up a custom passphrase. - * The caller should make sure that the sync engine is initialized before calling this - * method. + * Checks whether the sync feature is enabled, the user has chosen to sync passwords and they + * haven't set up a custom passphrase. The caller should make sure that the sync engine is + * initialized before calling this method. * - * Note that this doesn't mean that passwords are actively syncing. + * <p>Note that this doesn't mean that passwords are actively syncing. * * @param syncService the service to query about the sync status. * @return true if syncing passwords is enabled without custom passphrase. @@ -402,9 +403,8 @@ } /** - * Checks whether the user is actively syncing passwords without a custom passphrase. - * The caller should make sure that the sync engine is initialized before calling this - * method. + * Checks whether the user is actively syncing passwords without a custom passphrase. The caller + * should make sure that the sync engine is initialized before calling this method. * * @param syncService the service to query about the sync status. * @return true if actively syncing passwords and no custom passphrase was set. @@ -626,9 +626,8 @@ } /** - * Launches the pending intent and reports metrics if the loading dialog was not cancelled - * or timed out. Intent launch metric is not recorded if the loading was cancelled or timed - * out. + * Launches the pending intent and reports metrics if the loading dialog was not cancelled or + * timed out. Intent launch metric is not recorded if the loading was cancelled or timed out. * * @param loadingDialogCoordinator {@link LoadingModalDialogCoordinator}. * @param intent {@link PendingIntent} to be launched.
diff --git a/chrome/browser/performance_manager/DEPS b/chrome/browser/performance_manager/DEPS index a02f9a1e..3538eca2 100644 --- a/chrome/browser/performance_manager/DEPS +++ b/chrome/browser/performance_manager/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+components/performance_manager", + "+components/system_cpu", "+chromeos/ash/components/memory", "+dbus" ]
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h b/chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h deleted file mode 100644 index 671ed53..0000000 --- a/chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_PRESSURE_SAMPLE_H_ -#define CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_PRESSURE_SAMPLE_H_ - -namespace performance_manager::metrics { - -// Represents availability of compute resources measured over a period of time. -struct PressureSample { - // Average utilization of all CPU cores. - // - // Values use a scale from 0.0 (no utilization) to 1.0 (100% utilization). - double cpu_utilization; -}; - -} // namespace performance_manager::metrics - -#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_PRESSURE_SAMPLE_H_
diff --git a/chrome/browser/performance_manager/metrics/page_resource_monitor.cc b/chrome/browser/performance_manager/metrics/page_resource_monitor.cc index 59f3d277..a2ccf77 100644 --- a/chrome/browser/performance_manager/metrics/page_resource_monitor.cc +++ b/chrome/browser/performance_manager/metrics/page_resource_monitor.cc
@@ -26,10 +26,10 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "build/build_config.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h" #include "components/performance_manager/public/features.h" #include "components/performance_manager/public/graph/page_node.h" #include "components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h" +#include "components/system_cpu/cpu_probe.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "services/metrics/public/cpp/ukm_source_id.h" @@ -39,6 +39,8 @@ namespace { +using system_cpu::CpuProbe; +using system_cpu::PressureSample; using PageMeasurementBackgroundState = PageResourceMonitor::PageMeasurementBackgroundState;
diff --git a/chrome/browser/performance_manager/metrics/page_resource_monitor.h b/chrome/browser/performance_manager/metrics/page_resource_monitor.h index a4765c9..a57a12e6 100644 --- a/chrome/browser/performance_manager/metrics/page_resource_monitor.h +++ b/chrome/browser/performance_manager/metrics/page_resource_monitor.h
@@ -15,15 +15,18 @@ #include "base/sequence_checker.h" #include "base/time/time.h" #include "base/timer/timer.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h" #include "chrome/browser/performance_manager/metrics/page_resource_cpu_monitor.h" #include "components/performance_manager/public/graph/graph.h" #include "components/performance_manager/public/resource_attribution/page_context.h" +#include "components/system_cpu/pressure_sample.h" #include "third_party/abseil-cpp/absl/types/optional.h" +namespace system_cpu { +class CpuProbe; +} + namespace performance_manager::metrics { -class CpuProbe; class PageResourceMonitorUnitTest; // Periodically reports tab resource usage via UKM. @@ -75,8 +78,9 @@ // Invoked asynchronously from CollectPageResourceUsage() when measurements // are ready. - void OnPageResourceUsageResult(const PageCPUUsageVector& page_cpu_usage, - absl::optional<PressureSample> system_cpu); + void OnPageResourceUsageResult( + const PageCPUUsageVector& page_cpu_usage, + absl::optional<system_cpu::PressureSample> system_cpu); // Asynchronously checks if the CPU metrics are still above the threshold // after a delay. @@ -86,12 +90,12 @@ // measurements are ready. void OnDelayedCPUInterventionMetricsResult( const PageCPUUsageVector& page_cpu_usage, - absl::optional<PressureSample> system_cpu); + absl::optional<system_cpu::PressureSample> system_cpu); // Log CPU intervention metrics with the provided suffix. void LogCPUInterventionMetrics( const PageCPUUsageVector& page_cpu_usage, - const absl::optional<PressureSample>& system_cpu, + const absl::optional<system_cpu::PressureSample>& system_cpu, const base::TimeTicks now, CPUInterventionSuffix histogram_suffix); @@ -103,7 +107,8 @@ void CalculatePageCPUUsage( bool use_delayed_system_cpu_probe, base::OnceCallback<void(const PageCPUUsageVector&, - absl::optional<PressureSample>)> callback); + absl::optional<system_cpu::PressureSample>)> + callback); // Invoked asynchronously from CalculatePageCPUUsage() when page CPU // measurements are ready. Converts the measurements in `cpu_usage_map` @@ -114,7 +119,8 @@ void OnPageCPUUsageResult( bool use_delayed_system_cpu_probe, base::OnceCallback<void(const PageCPUUsageVector&, - absl::optional<PressureSample>)> callback, + absl::optional<system_cpu::PressureSample>)> + callback, const PageResourceCPUMonitor::CPUUsageMap& cpu_usage_map); // If this is called, CollectPageResourceUsage() will not be called on a @@ -151,9 +157,9 @@ PageResourceCPUMonitor cpu_monitor_ GUARDED_BY_CONTEXT(sequence_checker_); // Helpers to take system CPU measurements for UMA. - std::unique_ptr<CpuProbe> system_cpu_probe_ + std::unique_ptr<system_cpu::CpuProbe> system_cpu_probe_ GUARDED_BY_CONTEXT(sequence_checker_); - std::unique_ptr<CpuProbe> delayed_system_cpu_probe_ + std::unique_ptr<system_cpu::CpuProbe> delayed_system_cpu_probe_ GUARDED_BY_CONTEXT(sequence_checker_); // WeakPtrFactory for the RepeatingTimer to call a method on this object.
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 1153b338..6675ae2b 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -2069,6 +2069,9 @@ { key::kCACertificates, prefs::kCACertificates, base::Value::Type::LIST }, + { key::kCADistrustedCertificates, + prefs::kCADistrustedCertificates, + base::Value::Type::LIST }, #endif // BUILDFLAG(CHROME_CERTIFICATE_POLICIES_SUPPORTED) }; // clang-format on
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 90c8bd9..f80beb38 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -955,6 +955,10 @@ constexpr char kIsolatedWebAppsEnabled[] = "ash.isolated_web_apps_enabled"; #endif // BUILDFLAG(IS_CHROMEOS_ASH) +// Deprecated 12/2023. +const char kPrivacyBudgetReportedReidBlocks[] = + "privacy_budget.reported_reid_blocks"; + // Register local state used only for migration (clearing or moving to a new // key). void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) { @@ -1075,6 +1079,9 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) registry->RegisterBooleanPref(kIsolatedWebAppsEnabled, false); #endif + + // Deprecated 12/2023 + registry->RegisterStringPref(kPrivacyBudgetReportedReidBlocks, std::string()); } // Register prefs used only for migration (clearing or moving to a new key). @@ -2216,6 +2223,9 @@ local_state->ClearPref(kIsolatedWebAppsEnabled); #endif + // Added 12/2023 + local_state->ClearPref(kPrivacyBudgetReportedReidBlocks); + // Please don't delete the following line. It is used by PRESUBMIT.py. // END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS
diff --git a/chrome/browser/privacy_budget/BUILD.gn b/chrome/browser/privacy_budget/BUILD.gn index 0af2b7f..752cb27 100644 --- a/chrome/browser/privacy_budget/BUILD.gn +++ b/chrome/browser/privacy_budget/BUILD.gn
@@ -10,7 +10,6 @@ "mesa_distribution.h", "privacy_budget_metrics_provider.h", "privacy_budget_prefs.h", - "privacy_budget_reid_score_estimator.h", "privacy_budget_ukm_entry_filter.h", "representative_surface_set.h", "surface_set_equivalence.h", @@ -35,7 +34,6 @@ "identifiability_study_state.cc", "privacy_budget_metrics_provider.cc", "privacy_budget_prefs.cc", - "privacy_budget_reid_score_estimator.cc", "privacy_budget_ukm_entry_filter.cc", "representative_surface_set.cc", "surface_set_equivalence.cc", @@ -71,7 +69,6 @@ "inspectable_identifiability_study_state.h", "mesa_distribution_unittest.cc", "privacy_budget_metrics_provider_unittest.cc", - "privacy_budget_reid_score_estimator_unittest.cc", "privacy_budget_ukm_entry_filter_unittest.cc", "representative_surface_set_unittest.cc", "surface_set_equivalence_unittest.cc", @@ -99,7 +96,6 @@ "privacy_budget_browsertest.cc", "privacy_budget_browsertest_util.cc", "privacy_budget_browsertest_util.h", - "privacy_budget_reid_score_browsertest.cc", ] defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
diff --git a/chrome/browser/privacy_budget/identifiability_study_group_settings.cc b/chrome/browser/privacy_budget/identifiability_study_group_settings.cc index e5b2db5..ca7e399 100644 --- a/chrome/browser/privacy_budget/identifiability_study_group_settings.cc +++ b/chrome/browser/privacy_budget/identifiability_study_group_settings.cc
@@ -26,17 +26,12 @@ // static IdentifiabilityStudyGroupSettings IdentifiabilityStudyGroupSettings::InitFromFeatureParams() { - return InitFrom( - base::FeatureList::IsEnabled(features::kIdentifiabilityStudy), - features::kIdentifiabilityStudyExpectedSurfaceCount.Get(), - features::kIdentifiabilityStudyActiveSurfaceBudget.Get(), - features::kIdentifiabilityStudyBlocks.Get(), - features::kIdentifiabilityStudyBlockWeights.Get(), - features::kIdentifiabilityStudyAllowedRandomTypes.Get(), - features::kIdentifiabilityStudyReidSurfaceBlocks.Get(), - features::kIdentifiabilityStudyReidSurfaceBlocksSaltsRanges.Get(), - features::kIdentifiabilityStudyReidSurfaceBlocksBits.Get(), - features::kIdentifiabilityStudyReidBlocksNoiseProbabilities.Get()); + return InitFrom(base::FeatureList::IsEnabled(features::kIdentifiabilityStudy), + features::kIdentifiabilityStudyExpectedSurfaceCount.Get(), + features::kIdentifiabilityStudyActiveSurfaceBudget.Get(), + features::kIdentifiabilityStudyBlocks.Get(), + features::kIdentifiabilityStudyBlockWeights.Get(), + features::kIdentifiabilityStudyAllowedRandomTypes.Get()); } // static @@ -46,24 +41,13 @@ int surface_budget, const std::string& blocks, const std::string& blocks_weights, - const std::string& allowed_random_types, - const std::string& reid_blocks, - const std::string& reid_blocks_salts_ranges, - const std::string& reid_blocks_bits, - const std::string& reid_blocks_noise_probabilities) { + const std::string& allowed_random_types) { return IdentifiabilityStudyGroupSettings( enabled, expected_surface_count, surface_budget, DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceBlocks>(blocks), DecodeIdentifiabilityFieldTrialParam<std::vector<double>>(blocks_weights), DecodeIdentifiabilityFieldTrialParam< - std::vector<blink::IdentifiableSurface::Type>>(allowed_random_types), - DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceBlocks>( - reid_blocks), - DecodeIdentifiabilityFieldTrialParam<std::vector<uint64_t>>( - reid_blocks_salts_ranges), - DecodeIdentifiabilityFieldTrialParam<std::vector<int>>(reid_blocks_bits), - DecodeIdentifiabilityFieldTrialParam<std::vector<double>>( - reid_blocks_noise_probabilities)); + std::vector<blink::IdentifiableSurface::Type>>(allowed_random_types)); } IdentifiabilityStudyGroupSettings::IdentifiabilityStudyGroupSettings( @@ -72,11 +56,7 @@ int surface_budget, IdentifiableSurfaceBlocks blocks, std::vector<double> blocks_weights, - std::vector<blink::IdentifiableSurface::Type> allowed_random_types, - IdentifiableSurfaceBlocks reid_blocks, - std::vector<uint64_t> reid_blocks_salts_ranges, - std::vector<int> reid_blocks_bits, - std::vector<double> reid_blocks_noise_probabilities) + std::vector<blink::IdentifiableSurface::Type> allowed_random_types) : enabled_(enabled), expected_surface_count_(std::clamp<int>( expected_surface_count, @@ -88,11 +68,6 @@ features::kMaxIdentifiabilityStudyActiveSurfaceBudget)), blocks_(std::move(blocks)), blocks_weights_(std::move(blocks_weights)), - reid_blocks_(std::move(reid_blocks)), - reid_blocks_salts_ranges_(std::move(reid_blocks_salts_ranges)), - reid_blocks_bits_(std::move(reid_blocks_bits)), - reid_blocks_noise_probabilities_( - std::move(reid_blocks_noise_probabilities)), allowed_random_types_(std::move(allowed_random_types)) { bool validates = Validate(); UmaHistogramFinchConfigValidation(validates); @@ -110,17 +85,14 @@ if (!enabled_) return true; // If the study is enabled, at least one of assigned-block-sampling or - // reid-score-estimation or random-surface-assignment should be enabled. - if (!IsUsingAssignedBlockSampling() && !IsUsingReidScoreEstimator() && - !IsUsingRandomSampling()) { + // random-surface-assignment should be enabled. + if (!IsUsingAssignedBlockSampling() && !IsUsingRandomSampling()) { return false; } if (IsUsingAssignedBlockSampling() && IsUsingRandomSampling()) return false; if (IsUsingAssignedBlockSampling() && !ValidateAssignedBlockSampling()) return false; - if (IsUsingReidScoreEstimator() && !ValidateReidBlockEstimator()) - return false; return true; } @@ -161,26 +133,6 @@ return true; } -bool IdentifiabilityStudyGroupSettings::ValidateReidBlockEstimator() { - if (reid_blocks_salts_ranges_.size() != reid_blocks_.size() || - reid_blocks_bits_.size() != reid_blocks_.size() || - reid_blocks_noise_probabilities_.size() != reid_blocks_.size()) - return false; - bool valid_params = - base::ranges::all_of(reid_blocks_salts_ranges_, - [](uint64_t salt_range) { return salt_range > 0; }); - valid_params = valid_params && - base::ranges::all_of(reid_blocks_bits_, [](int reid_bits) { - return reid_bits > 0 && reid_bits <= 32; - }); - - return valid_params && base::ranges::all_of(reid_blocks_noise_probabilities_, - [](double reid_noise) { - return reid_noise >= 0 && - reid_noise <= 1; - }); -} - const IdentifiableSurfaceBlocks& IdentifiabilityStudyGroupSettings::blocks() const { return blocks_; @@ -191,26 +143,6 @@ return blocks_weights_; } -const std::vector<uint64_t>& -IdentifiabilityStudyGroupSettings::reid_blocks_salts_ranges() const { - return reid_blocks_salts_ranges_; -} - -const std::vector<int>& IdentifiabilityStudyGroupSettings::reid_blocks_bits() - const { - return reid_blocks_bits_; -} - -const std::vector<double>& -IdentifiabilityStudyGroupSettings::reid_blocks_noise_probabilities() const { - return reid_blocks_noise_probabilities_; -} - -const IdentifiableSurfaceBlocks& -IdentifiabilityStudyGroupSettings::reid_blocks() const { - return reid_blocks_; -} - const std::vector<blink::IdentifiableSurface::Type>& IdentifiabilityStudyGroupSettings::allowed_random_types() const { return allowed_random_types_; @@ -224,10 +156,6 @@ return expected_surface_count() > 0; } -bool IdentifiabilityStudyGroupSettings::IsUsingReidScoreEstimator() const { - return !reid_blocks().empty(); -} - bool IdentifiabilityStudyGroupSettings::IsUsingSamplingOfSurfaces() const { // Random and assigned block sampling are mutually exclusive. DCHECK(!IsUsingRandomSampling() || !IsUsingAssignedBlockSampling());
diff --git a/chrome/browser/privacy_budget/identifiability_study_group_settings.h b/chrome/browser/privacy_budget/identifiability_study_group_settings.h index 9a916514..5b37c65 100644 --- a/chrome/browser/privacy_budget/identifiability_study_group_settings.h +++ b/chrome/browser/privacy_budget/identifiability_study_group_settings.h
@@ -25,11 +25,7 @@ int surface_budget, const std::string& blocks, const std::string& blocks_weights, - const std::string& allowed_random_types, - const std::string& reid_blocks, - const std::string& reid_blocks_salts_ranges, - const std::string& reid_blocks_bits, - const std::string& reid_blocks_noise_probabilities); + const std::string& allowed_random_types); IdentifiabilityStudyGroupSettings(const IdentifiabilityStudyGroupSettings&) = delete; @@ -46,18 +42,13 @@ bool IsUsingAssignedBlockSampling() const; bool IsUsingRandomSampling() const; - bool IsUsingReidScoreEstimator() const; // Whether the study is using one of the sampling strategies (random or block // assignment). bool IsUsingSamplingOfSurfaces() const; const IdentifiableSurfaceBlocks& blocks() const; - const IdentifiableSurfaceBlocks& reid_blocks() const; const std::vector<double>& blocks_weights() const; - const std::vector<uint64_t>& reid_blocks_salts_ranges() const; - const std::vector<int>& reid_blocks_bits() const; - const std::vector<double>& reid_blocks_noise_probabilities() const; const std::vector<blink::IdentifiableSurface::Type>& allowed_random_types() const; @@ -71,15 +62,10 @@ int surface_budget, IdentifiableSurfaceBlocks blocks, std::vector<double> blocks_weights, - std::vector<blink::IdentifiableSurface::Type> allowed_random_types, - IdentifiableSurfaceBlocks reid_blocks, - std::vector<uint64_t> reid_blocks_salts_ranges, - std::vector<int> reid_blocks_bits, - std::vector<double> reid_blocks_noise_probabilities); + std::vector<blink::IdentifiableSurface::Type> allowed_random_types); bool Validate(); bool ValidateAssignedBlockSampling(); - bool ValidateReidBlockEstimator(); // True if identifiability study is enabled. If this field is false, then none // of the other values are applicable. @@ -93,14 +79,6 @@ const std::vector<double> blocks_weights_; - const IdentifiableSurfaceBlocks reid_blocks_; - - const std::vector<uint64_t> reid_blocks_salts_ranges_; - - const std::vector<int> reid_blocks_bits_; - - const std::vector<double> reid_blocks_noise_probabilities_; - // Surface types to sample from when random surface sampling is enabled. If // this vector is empty all surface types are allowed to be sampled. const std::vector<blink::IdentifiableSurface::Type> allowed_random_types_;
diff --git a/chrome/browser/privacy_budget/identifiability_study_group_settings_unittest.cc b/chrome/browser/privacy_budget/identifiability_study_group_settings_unittest.cc index 63a5343..8be4512 100644 --- a/chrome/browser/privacy_budget/identifiability_study_group_settings_unittest.cc +++ b/chrome/browser/privacy_budget/identifiability_study_group_settings_unittest.cc
@@ -13,32 +13,32 @@ }; TEST_F(IdentifiabilityStudyGroupSettingsTest, Disabled) { - auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - false, 0, 0, "", "", "", "", "", "", ""); + auto settings = + IdentifiabilityStudyGroupSettings::InitFrom(false, 0, 0, "", "", ""); EXPECT_FALSE(settings.enabled()); histogram_tester.ExpectUniqueSample( "PrivacyBudget.Identifiability.FinchConfigValidationResult", true, 1); } TEST_F(IdentifiabilityStudyGroupSettingsTest, DisabledWithParams) { - auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - false, 10, 40, "", "", "", "", "", "", ""); + auto settings = + IdentifiabilityStudyGroupSettings::InitFrom(false, 10, 40, "", "", ""); EXPECT_FALSE(settings.enabled()); histogram_tester.ExpectUniqueSample( "PrivacyBudget.Identifiability.FinchConfigValidationResult", true, 1); } TEST_F(IdentifiabilityStudyGroupSettingsTest, DisabledBySurfaceCountZero) { - auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - true, 0, 40, "", "", "", "", "", "", ""); + auto settings = + IdentifiabilityStudyGroupSettings::InitFrom(true, 0, 40, "", "", ""); EXPECT_FALSE(settings.enabled()); histogram_tester.ExpectUniqueSample( "PrivacyBudget.Identifiability.FinchConfigValidationResult", false, 1); } TEST_F(IdentifiabilityStudyGroupSettingsTest, ValidRandomSurfaceSampling) { - auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - true, 10, 40, "", "", "1,4", "", "", "", ""); + auto settings = + IdentifiabilityStudyGroupSettings::InitFrom(true, 10, 40, "", "", "1,4"); EXPECT_TRUE(settings.enabled()); EXPECT_FALSE(settings.IsUsingAssignedBlockSampling()); EXPECT_TRUE(settings.IsUsingRandomSampling()); @@ -56,7 +56,7 @@ TEST_F(IdentifiabilityStudyGroupSettingsTest, ValidAssignedBlockSampling) { auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - true, 0, 0, "1;2,3;4,5;6", "1,1,1", "", "", "", "", ""); + true, 0, 0, "1;2,3;4,5;6", "1,1,1", ""); EXPECT_TRUE(settings.enabled()); EXPECT_TRUE(settings.IsUsingAssignedBlockSampling()); EXPECT_FALSE(settings.IsUsingRandomSampling()); @@ -67,7 +67,7 @@ TEST_F(IdentifiabilityStudyGroupSettingsTest, InvalidNegativeWeight) { auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - true, 0, 0, "1;2,3;4,5;6", "-1,1,1", "", "", "", "", ""); + true, 0, 0, "1;2,3;4,5;6", "-1,1,1", ""); EXPECT_FALSE(settings.enabled()); histogram_tester.ExpectUniqueSample( "PrivacyBudget.Identifiability.FinchConfigValidationResult", false, 1); @@ -75,25 +75,7 @@ TEST_F(IdentifiabilityStudyGroupSettingsTest, InvalidSurfaceTooLikely) { auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - true, 0, 0, "1;2,1;4,5;6", "1,1,1", "", "", "", "", ""); - EXPECT_FALSE(settings.enabled()); - histogram_tester.ExpectUniqueSample( - "PrivacyBudget.Identifiability.FinchConfigValidationResult", false, 1); -} - -TEST_F(IdentifiabilityStudyGroupSettingsTest, EnableSettingsForValidReidBlock) { - auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - true, 0, 0, "", "", "", "1;2,4;5;6", "2,2", "2,3", "0.1,0.2"); - EXPECT_TRUE(settings.IsUsingReidScoreEstimator()); - EXPECT_FALSE(settings.IsUsingSamplingOfSurfaces()); - EXPECT_TRUE(settings.enabled()); - histogram_tester.ExpectUniqueSample( - "PrivacyBudget.Identifiability.FinchConfigValidationResult", true, 1); -} - -TEST_F(IdentifiabilityStudyGroupSettingsTest, InvalidReidBlocks) { - auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - true, 0, 0, "", "", "", "1;2,4;5;6", "2", "2,3", "0.1,0.2"); + true, 0, 0, "1;2,1;4,5;6", "1,1,1", ""); EXPECT_FALSE(settings.enabled()); histogram_tester.ExpectUniqueSample( "PrivacyBudget.Identifiability.FinchConfigValidationResult", false, 1);
diff --git a/chrome/browser/privacy_budget/identifiability_study_state.cc b/chrome/browser/privacy_budget/identifiability_study_state.cc index 442fe44..44a5551 100644 --- a/chrome/browser/privacy_budget/identifiability_study_state.cc +++ b/chrome/browser/privacy_budget/identifiability_study_state.cc
@@ -24,7 +24,6 @@ #include "base/ranges/algorithm.h" #include "chrome/browser/privacy_budget/identifiability_study_group_settings.h" #include "chrome/browser/privacy_budget/privacy_budget_prefs.h" -#include "chrome/browser/privacy_budget/privacy_budget_reid_score_estimator.h" #include "chrome/browser/privacy_budget/representative_surface_set.h" #include "chrome/browser/privacy_budget/surface_set_equivalence.h" #include "chrome/common/privacy_budget/field_trial_param_conversions.h" @@ -64,9 +63,7 @@ // bigger than 0. : 1, kMesaDistributionRatio, - kMesaDistributionGeometricDistributionParam), - reid_estimator_( - PrivacyBudgetReidScoreEstimator(&settings_, pref_service)) { + kMesaDistributionGeometricDistributionParam) { InitializeGlobalStudySettings(); InitFromPrefs(); } @@ -87,11 +84,6 @@ if (surface.GetType() == blink::IdentifiableSurface::Type::kReservedInternal) return true; - if (surface.GetType() == - blink::IdentifiableSurface::Type::kReidScoreEstimator) { - return settings_.IsUsingReidScoreEstimator(); - } - // All other surfaces should be recorded only when sampling. if (!settings_.IsUsingSamplingOfSurfaces()) return false; @@ -342,7 +334,6 @@ void IdentifiabilityStudyState::ResetPersistedState() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - reid_estimator_.ResetPersistedState(); ResetInMemoryState(); @@ -507,8 +498,6 @@ return; } - reid_estimator_.Init(); - if (settings_.IsUsingAssignedBlockSampling()) { InitStateForAssignedBlockSampling(); } @@ -520,14 +509,6 @@ CheckInvariants(); } -void IdentifiabilityStudyState::MaybeStoreValueForComputingReidScore( - blink::IdentifiableSurface surface, - blink::IdentifiableToken token) { - if (!settings_.IsUsingReidScoreEstimator()) - return; - reid_estimator_.ProcessForReidScore(surface, token); -} - void IdentifiabilityStudyState::InitStateForRandomSurfaceSampling() { DCHECK(settings_.IsUsingRandomSampling()); ResetInMemoryState();
diff --git a/chrome/browser/privacy_budget/identifiability_study_state.h b/chrome/browser/privacy_budget/identifiability_study_state.h index 2f520f2..49fd7d285 100644 --- a/chrome/browser/privacy_budget/identifiability_study_state.h +++ b/chrome/browser/privacy_budget/identifiability_study_state.h
@@ -19,7 +19,6 @@ #include "chrome/browser/privacy_budget/encountered_surface_tracker.h" #include "chrome/browser/privacy_budget/mesa_distribution.h" #include "chrome/browser/privacy_budget/privacy_budget_prefs.h" -#include "chrome/browser/privacy_budget/privacy_budget_reid_score_estimator.h" #include "chrome/browser/privacy_budget/representative_surface_set.h" #include "chrome/browser/privacy_budget/surface_set_equivalence.h" #include "chrome/browser/privacy_budget/surface_set_valuation.h" @@ -112,11 +111,6 @@ // Initializes from fields persisted in `pref_service_`. void InitFromPrefs(); - // Checks if this surface is part of a set of surfaces we want to estimate the - // Reid score of. If so, stores its value for later estimation. - void MaybeStoreValueForComputingReidScore(blink::IdentifiableSurface surface, - blink::IdentifiableToken token); - // The largest offset that we can select. At worst `seen_surfaces_` must keep // track of this many (+1) surfaces. This value is approximately based on the // 90ᵗʰ percentile surface encounter rate as measured in June 2021. @@ -387,10 +381,6 @@ // Where kSettings is the PrivacyBudgetSettingsProvider singleton. EncounteredSurfaceTracker surface_encounters_; - // Keeps track of the list of surfaces for which we need to estimate the Reid - // score. - PrivacyBudgetReidScoreEstimator reid_estimator_; - SEQUENCE_CHECKER(sequence_checker_); };
diff --git a/chrome/browser/privacy_budget/privacy_budget_prefs.cc b/chrome/browser/privacy_budget/privacy_budget_prefs.cc index b48b8cb..283f264 100644 --- a/chrome/browser/privacy_budget/privacy_budget_prefs.cc +++ b/chrome/browser/privacy_budget/privacy_budget_prefs.cc
@@ -9,15 +9,12 @@ namespace prefs { const char kPrivacyBudgetGeneration[] = "privacy_budget.generation"; -const char kPrivacyBudgetReportedReidBlocks[] = - "privacy_budget.reported_reid_blocks"; const char kPrivacyBudgetSeenSurfaces[] = "privacy_budget.seen"; const char kPrivacyBudgetSelectedOffsets[] = "privacy_budget.selected"; const char kPrivacyBudgetSelectedBlock[] = "privacy_budget.block_offset"; void RegisterPrivacyBudgetPrefs(PrefRegistrySimple* registry) { registry->RegisterIntegerPref(kPrivacyBudgetGeneration, 0); - registry->RegisterStringPref(kPrivacyBudgetReportedReidBlocks, std::string()); registry->RegisterStringPref(kPrivacyBudgetSeenSurfaces, std::string()); registry->RegisterStringPref(kPrivacyBudgetSelectedOffsets, std::string()); registry->RegisterIntegerPref(kPrivacyBudgetSelectedBlock, -1);
diff --git a/chrome/browser/privacy_budget/privacy_budget_prefs.h b/chrome/browser/privacy_budget/privacy_budget_prefs.h index 8128bd4..e4873aa 100644 --- a/chrome/browser/privacy_budget/privacy_budget_prefs.h +++ b/chrome/browser/privacy_budget/privacy_budget_prefs.h
@@ -17,11 +17,6 @@ // Value is an int stored as IntegerPref. extern const char kPrivacyBudgetGeneration[]; -// Pref used for persisting for which blocks of surfaces we already reported the -// hash for estimating the Reid score. Used to avoid recomputing and reporting -// the hashes multiple times. -extern const char kPrivacyBudgetReportedReidBlocks[]; - // Pref used for persisting |IdentifiabilityStudyState::seen_surface_sequence_|. // // Value is a list of IdentifiableSurface encoded via
diff --git a/chrome/browser/privacy_budget/privacy_budget_reid_score_browsertest.cc b/chrome/browser/privacy_budget/privacy_budget_reid_score_browsertest.cc deleted file mode 100644 index 907dde78..0000000 --- a/chrome/browser/privacy_budget/privacy_budget_reid_score_browsertest.cc +++ /dev/null
@@ -1,195 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/barrier_closure.h" -#include "build/build_config.h" -#include "build/buildflag.h" -#include "chrome/browser/privacy_budget/identifiability_study_state.h" -#include "chrome/browser/privacy_budget/privacy_budget_browsertest_util.h" -#include "chrome/browser/privacy_budget/privacy_budget_ukm_entry_filter.h" -#include "chrome/common/privacy_budget/privacy_budget_features.h" -#include "chrome/common/privacy_budget/scoped_privacy_budget_config.h" -#include "chrome/test/base/chrome_test_utils.h" -#include "components/ukm/test_ukm_recorder.h" -#include "content/public/test/browser_test.h" -#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h" - -#if BUILDFLAG(IS_ANDROID) -#include "chrome/test/base/android/android_browser_test.h" -#else -#include "chrome/test/base/in_process_browser_test.h" -#endif - -namespace { - -using testing::IsSupersetOf; -using testing::Key; - -class EnableReidEstimation { - public: - EnableReidEstimation() { - test::ScopedPrivacyBudgetConfig::Parameters parameters; - - parameters.reid_blocks = { - {blink::IdentifiableSurface::FromTypeAndToken( - blink::IdentifiableSurface::Type::kWebFeature, - blink::mojom::WebFeature::kNavigatorUserAgent), - blink::IdentifiableSurface::FromTypeAndToken( - blink::IdentifiableSurface::Type::kWebFeature, - blink::mojom::WebFeature::kNavigatorLanguage)}}; - - parameters.reid_salts_ranges = {1}; - parameters.reid_bits = {1}; - parameters.reid_noise = {0.01}; - - scoped_config_.Apply(parameters); - } - - private: - test::ScopedPrivacyBudgetConfig scoped_config_; -}; - -class PrivacyBudgetReidScoreBrowserTest : private EnableReidEstimation, - public PlatformBrowserTest {}; - -class PrivacyBudgetReidScoreBrowserTestWithTestRecorder - : private EnableReidEstimation, - public PrivacyBudgetBrowserTestBaseWithTestRecorder {}; - -} // namespace - -IN_PROC_BROWSER_TEST_F(PrivacyBudgetReidScoreBrowserTest, LoadsAGroup) { - EXPECT_TRUE(base::FeatureList::IsEnabled(features::kIdentifiabilityStudy)); - - const auto* settings = blink::IdentifiabilityStudySettings::Get(); - ASSERT_TRUE(settings->IsActive()); -} - -IN_PROC_BROWSER_TEST_F(PrivacyBudgetReidScoreBrowserTestWithTestRecorder, - ReidHashIsReported) { - blink::IdentifiabilityStudySettings::ResetStateForTesting(); - auto study_state = std::make_unique<IdentifiabilityStudyState>( - g_browser_process->local_state()); - auto filter = - std::make_unique<PrivacyBudgetUkmEntryFilter>(study_state.get()); - recorder().SetEntryFilter(std::move(filter)); - ASSERT_TRUE(embedded_test_server()->Start()); - content::DOMMessageQueue messages(web_contents()); - base::RunLoop run_loop; - - recorder().SetOnAddEntryCallback(ukm::builders::Identifiability::kEntryName, - BarrierClosure(4u, run_loop.QuitClosure())); - - ASSERT_TRUE(content::NavigateToURL( - web_contents(), - embedded_test_server()->GetURL("/privacy_budget/calls_user_agent.html"))); - - // The document calls the user agent and language apis and replies with done. - // Receipt of the message indicates that the script successfully completed. - std::string reply; - ASSERT_TRUE(messages.WaitForMessage(&reply)); - // Navigating away from the test page causes the document to be unloaded. That - // will cause any buffered metrics to be flushed. - content::NavigateToURLBlockUntilNavigationsComplete(web_contents(), - GURL("about:blank"), 1); - // Wait for the metrics to come down the pipe. - run_loop.Run(); - - auto merged_entries = recorder().GetMergedEntriesByName( - ukm::builders::Identifiability::kEntryName); - - // Calculate the reid surface key manually. - constexpr auto kReidScoreType = - blink::IdentifiableSurface::Type::kReidScoreEstimator; - auto surface_1 = blink::IdentifiableSurface::FromTypeAndToken( - blink::IdentifiableSurface::Type::kWebFeature, - blink::mojom::WebFeature::kNavigatorUserAgent); - auto surface_2 = blink::IdentifiableSurface::FromTypeAndToken( - blink::IdentifiableSurface::Type::kWebFeature, - blink::mojom::WebFeature::kNavigatorLanguage); - std::vector<uint64_t> tokens{surface_1.ToUkmMetricHash(), - surface_2.ToUkmMetricHash()}; - auto expected_surface = blink::IdentifiableSurface::FromTypeAndToken( - kReidScoreType, base::make_span(tokens)); - - // Merge all entries for comparison in the next step. - base::flat_map<uint64_t, int64_t> metrics; - - for (auto& it : merged_entries) { - metrics.insert(it.second->metrics.begin(), it.second->metrics.end()); - } - - EXPECT_THAT(metrics, IsSupersetOf({ - Key(expected_surface.ToUkmMetricHash()), - })); -} - -namespace { - -// Test class that allows to enable UKM recording. -class PrivacyBudgetReidScoreBrowserTestWithUkmRecording - : private EnableReidEstimation, - public PrivacyBudgetBrowserTestBaseWithUkmRecording {}; - -} // namespace - -IN_PROC_BROWSER_TEST_F(PrivacyBudgetReidScoreBrowserTestWithUkmRecording, - ReidIsReported) { - ASSERT_TRUE(base::FeatureList::IsEnabled(features::kIdentifiabilityStudy)); - ASSERT_TRUE(EnableUkmRecording()); - - constexpr blink::IdentifiableToken kDummyToken = 1; - constexpr blink::IdentifiableSurface kUserAgentSurface = - blink::IdentifiableSurface::FromTypeAndToken( - blink::IdentifiableSurface::Type::kWebFeature, - blink::mojom::WebFeature::kNavigatorUserAgent); - constexpr blink::IdentifiableSurface kLanguageSurface = - blink::IdentifiableSurface::FromTypeAndToken( - blink::IdentifiableSurface::Type::kWebFeature, - blink::mojom::WebFeature::kNavigatorLanguage); - - auto* ukm_recorder = ukm::UkmRecorder::Get(); - - blink::IdentifiabilityMetricBuilder(ukm::UkmRecorder::GetNewSourceID()) - .Add(kUserAgentSurface, kDummyToken) - .Add(kLanguageSurface, kDummyToken) - .Record(ukm_recorder); - - blink::IdentifiabilitySampleCollector::Get()->Flush(ukm_recorder); - - // Wait for the metrics to come down the pipe. - content::RunAllTasksUntilIdle(); - - ukm::UkmTestHelper ukm_test_helper(ukm_service()); - ukm_test_helper.BuildAndStoreLog(); - std::unique_ptr<ukm::Report> ukm_report = ukm_test_helper.GetUkmReport(); - ASSERT_TRUE(ukm_test_helper.HasUnsentLogs()); - ASSERT_TRUE(ukm_report); - ASSERT_NE(ukm_report->entries_size(), 0); - - std::map<uint64_t, int64_t> seen_metrics; - for (const auto& entry : ukm_report->entries()) { - ASSERT_TRUE(entry.has_event_hash()); - if (entry.event_hash() != ukm::builders::Identifiability::kEntryNameHash) { - continue; - } - for (const auto& metric : entry.metrics()) { - ASSERT_TRUE(metric.has_metric_hash()); - ASSERT_TRUE(metric.has_value()); - seen_metrics.insert({metric.metric_hash(), metric.value()}); - } - } - - // Calculate the reid surface key manually. - constexpr auto kReidScoreType = - blink::IdentifiableSurface::Type::kReidScoreEstimator; - std::vector<uint64_t> tokens{kUserAgentSurface.ToUkmMetricHash(), - kLanguageSurface.ToUkmMetricHash()}; - auto expected_surface = blink::IdentifiableSurface::FromTypeAndToken( - kReidScoreType, base::make_span(tokens)); - - EXPECT_THAT(seen_metrics, IsSupersetOf({ - Key(expected_surface.ToUkmMetricHash()), - })); -}
diff --git a/chrome/browser/privacy_budget/privacy_budget_reid_score_estimator.cc b/chrome/browser/privacy_budget/privacy_budget_reid_score_estimator.cc deleted file mode 100644 index a19f9109..0000000 --- a/chrome/browser/privacy_budget/privacy_budget_reid_score_estimator.cc +++ /dev/null
@@ -1,232 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/privacy_budget/privacy_budget_reid_score_estimator.h" - -#include "base/containers/contains.h" -#include "base/containers/flat_map.h" -#include "base/functional/bind.h" -#include "base/rand_util.h" -#include "base/task/sequenced_task_runner.h" -#include "chrome/browser/privacy_budget/privacy_budget_prefs.h" -#include "chrome/common/privacy_budget/field_trial_param_conversions.h" -#include "chrome/common/privacy_budget/types.h" -#include "components/prefs/pref_service.h" -#include "services/metrics/public/cpp/ukm_recorder.h" -#include "services/metrics/public/mojom/ukm_interface.mojom.h" -#include "third_party/abseil-cpp/absl/types/optional.h" -#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" -#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h" -#include "third_party/blink/public/common/privacy_budget/identifiability_sample_collector.h" -#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h" -#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" -#include "third_party/blink/public/common/privacy_budget/identifiable_token.h" - -namespace { -void ReportHashForReidScore(blink::IdentifiableSurface surface, - uint64_t reid_hash) { - ukm::SourceId ukm_source_id = ukm::NoURLSourceId(); - ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get(); - blink::IdentifiabilityMetricBuilder(ukm_source_id) - .Add(surface, reid_hash) - .Record(ukm_recorder); - blink::IdentifiabilitySampleCollector::Get()->FlushSource(ukm_recorder, - ukm_source_id); -} -} // namespace - -PrivacyBudgetReidScoreEstimator::ReidBlockStorage::ReidBlockStorage( - const IdentifiableSurfaceList& surface_list, - uint64_t salt_range, - int number_of_bits, - double noise_probability) - : salt_range_(salt_range), - number_of_bits_(number_of_bits), - noise_probability_(noise_probability) { - std::vector<uint64_t> surface_hashes; - for (const auto& surface : surface_list) { - surface_hashes.emplace_back(surface.ToUkmMetricHash()); - } - reid_surface_key_ = blink::IdentifiableSurface::FromTypeAndToken( - blink::IdentifiableSurface::Type::kReidScoreEstimator, - base::make_span(surface_hashes)); - std::vector<std::pair<blink::IdentifiableSurface, - absl::optional<blink::IdentifiableToken>>> - surfaces_vector; - surfaces_vector.reserve(surface_list.size()); - for (blink::IdentifiableSurface surface : surface_list) { - surfaces_vector.emplace_back(surface, absl::nullopt); - } - // Use the constructor which takes an unsorted vector, because inserting the - // items one by one runs in O(n^2) time. - surfaces_ = base::flat_map<blink::IdentifiableSurface, - absl::optional<blink::IdentifiableToken>>( - std::move(surfaces_vector)); -} - -PrivacyBudgetReidScoreEstimator::ReidBlockStorage::~ReidBlockStorage() = - default; - -PrivacyBudgetReidScoreEstimator::ReidBlockStorage::ReidBlockStorage( - ReidBlockStorage&&) = default; - -PrivacyBudgetReidScoreEstimator::ReidBlockStorage& -PrivacyBudgetReidScoreEstimator::ReidBlockStorage::operator=( - ReidBlockStorage&&) = default; - -bool PrivacyBudgetReidScoreEstimator::ReidBlockStorage::Full() const { - DCHECK_LE(recorded_values_count_, surfaces_.size()); - return recorded_values_count_ == surfaces_.size(); -} - -void PrivacyBudgetReidScoreEstimator::ReidBlockStorage::Record( - blink::IdentifiableSurface surface, - blink::IdentifiableToken value) { - auto surface_itr = surfaces_.find(surface); - if (surface_itr != surfaces_.end()) { - if (!surface_itr->second.has_value()) { - ++recorded_values_count_; - } - surface_itr->second = value; - } -} - -uint64_t -PrivacyBudgetReidScoreEstimator::ReidBlockStorage::ComputeHashForReidScore() { - std::vector<uint64_t> tokens; - uint64_t salt = base::RandGenerator(salt_range_); - - tokens.emplace_back(salt); - for (blink::IdentifiableToken value : GetValues()) { - tokens.emplace_back(static_cast<uint64_t>(value.ToUkmMetricValue())); - } - // Initialize Reid hash with random noise. - uint64_t reid_hash = base::RandUint64(); - // Calculate the real hash if the random number is greater than the Reid noise - // probability. - if (base::RandDouble() >= noise_probability_) { - // Use the hash function embedded in IdentifiableToken. - reid_hash = blink::IdentifiabilityDigestOfBytes( - base::as_bytes(base::make_span(tokens))); - } - // Create mask based on reid_bits required. - constexpr uint64_t kTypedOne = 1; - uint64_t mask = (kTypedOne << number_of_bits_) - 1; - uint64_t needed_bits = reid_hash & mask; - // Return salt in the left 32 bits and Reid b-bits hash in the right 32 bits. - return ((salt << 32) | needed_bits); -} - -std::vector<blink::IdentifiableToken> -PrivacyBudgetReidScoreEstimator::ReidBlockStorage::GetValues() const { - DCHECK(Full()); - std::vector<blink::IdentifiableToken> values; - for (auto& [key, value] : surfaces_) { - DCHECK(value.has_value()); - values.emplace_back(value.value()); - } - return values; -} - -uint64_t PrivacyBudgetReidScoreEstimator::ReidBlockStorage::salt_range() const { - DCHECK(Full()); - return salt_range_; -} - -int PrivacyBudgetReidScoreEstimator::ReidBlockStorage::number_of_bits() const { - DCHECK(Full()); - return number_of_bits_; -} - -double PrivacyBudgetReidScoreEstimator::ReidBlockStorage::noise_probability() - const { - DCHECK(Full()); - return noise_probability_; -} - -PrivacyBudgetReidScoreEstimator::PrivacyBudgetReidScoreEstimator( - const IdentifiabilityStudyGroupSettings* state_settings, - PrefService* pref_service) - : settings_(state_settings), pref_service_(pref_service) {} - -void PrivacyBudgetReidScoreEstimator::Init() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!settings_->enabled() || !settings_->IsUsingReidScoreEstimator()) - return; - - already_reported_reid_blocks_ = - DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceList>( - pref_service_->GetString(prefs::kPrivacyBudgetReportedReidBlocks)); - - surface_blocks_.clear(); - for (size_t i = 0; i < settings_->reid_blocks().size(); ++i) { - // All the vectors below have the same size. This is enforced by - // `IdentifiabilityStudyGroupSettings`. - ReidBlockStorage block( - /*surface_list=*/settings_->reid_blocks()[i], - /*salt_range=*/settings_->reid_blocks_salts_ranges()[i], - /*number_of_bits=*/settings_->reid_blocks_bits()[i], - /*noise_probability=*/ - settings_->reid_blocks_noise_probabilities()[i]); - if (!base::Contains(already_reported_reid_blocks_, - block.reid_surface_key())) { - surface_blocks_.emplace_back(std::move(block)); - } - } -} - -PrivacyBudgetReidScoreEstimator::~PrivacyBudgetReidScoreEstimator() = default; - -void PrivacyBudgetReidScoreEstimator::ProcessForReidScore( - blink::IdentifiableSurface surface, - blink::IdentifiableToken token) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - bool at_least_one_reported_block = false; - for (auto block_itr = surface_blocks_.begin(); - block_itr != surface_blocks_.end();) { - block_itr->Record(surface, token); - if (block_itr->Full()) { - // Report new Reid surface if the map is full. - - // Compute the Reid hash for the needed Reid block. - uint64_t reid_hash = block_itr->ComputeHashForReidScore(); - - // Report to UKM in a separate task in order to avoid re-entrancy. - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce(&ReportHashForReidScore, - block_itr->reid_surface_key(), reid_hash)); - - // Remove this block from the map, and store the information in the - // PrefService, since we want to report a hash for a block only once. - DCHECK(!base::Contains(already_reported_reid_blocks_, - block_itr->reid_surface_key())); - already_reported_reid_blocks_.push_back(block_itr->reid_surface_key()); - // Note: The returned `block_itr` points to the next element in the - // vector. - block_itr = surface_blocks_.erase(block_itr); - - at_least_one_reported_block = true; - } else { - ++block_itr; - } - } - - if (at_least_one_reported_block) - WriteReportedReidBlocksToPrefs(); -} - -void PrivacyBudgetReidScoreEstimator::WriteReportedReidBlocksToPrefs() const { - DCHECK(!already_reported_reid_blocks_.empty()); - pref_service_->SetString( - prefs::kPrivacyBudgetReportedReidBlocks, - EncodeIdentifiabilityFieldTrialParam(already_reported_reid_blocks_)); -} - -void PrivacyBudgetReidScoreEstimator::ResetPersistedState() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - pref_service_->ClearPref(prefs::kPrivacyBudgetReportedReidBlocks); - already_reported_reid_blocks_.clear(); - surface_blocks_.clear(); - Init(); -}
diff --git a/chrome/browser/privacy_budget/privacy_budget_reid_score_estimator.h b/chrome/browser/privacy_budget/privacy_budget_reid_score_estimator.h deleted file mode 100644 index 67d5e34..0000000 --- a/chrome/browser/privacy_budget/privacy_budget_reid_score_estimator.h +++ /dev/null
@@ -1,140 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PRIVACY_BUDGET_PRIVACY_BUDGET_REID_SCORE_ESTIMATOR_H_ -#define CHROME_BROWSER_PRIVACY_BUDGET_PRIVACY_BUDGET_REID_SCORE_ESTIMATOR_H_ - -#include <list> - -#include "base/containers/flat_map.h" -#include "base/sequence_checker.h" -#include "chrome/browser/privacy_budget/identifiability_study_group_settings.h" -#include "chrome/common/privacy_budget/types.h" -#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" -#include "third_party/blink/public/common/privacy_budget/identifiable_token.h" - -class PrefService; - -// Temporary surface-value storage to estimate the Reid score of specified -// surface set. -class PrivacyBudgetReidScoreEstimator { - public: - // `state_settings` and `pref_service` pointees must outlive `this`. - explicit PrivacyBudgetReidScoreEstimator( - const IdentifiabilityStudyGroupSettings* state_settings, - PrefService* pref_service); - - void Init(); - - PrivacyBudgetReidScoreEstimator(const PrivacyBudgetReidScoreEstimator&) = - delete; - PrivacyBudgetReidScoreEstimator& operator=( - const PrivacyBudgetReidScoreEstimator&) = delete; - - ~PrivacyBudgetReidScoreEstimator(); - - // Searches the storage for the surface. - // If found, it updates its value to the token sent. - void ProcessForReidScore(blink::IdentifiableSurface surface, - blink::IdentifiableToken token); - - void ResetPersistedState(); - - private: - // ReidBlockStorage is a helper class which stores a list of surfaces - // for which we want to estimate the Reid score, i.e. corresponding to a Reid - // block. - class ReidBlockStorage { - public: - ReidBlockStorage(const IdentifiableSurfaceList& surface_list, - uint64_t salt_range, - int number_of_bits, - double noise_probability); - ~ReidBlockStorage(); - - ReidBlockStorage(const ReidBlockStorage&) = delete; - ReidBlockStorage& operator=(const ReidBlockStorage&) = delete; - - ReidBlockStorage(ReidBlockStorage&&); - ReidBlockStorage& operator=(ReidBlockStorage&&); - - // Returns whether we know the values of all the surfaces in the block. - bool Full() const; - - // If `surface` is one of the surfaces of this block, stores `value` - // for `surface`. If we already have a value for `surface`, the old value - // will be discarded. Does nothing if `surface` does not belong to this - // block. - void Record(blink::IdentifiableSurface surface, - blink::IdentifiableToken value); - - // Compute the hash for estimating the REID score. - uint64_t ComputeHashForReidScore(); - - // Returns the values of the surfaces. Can be called only if full. - std::vector<blink::IdentifiableToken> GetValues() const; - - // Returns the key to be used for reporting the synthetic surface - // corresponding to this Reid block. - blink::IdentifiableSurface reid_surface_key() const { - return reid_surface_key_; - } - - // Can be called only if full. - uint64_t salt_range() const; - - // Can be called only if full. - int number_of_bits() const; - - // Can be called only if full. - double noise_probability() const; - - private: - // The surfaces which we want to track in this block, together with their - // values (if we recorded them already). - base::flat_map<blink::IdentifiableSurface, - absl::optional<blink::IdentifiableToken>> - surfaces_; - - // Keeps track of the number of surfaces for which we have recorded a value - // in this block. - size_t recorded_values_count_ = 0; - - // A random salt for this block will be chosen in the interval - // [0,`salt_range_`]. - uint64_t salt_range_; - - // The number of bits that will be reported for this block. - int number_of_bits_; - - // The probability of reporting a random value, instead of the real hash, - // for this block. - double noise_probability_; - - // The surface key under which the hash for this Reid block should be - // reported. - blink::IdentifiableSurface reid_surface_key_; - }; - - void WriteReportedReidBlocksToPrefs() const - VALID_CONTEXT_REQUIRED(sequence_checker_); - - // Keeps track of the blocks for which we want to compute the Reid score. - std::list<ReidBlockStorage> surface_blocks_ - GUARDED_BY_CONTEXT(sequence_checker_); - - // Keeps track of the Reid blocks which where already reported. - IdentifiableSurfaceList already_reported_reid_blocks_ - GUARDED_BY_CONTEXT(sequence_checker_); - - // `settings_` pointee must outlive `this`. - raw_ptr<const IdentifiabilityStudyGroupSettings> settings_; - - // `pref_service_` pointee must outlive `this`. Used for persistent state. - raw_ptr<PrefService> pref_service_ = nullptr; - - SEQUENCE_CHECKER(sequence_checker_); -}; - -#endif // CHROME_BROWSER_PRIVACY_BUDGET_PRIVACY_BUDGET_REID_SCORE_ESTIMATOR_H_
diff --git a/chrome/browser/privacy_budget/privacy_budget_reid_score_estimator_unittest.cc b/chrome/browser/privacy_budget/privacy_budget_reid_score_estimator_unittest.cc deleted file mode 100644 index d901e70..0000000 --- a/chrome/browser/privacy_budget/privacy_budget_reid_score_estimator_unittest.cc +++ /dev/null
@@ -1,326 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/privacy_budget/privacy_budget_reid_score_estimator.h" - -#include <cstdint> - -#include "base/barrier_closure.h" -#include "base/containers/flat_set.h" -#include "base/rand_util.h" -#include "base/run_loop.h" -#include "base/test/task_environment.h" -#include "chrome/browser/privacy_budget/identifiability_study_group_settings.h" -#include "chrome/browser/privacy_budget/privacy_budget_prefs.h" -#include "components/prefs/testing_pref_service.h" -#include "components/ukm/test_ukm_recorder.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" -#include "third_party/blink/public/common/privacy_budget/identifiable_token.h" -#include "third_party/blink/public/common/privacy_budget/scoped_identifiability_test_sample_collector.h" - -class PrivacyBudgetReidScoreEstimatorStandaloneTest - : public ::testing::TestWithParam<std::tuple<uint32_t, int, int, bool>> { - public: - PrivacyBudgetReidScoreEstimatorStandaloneTest() { - prefs::RegisterPrivacyBudgetPrefs(pref_service_.registry()); - } - - TestingPrefServiceSimple* pref_service() { return &pref_service_; } - - void RunUntilIdle() { task_environment_.RunUntilIdle(); } - - void ProcessReidRecords(IdentifiabilityStudyGroupSettings* settings, - bool fixedToken) { - for (int i = 0; i < kNumIterations; ++i) { - PrivacyBudgetReidScoreEstimator reid_storage(settings, pref_service()); - reid_storage.ResetPersistedState(); - reid_storage.Init(); - int64_t token1 = - fixedToken ? 1 : static_cast<int64_t>(base::RandUint64()); - int64_t token2 = - fixedToken ? 2 : static_cast<int64_t>(base::RandUint64()); - // Process values for 2 surfaces. - reid_storage.ProcessForReidScore(kSurface_1, - blink::IdentifiableToken(token1)); - reid_storage.ProcessForReidScore(kSurface_2, - blink::IdentifiableToken(token2)); - } - } - - // Example surfaces for testing. - const blink::IdentifiableSurface kSurface_1 = - blink::IdentifiableSurface::FromMetricHash(2077075229u); - const blink::IdentifiableSurface kSurface_2 = - blink::IdentifiableSurface::FromMetricHash(1122849309u); - const blink::IdentifiableSurface kSurface_3 = - blink::IdentifiableSurface::FromMetricHash(1122849311u); - - // Expected Reid surface key to be reported based on the example surfaces - // defined (kSurface_1, kSurface_2) using the function - // IdentifiableSurface::FromTypeAndToken() with type - // IdentifiableSurface::Type::kReidScoreEstimator. - const uint64_t kExpectedSurface = 11332616172707669541u; - - const int kNumIterations = 50; - - private: - TestingPrefServiceSimple pref_service_; - base::test::SingleThreadTaskEnvironment task_environment_; -}; - -TEST_F(PrivacyBudgetReidScoreEstimatorStandaloneTest, - ReidEstimatorWrongParameters) { - auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - /*enabled=*/true, - /*expected_surface_count=*/0, - /*surface_budget=*/0, - /*blocks=*/"", - /*blocks_weights=*/"", - /*allowed_random_types=*/"", - /*reid_blocks=*/"2077075229;1122849309,2077075230;1122849310", - /*reid_blocks_salts_ranges=*/"1000000", /*Missing Salt!*/ - /*reid_blocks_bits=*/"1,2", - /*reid_blocks_noise_probabilities=*/"0,0"); - - PrivacyBudgetReidScoreEstimator reid_storage(&settings, pref_service()); - reid_storage.ResetPersistedState(); - // Test passes if initializing the Reid estimator is skipped and does not - // crash. - reid_storage.Init(); -} - -TEST_P(PrivacyBudgetReidScoreEstimatorStandaloneTest, - ReportReidwithParameters) { - const auto [salt_ranges, bits, noise, fixed_token] = GetParam(); - auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - /*enabled=*/true, - /*expected_surface_count=*/0, - /*surface_budget=*/0, - /*blocks=*/"", - /*blocks_weights=*/"", - /*allowed_random_types=*/"", - /*reid_blocks=*/"2077075229;1122849309", - /*reid_blocks_salts_ranges=*/base::NumberToString(salt_ranges), - /*reid_blocks_bits=*/base::NumberToString(bits), - /*reid_blocks_noise_probabilities=*/base::NumberToString(noise)); - - ukm::TestAutoSetUkmRecorder test_recorder; - base::RunLoop run_loop; - test_recorder.SetOnAddEntryCallback( - ukm::builders::Identifiability::kEntryName, - base::BarrierClosure(kNumIterations, run_loop.QuitClosure())); - blink::test::ScopedIdentifiabilityTestSampleCollector collector; - ProcessReidRecords(&settings, fixed_token); - // This should let the async tasks run. - run_loop.Run(); - const auto& entries = collector.entries(); - bool has_value_0 = false; - bool has_value_1 = false; - base::flat_set<uint32_t> reid_results; - int count = 0; - for (auto& entry : entries) { - for (auto& metric : entry.metrics) { - auto surface = metric.surface; - if (surface.GetType() == - blink::IdentifiableSurface::Type::kReidScoreEstimator) { - EXPECT_EQ(metric.surface.ToUkmMetricHash(), kExpectedSurface); - ++count; - uint64_t hash = static_cast<uint64_t>(metric.value.ToUkmMetricValue()); - uint32_t reid_bits = hash & 0xFFFFFFFF; - if (noise == 1) { - // Result should be noise i.e. didn't appear before. - EXPECT_FALSE(reid_results.contains(reid_bits)); - reid_results.insert(reid_bits); - } else { - EXPECT_TRUE(reid_bits == 0 || reid_bits == 1); - if (reid_bits == 0) - has_value_0 = true; - else if (reid_bits == 1) - has_value_1 = true; - } - uint32_t salt = (hash >> 32); - EXPECT_TRUE((salt >= 0) && (salt < salt_ranges)); - } - } - } - EXPECT_EQ(count, kNumIterations); - // Since the 1 bit should be random, the probability of it being always 0 or - // always 1 is 2/(2^kNumIterations), hence it should be negligible. - if (noise != 1) { - EXPECT_TRUE(has_value_0); - EXPECT_TRUE(has_value_1); - } -} - -INSTANTIATE_TEST_SUITE_P( - PrivacyBudgetReidScoreEstimatorParameterizedTest, - PrivacyBudgetReidScoreEstimatorStandaloneTest, - ::testing::Values( - /*RandomSaltFixedTokens*/ std::make_tuple(1000000, 1, 0, true), - /*FixedSaltRandomTokens*/ std::make_tuple(1, 1, 0, false), - /*AllNoise*/ std::make_tuple(1, 32, 1, true))); - -TEST_F(PrivacyBudgetReidScoreEstimatorStandaloneTest, ReportingMultiBlockReid) { - auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - /*enabled=*/true, - /*expected_surface_count=*/0, - /*surface_budget=*/0, - /*blocks=*/"", - /*blocks_weights=*/"", - /*allowed_random_types=*/"", - /*reid_blocks=*/ - "2077075229;1122849309;1122849311,1122849310;1122849311,2077075229", - /*reid_blocks_salts_ranges=*/"1,1000000,1", - /*reid_blocks_bits=*/"10,1,1", - /*reid_blocks_noise_probabilities=*/"0,0,0"); - - ukm::TestAutoSetUkmRecorder test_recorder; - - PrivacyBudgetReidScoreEstimator reid_storage(&settings, pref_service()); - reid_storage.Init(); - - base::RunLoop run_loop; - test_recorder.SetOnAddEntryCallback( - ukm::builders::Identifiability::kEntryName, - BarrierClosure(2u, run_loop.QuitClosure())); - blink::test::ScopedIdentifiabilityTestSampleCollector collector; - - // Process values for the surfaces. - reid_storage.ProcessForReidScore(kSurface_1, blink::IdentifiableToken(1)); - reid_storage.ProcessForReidScore(kSurface_2, blink::IdentifiableToken(2)); - reid_storage.ProcessForReidScore(kSurface_3, blink::IdentifiableToken(3)); - - // Get these values using IdentifiableSurface::FromTypeAndToken() with type - // IdentifiableSurface::Type::kReidScoreEstimator. - uint64_t expected_surface_key_for_block_0 = 11985663064608009253u; - uint64_t expected_surface_key_for_block_2 = 17524302200237928997u; - - // Get the expected values of Reid hashes. The salt is forced to 0. - // The surfaces will be sorted in ReidBlockStorage so the hash will be - // computed based on the surface key order. - std::vector<uint64_t> tokens_0 = {0, 2, 3, 1}; - std::vector<uint64_t> tokens_2 = {0, 1}; - uint64_t reid_hash_0 = blink::IdentifiabilityDigestOfBytes( - base::as_bytes(base::make_span(tokens_0))); - uint64_t reid_hash_2 = blink::IdentifiabilityDigestOfBytes( - base::as_bytes(base::make_span(tokens_2))); - - // Get the lower b bits required. - uint64_t reid_bits_0 = reid_hash_0 & ((1 << 10) - 1); - uint64_t reid_bits_2 = reid_hash_2 % 2; - - // This should let the async tasks run. - run_loop.Run(); - - const auto& entries = collector.entries(); - EXPECT_EQ(entries.size(), 2u); - EXPECT_EQ(entries[0].metrics[0].surface.ToUkmMetricHash(), - expected_surface_key_for_block_2); - uint64_t value_2 = - static_cast<uint64_t>(entries[0].metrics[0].value.ToUkmMetricValue()); - EXPECT_EQ(value_2, reid_bits_2); - EXPECT_EQ(entries[1].metrics[0].surface.ToUkmMetricHash(), - expected_surface_key_for_block_0); - uint64_t value_0 = - static_cast<uint64_t>(entries[1].metrics[0].value.ToUkmMetricValue()); - EXPECT_EQ(value_0, reid_bits_0); -} - -TEST_F(PrivacyBudgetReidScoreEstimatorStandaloneTest, - ReidHashIsReportedOnlyOnce) { - auto settings = IdentifiabilityStudyGroupSettings::InitFrom( - /*enabled=*/true, - /*expected_surface_count=*/0, - /*surface_budget=*/0, - /*blocks=*/"", - /*blocks_weights=*/"", - /*allowed_random_types=*/"", - /*reid_blocks=*/"2077075229;1122849309", - /*reid_blocks_salts_ranges=*/"1000000", - /*reid_blocks_bits=*/"1", - /*reid_blocks_noise_probabilities=*/"0"); - - ukm::TestAutoSetUkmRecorder test_recorder; - - { - PrivacyBudgetReidScoreEstimator reid_storage(&settings, pref_service()); - reid_storage.Init(); - - { - base::RunLoop run_loop; - test_recorder.SetOnAddEntryCallback( - ukm::builders::Identifiability::kEntryName, run_loop.QuitClosure()); - blink::test::ScopedIdentifiabilityTestSampleCollector collector; - - // Process values for 2 surfaces. - reid_storage.ProcessForReidScore(kSurface_1, blink::IdentifiableToken(1)); - reid_storage.ProcessForReidScore(kSurface_2, blink::IdentifiableToken(2)); - - // This should let the async tasks run. - run_loop.Run(); - - const auto& entries = collector.entries(); - EXPECT_EQ(entries.size(), 1u); - EXPECT_EQ(entries[0].metrics.size(), 1u); - EXPECT_EQ(entries[0].metrics[0].surface.ToUkmMetricHash(), - kExpectedSurface); - } - - // Now check that the reid hash is not reported again if we see again the - // two surfaces. - { - blink::test::ScopedIdentifiabilityTestSampleCollector collector; - - reid_storage.ProcessForReidScore(kSurface_1, blink::IdentifiableToken(1)); - reid_storage.ProcessForReidScore(kSurface_2, blink::IdentifiableToken(2)); - - RunUntilIdle(); - const auto& entries = collector.entries(); - EXPECT_TRUE(entries.empty()); - } - } - - // Even if we instantiate a new PrivacyBudgetReidScoreEstimator, the Reid - // hash is not reported again because of the information persisted in the - // PrefService. - { - PrivacyBudgetReidScoreEstimator reid_storage(&settings, pref_service()); - reid_storage.Init(); - { - blink::test::ScopedIdentifiabilityTestSampleCollector collector; - - reid_storage.ProcessForReidScore(kSurface_1, blink::IdentifiableToken(1)); - reid_storage.ProcessForReidScore(kSurface_2, blink::IdentifiableToken(2)); - - RunUntilIdle(); - - const auto& entries = collector.entries(); - EXPECT_TRUE(entries.empty()); - } - - // If we reset the persisted state, then the Reid hash will be reported - // again. - reid_storage.ResetPersistedState(); - reid_storage.Init(); - - { - base::RunLoop run_loop; - test_recorder.SetOnAddEntryCallback( - ukm::builders::Identifiability::kEntryName, run_loop.QuitClosure()); - - blink::test::ScopedIdentifiabilityTestSampleCollector collector; - reid_storage.ProcessForReidScore(kSurface_1, blink::IdentifiableToken(1)); - reid_storage.ProcessForReidScore(kSurface_2, blink::IdentifiableToken(2)); - - run_loop.Run(); - - const auto& entries = collector.entries(); - EXPECT_EQ(entries.size(), 1u); - EXPECT_EQ(entries[0].metrics.size(), 1u); - EXPECT_EQ(entries[0].metrics[0].surface.ToUkmMetricHash(), - kExpectedSurface); - } - } -}
diff --git a/chrome/browser/privacy_budget/privacy_budget_ukm_entry_filter.cc b/chrome/browser/privacy_budget/privacy_budget_ukm_entry_filter.cc index 71edf9f..af02e84 100644 --- a/chrome/browser/privacy_budget/privacy_budget_ukm_entry_filter.cc +++ b/chrome/browser/privacy_budget/privacy_budget_ukm_entry_filter.cc
@@ -46,10 +46,6 @@ blink::IdentifiableSurface::FromMetricHash(metric.first); const blink::IdentifiableToken token = metric.second; - // Update the Reid surface storage map. - identifiability_study_state_->MaybeStoreValueForComputingReidScore(surface, - token); - if (!blink::IdentifiabilityStudySettings::Get()->ShouldSampleSurface( surface)) return true;
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragment.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragment.java index a433902..8a8f118 100644 --- a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragment.java +++ b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragment.java
@@ -26,7 +26,6 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.OneshotSupplier; -import org.chromium.chrome.browser.back_press.BackPressHelper; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.privacy_guide.PrivacyGuideUtils.CustomTabIntentHelper; import org.chromium.chrome.browser.profiles.Profile; @@ -48,7 +47,6 @@ */ public class PrivacyGuideFragment extends Fragment implements BackPressHandler, - BackPressHelper.ObsoleteBackPressedHandler, ProfileDependentSetting, FragmentSettingsLauncher { /** @@ -257,6 +255,15 @@ mPagerAdapter.getFragmentType(followingStepIdx)); } + private boolean onBackPressed() { + if (shouldHandleBackPress()) { + previousStep(); + return true; + } + + return false; + } + @Override public void onAttachFragment(@NonNull Fragment childFragment) { if (childFragment instanceof ProfileDependentSetting) { @@ -302,16 +309,6 @@ } @Override - public boolean onBackPressed() { - if (shouldHandleBackPress()) { - previousStep(); - return true; - } - - return false; - } - - @Override public int handleBackPress() { return onBackPressed() ? BackPressResult.SUCCESS : BackPressResult.FAILURE; }
diff --git a/chrome/browser/readaloud/android/BUILD.gn b/chrome/browser/readaloud/android/BUILD.gn index 4b42934..cc08332 100644 --- a/chrome/browser/readaloud/android/BUILD.gn +++ b/chrome/browser/readaloud/android/BUILD.gn
@@ -8,24 +8,21 @@ android_library("java") { sources = [ "java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java", - "java/src/org/chromium/chrome/browser/readaloud/ReadAloudMetrics.java", "java/src/org/chromium/chrome/browser/readaloud/ReadAloudMiniPlayerSceneLayer.java", "java/src/org/chromium/chrome/browser/readaloud/ReadAloudPrefs.java", "java/src/org/chromium/chrome/browser/readaloud/ReadAloudToolbarButtonController.java", ] deps = [ ":hooks_java", + ":metrics_java", "//base:base_java", "//chrome/android:chrome_app_java_resources", "//chrome/android/modules/readaloud/public:java", "//chrome/browser/browser_controls/android:java", "//chrome/browser/device:java", - "//chrome/browser/flags:java", "//chrome/browser/language/android:base_module_java", "//chrome/browser/language/android:java", "//chrome/browser/profiles/android:java", - "//chrome/browser/search_engines/android:java", - "//chrome/browser/signin/services/android:java", "//chrome/browser/tab:java", "//chrome/browser/tabmodel:java", "//chrome/browser/ui/android/layouts:java", @@ -33,14 +30,11 @@ "//chrome/browser/ui/android/toolbar:java", "//chrome/browser/user_education:java", "//components/browser_ui/bottomsheet/android:java", - "//components/browser_ui/bottomsheet/android:java", "//components/embedder_support/android:util_java", "//components/feature_engagement/public:public_java", "//components/prefs/android:java", - "//components/search_engines/android:java", "//components/user_prefs/android:java", "//content/public/android:content_java", - "//third_party/android_deps:guava_android_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/jni_zero:jni_zero_java", "//ui/android:ui_no_recycler_view_java", @@ -57,11 +51,22 @@ ] } +android_library("metrics_java") { + sources = + [ "java/src/org/chromium/chrome/browser/readaloud/ReadAloudMetrics.java" ] + + deps = [ + "//base:base_java", + "//third_party/androidx:androidx_annotation_annotation_java", + ] +} + android_library("features_java") { sources = [ "java/src/org/chromium/chrome/browser/readaloud/ReadAloudFeatures.java", ] deps = [ + ":metrics_java", "//base:base_java", "//chrome/browser/flags:java", "//chrome/browser/preferences:java",
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java index b6d5bba4c..7bcef5a0 100644 --- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudController.java
@@ -285,6 +285,12 @@ maybeCheckReadability(url); maybeHandleTabReload(tab, url); maybeStopPlayback(tab); + boolean isAllowed = ReadAloudFeatures.isAllowed(mProfileSupplier.get()); + ReadAloudMetrics.recordIsUserEligible(isAllowed); + if (!isAllowed) { + ReadAloudMetrics.recordIneligibilityReason( + ReadAloudFeatures.getIneligibilityReason()); + } } @Override
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudControllerUnitTest.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudControllerUnitTest.java index 00d2f36..b53ce69a 100644 --- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudControllerUnitTest.java +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudControllerUnitTest.java
@@ -49,6 +49,7 @@ import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.price_tracking.PriceTrackingFeatures; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.readaloud.ReadAloudMetrics.IneligibilityReason; import org.chromium.chrome.browser.search_engines.SearchEngineType; import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.signin.services.UnifiedConsentServiceBridge; @@ -1153,6 +1154,42 @@ verify(mPlayback, never()).release(); } + @Test + public void testMetricRecorded_eligibility() { + final String histogramName = ReadAloudMetrics.IS_USER_ELIGIBLE; + + var histogram = HistogramWatcher.newSingleRecordWatcher(histogramName, true); + mController.getTabModelTabObserverforTests().onPageLoadStarted(mTab, mTab.getUrl()); + histogram.assertExpected(); + + histogram = HistogramWatcher.newSingleRecordWatcher(histogramName, false); + when(mPrefService.getBoolean("readaloud.listen_to_this_page_enabled")).thenReturn(false); + mController.getTabModelTabObserverforTests().onPageLoadStarted(mTab, mTab.getUrl()); + histogram.assertExpected(); + } + + @Test + public void testMetricRecorded_ineligibilityReason() { + final String histogramName = ReadAloudMetrics.INELIGIBILITY_REASON; + + var histogram = + HistogramWatcher.newSingleRecordWatcher( + histogramName, IneligibilityReason.POLICY_DISABLED); + when(mPrefService.getBoolean("readaloud.listen_to_this_page_enabled")).thenReturn(false); + mController.getTabModelTabObserverforTests().onPageLoadStarted(mTab, mTab.getUrl()); + histogram.assertExpected(); + when(mPrefService.getBoolean("readaloud.listen_to_this_page_enabled")).thenReturn(true); + + histogram = + HistogramWatcher.newSingleRecordWatcher( + histogramName, IneligibilityReason.DEFAULT_SEARCH_ENGINE_GOOGLE_FALSE); + doReturn(SearchEngineType.SEARCH_ENGINE_OTHER) + .when(mTemplateUrlService) + .getSearchEngineTypeFromTemplateUrl(anyString()); + mController.getTabModelTabObserverforTests().onPageLoadStarted(mTab, mTab.getUrl()); + histogram.assertExpected(); + } + private void onPlaybackSuccess(Playback playback) { mPlaybackCallbackCaptor.getValue().onSuccess(playback); resolvePromises();
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudFeatures.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudFeatures.java index 36c129ba..cd61f19 100644 --- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudFeatures.java +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudFeatures.java
@@ -9,6 +9,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.readaloud.ReadAloudMetrics.IneligibilityReason; import org.chromium.chrome.browser.search_engines.SearchEngineType; import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.signin.services.UnifiedConsentServiceBridge; @@ -21,6 +22,8 @@ private static final String API_KEY_OVERRIDE_PARAM_NAME = "api_key_override"; private static final String VOICES_OVERRIDE_PARAM_NAME = "voices_override"; + private static @IneligibilityReason int sIneligibilityReason = IneligibilityReason.UNKNOWN; + /** * Returns true if Read Aloud is allowed. All must be true: * @@ -33,25 +36,53 @@ * </ul> */ public static boolean isAllowed(Profile profile) { - if (profile == null || profile.isOffTheRecord()) { + sIneligibilityReason = IneligibilityReason.UNKNOWN; + if (profile == null) { return false; } + + if (profile.isOffTheRecord()) { + sIneligibilityReason = IneligibilityReason.INCOGNITO_MODE; + return false; + } + + // Check whether the user has enabled anonymous URL-keyed data collection. + // This is surfaced on the relatively new "Make searches and browsing + // better" user setting. + if (!UnifiedConsentServiceBridge.isUrlKeyedAnonymizedDataCollectionEnabled(profile)) { + sIneligibilityReason = IneligibilityReason.MSBB_DISABLED; + return false; + } + TemplateUrlService templateUrlService = TemplateUrlServiceFactory.getForProfile(profile); TemplateUrl currentSearchEngine = templateUrlService.getDefaultSearchEngineTemplateUrl(); if (currentSearchEngine == null) { + sIneligibilityReason = IneligibilityReason.DEFAULT_SEARCH_ENGINE_GOOGLE_FALSE; return false; } int searchEngineType = templateUrlService.getSearchEngineTypeFromTemplateUrl( currentSearchEngine.getKeyword()); + if (searchEngineType != SearchEngineType.SEARCH_ENGINE_GOOGLE) { + sIneligibilityReason = IneligibilityReason.DEFAULT_SEARCH_ENGINE_GOOGLE_FALSE; + return false; + } - return searchEngineType == SearchEngineType.SEARCH_ENGINE_GOOGLE - && UserPrefs.get(profile).getBoolean(Pref.LISTEN_TO_THIS_PAGE_ENABLED) - // Check whether the user has enabled anonymous URL-keyed data collection. - // This is surfaced on the relatively new "Make searches and browsing - // better" user setting. - && UnifiedConsentServiceBridge.isUrlKeyedAnonymizedDataCollectionEnabled(profile) - && ChromeFeatureList.isEnabled(ChromeFeatureList.READALOUD); + if (!UserPrefs.get(profile).getBoolean(Pref.LISTEN_TO_THIS_PAGE_ENABLED)) { + sIneligibilityReason = IneligibilityReason.POLICY_DISABLED; + return false; + } + + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.READALOUD)) { + sIneligibilityReason = IneligibilityReason.FEATURE_FLAG_DISABLED; + return false; + } + + return true; + } + + public static @IneligibilityReason int getIneligibilityReason() { + return sIneligibilityReason; } /** Returns true if playback is enabled. */
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudMetrics.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudMetrics.java index 55e96ec..d0836c9a3 100644 --- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudMetrics.java +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudMetrics.java
@@ -4,14 +4,61 @@ package org.chromium.chrome.browser.readaloud; +import androidx.annotation.IntDef; import androidx.annotation.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + public class ReadAloudMetrics { @VisibleForTesting public static String READABILITY_SUCCESS = "ReadAloud.IsPageReadable"; + @VisibleForTesting + public static String INELIGIBILITY_REASON = "ReadAloud.Eligibility.IneligiblityReason"; + + @VisibleForTesting + public static String IS_USER_ELIGIBLE = "ReadAloud.Eligibility.IsUserEligible"; + + /** + * The reason why we clear the prepared message. + * + * <p>Needs to stay in sync with ReadAloudIneligibilityReason in enums.xml. These values are + * persisted to logs. Entries should not be renumbered and numeric values should never be + * reused. + */ + @IntDef({ + IneligibilityReason.UNKNOWN, + IneligibilityReason.FEATURE_FLAG_DISABLED, + IneligibilityReason.INCOGNITO_MODE, + IneligibilityReason.MSBB_DISABLED, + IneligibilityReason.POLICY_DISABLED, + IneligibilityReason.DEFAULT_SEARCH_ENGINE_GOOGLE_FALSE, + IneligibilityReason.COUNT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface IneligibilityReason { + int UNKNOWN = 0; + int FEATURE_FLAG_DISABLED = 1; + int INCOGNITO_MODE = 2; + int MSBB_DISABLED = 3; + int POLICY_DISABLED = 4; + int DEFAULT_SEARCH_ENGINE_GOOGLE_FALSE = 5; + // Always update COUNT to match the last reason in the list. + int COUNT = 6; + } + public static void recordIsPageReadable(boolean successful) { RecordHistogram.recordBooleanHistogram(READABILITY_SUCCESS, successful); } + + public static void recordIsUserEligible(boolean eligible) { + RecordHistogram.recordBooleanHistogram(IS_USER_ELIGIBLE, eligible); + } + + public static void recordIneligibilityReason(@IneligibilityReason int reason) { + RecordHistogram.recordEnumeratedHistogram( + INELIGIBILITY_REASON, reason, IneligibilityReason.COUNT); + } }
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudMetricsUnitTest.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudMetricsUnitTest.java index 39fe82c4..98ec4ce 100644 --- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudMetricsUnitTest.java +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudMetricsUnitTest.java
@@ -30,4 +30,32 @@ ReadAloudMetrics.recordIsPageReadable(false); histogram.assertExpected(); } + + @Test + @SmallTest + public void testRecordUserEligibility() { + final String histogramName = ReadAloudMetrics.IS_USER_ELIGIBLE; + + var histogram = HistogramWatcher.newSingleRecordWatcher(histogramName, true); + ReadAloudMetrics.recordIsUserEligible(true); + histogram.assertExpected(); + + histogram = HistogramWatcher.newSingleRecordWatcher(histogramName, false); + ReadAloudMetrics.recordIsUserEligible(false); + histogram.assertExpected(); + } + + @Test + @SmallTest + public void testRecordIneligibilityReason() { + final String histogramName = ReadAloudMetrics.INELIGIBILITY_REASON; + + var histogram = HistogramWatcher.newSingleRecordWatcher(histogramName, 1); + ReadAloudMetrics.recordIneligibilityReason(1); + histogram.assertExpected(); + + histogram = HistogramWatcher.newSingleRecordWatcher(histogramName, 4); + ReadAloudMetrics.recordIneligibilityReason(4); + histogram.assertExpected(); + } }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn index 23b2b97..11b2627 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -21,7 +21,7 @@ # chromevox scripts. # # TS files to compile. -ts_modules = [] +ts_modules = [ "background/input/background_keyboard_handler.ts" ] # These files all use older Closure provide/require support for dependency management and will be transitioned to ES6 modules (see below). chromevox_modules = [ @@ -95,7 +95,6 @@ "background/input/command_handler_interface.js", "background/input/gesture_command_handler.js", "background/input/gesture_interface.js", - "background/input/keyboard_handler.js", "background/input/smart_sticky_mode.js", "background/live_regions.js", "background/logging/event_stream_logger.js", @@ -196,7 +195,23 @@ ts_library("ts_build") { root_dir = "../" out_dir = tsc_out_dir - definitions = [] + + definitions = [ + "../definitions/tts.d.ts", + "//tools/typescript/definitions/metrics_private.d.ts", + "//tools/typescript/definitions/context_menus.d.ts", + "../definitions/automation.d.ts", + "../definitions/extensions.d.ts", + "../definitions/runtime.d.ts", + "../definitions/i18n.d.ts", + "../definitions/tabs.d.ts", + "../definitions/accessibility_private_mv2.d.ts", + "../definitions/settings_private_mv2.d.ts", + "../definitions/storage_mv2.d.ts", + "../definitions/clipboard_mv2.d.ts", + "../definitions/extension_types.d.ts", + "//tools/typescript/definitions/windows.d.ts", + ] in_files = [] foreach(_js_file, js_deps) { @@ -205,6 +220,8 @@ foreach(_ts_file, ts_modules) { in_files += [ "chromevox/" + _ts_file ] } + + tsconfig_base = "../tsconfig.base.json" } group("build") { @@ -234,6 +251,7 @@ deps = [ ":ts_build", "../common:copied_files", + "../common:ts_build", ] sources = [ "background/background.html",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js index 1d8c9b5d..864c5b4a 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js
@@ -34,9 +34,9 @@ import {EventSource} from './event_source.js'; import {FindHandler} from './find_handler.js'; import {InjectedScriptLoader} from './injected_script_loader.js'; +import {BackgroundKeyboardHandler} from './input/background_keyboard_handler.js'; import {CommandHandler} from './input/command_handler.js'; import {GestureCommandHandler} from './input/gesture_command_handler.js'; -import {BackgroundKeyboardHandler} from './input/keyboard_handler.js'; import {SmartStickyMode} from './input/smart_sticky_mode.js'; import {LiveRegions} from './live_regions.js'; import {EventStreamLogger} from './logging/event_stream_logger.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js index 2c4f2aac..e5a4fab1 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js
@@ -48,7 +48,7 @@ '/chromevox/background/input/gesture_command_handler.js'), importModule( 'BackgroundKeyboardHandler', - '/chromevox/background/input/keyboard_handler.js'), + '/chromevox/background/input/background_keyboard_handler.js'), importModule('Output', '/chromevox/background/output/output.js'), importModule( 'OutputAction', '/chromevox/background/output/output_types.js'),
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/forced_action_path_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/forced_action_path_test.js index 85a00b1b..1dcf67a4 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/forced_action_path_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/forced_action_path_test.js
@@ -19,7 +19,7 @@ 'ChromeVoxRange', '/chromevox/background/chromevox_range.js'), importModule( 'BackgroundKeyboardHandler', - '/chromevox/background/input/keyboard_handler.js'), + '/chromevox/background/input/background_keyboard_handler.js'), importModule( 'ForcedActionPath', '/chromevox/background/forced_action_path.js'), importModule(
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/keyboard_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/background_keyboard_handler.ts similarity index 69% rename from chrome/browser/resources/chromeos/accessibility/chromevox/background/input/keyboard_handler.js rename to chrome/browser/resources/chromeos/accessibility/chromevox/background/input/background_keyboard_handler.ts index f7055982..0236b47 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/keyboard_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/background_keyboard_handler.ts
@@ -6,7 +6,6 @@ * @fileoverview ChromeVox keyboard handler. */ import {KeyCode} from '../../../common/key_code.js'; -import {EarconId} from '../../common/earcon_id.js'; import {EventSourceType} from '../../common/event_source_type.js'; import {ChromeVoxKbHandler} from '../../common/keyboard_handler.js'; import {Msgs} from '../../common/msgs.js'; @@ -20,36 +19,35 @@ import {ChromeVoxPrefs} from '../prefs.js'; /** - * @enum {string} * Internal pass through mode state (see usage below). - * @private */ -const KeyboardPassThroughState_ = { +enum KeyboardPassThroughState { // No pass through is in progress. - NO_PASS_THROUGH: 'no_pass_through', + NO_PASS_THROUGH = 'no_pass_through', // The pass through shortcut command has been pressed (keydowns), waiting for // user to release (keyups) all the shortcut keys. - PENDING_PASS_THROUGH_SHORTCUT_KEYUPS: 'pending_pass_through_keyups', + PENDING_PASS_THROUGH_SHORTCUT_KEYUPS = 'pending_pass_through_keyups', // The pass through shortcut command has been pressed and released, waiting // for the user to press/release a shortcut to be passed through. - PENDING_SHORTCUT_KEYUPS: 'pending_shortcut_keyups', -}; + PENDING_SHORTCUT_KEYUPS = 'pending_shortcut_keyups', +} + +class InternalKeyEvent extends KeyboardEvent { + stickyMode?: boolean; +} export class BackgroundKeyboardHandler { - /** @private */ - constructor() { - /** @private {Set} */ + static instance?: BackgroundKeyboardHandler; + private static passThroughModeEnabled_: boolean = false; + private eatenKeyDowns_: Set<number>; + private passThroughState_: KeyboardPassThroughState; + private passedThroughKeyDowns_: Set<number>; + + private constructor() { this.eatenKeyDowns_ = new Set(); - - /** @private {boolean} */ - this.passThroughModeEnabled_ = false; - - /** @private {!KeyboardPassThroughState_} */ - this.passThroughState_ = KeyboardPassThroughState_.NO_PASS_THROUGH; - - /** @private {Set} */ + this.passThroughState_ = KeyboardPassThroughState.NO_PASS_THROUGH; this.passedThroughKeyDowns_ = new Set(); document.addEventListener( @@ -60,25 +58,24 @@ true, ChromeVoxPrefs.isStickyPrefOn); } - static init() { + static init(): void { if (BackgroundKeyboardHandler.instance) { throw 'Error: trying to create two instances of singleton BackgroundKeyboardHandler.'; } BackgroundKeyboardHandler.instance = new BackgroundKeyboardHandler(); } - static enablePassThroughMode() { + static enablePassThroughMode(): void { ChromeVox.tts.speak(Msgs.getMsg('pass_through_key'), QueueMode.QUEUE); - BackgroundKeyboardHandler.instance.passThroughModeEnabled_ = true; + BackgroundKeyboardHandler.passThroughModeEnabled_ = true; } /** * Handles key down events. - * @param {Event} evt The key down event to process. - * @return {boolean} This value has no effect since we ignore it in + * The return value has no effect since we ignore it in * SpokenFeedbackEventRewriterDelegate::HandleKeyboardEvent. */ - onKeyDown(evt) { + onKeyDown(evt: InternalKeyEvent): boolean { EventSource.set(EventSourceType.STANDARD_KEYBOARD); evt.stickyMode = ChromeVoxPrefs.isStickyModeOn(); @@ -90,7 +87,7 @@ this.passedThroughKeyDowns_.clear(); } - if (this.passThroughModeEnabled_) { + if (BackgroundKeyboardHandler.passThroughModeEnabled_) { this.passedThroughKeyDowns_.add(evt.keyCode); return false; } @@ -102,9 +99,9 @@ if (!this.callOnKeyDownHandlers_(evt) || this.shouldConsumeSearchKey_(evt)) { - if (this.passThroughModeEnabled_) { + if (BackgroundKeyboardHandler.passThroughModeEnabled_) { this.passThroughState_ = - KeyboardPassThroughState_.PENDING_PASS_THROUGH_SHORTCUT_KEYUPS; + KeyboardPassThroughState.PENDING_PASS_THROUGH_SHORTCUT_KEYUPS; } evt.preventDefault(); evt.stopPropagation(); @@ -114,12 +111,8 @@ return false; } - /** - * @param {Event} evt The key down event to process. - * @return {boolean} Whether the event should continue propagating. - * @private - */ - callOnKeyDownHandlers_(evt) { + /** Returns true if the key should continue propagation. */ + private callOnKeyDownHandlers_(evt: Event): boolean { // Defer first to the math handler, if it exists, then ordinary keyboard // commands. if (!MathHandler.onKeyDown(evt)) { @@ -134,12 +127,7 @@ return ChromeVoxKbHandler.basicKeyDownActionsListener(evt); } - /** - * @param {Event} evt The key down event to evaluate. - * @return {boolean} Whether the event should be consumed. - * @private - */ - shouldConsumeSearchKey_(evt) { + private shouldConsumeSearchKey_(evt: InternalKeyEvent): boolean { // We natively always capture Search, so we have to be very careful to // either eat it here or re-inject it; otherwise, some components, like // ARC++ with TalkBack never get it. We only want to re-inject when @@ -148,49 +136,46 @@ return false; } - return Boolean(evt.metaKey) || evt.keyCode === KeyCode.SEARCH; + // TODO(accessibility): address this awkward indexing once we convert + // key_code.js to TS. + return Boolean(evt.metaKey) || evt.keyCode === KeyCode['SEARCH']; } /** - * Handles key up events. - * @param {Event} evt The key up event to process. - * @return {boolean} This value has no effect since we ignore it in + * The return value has no effect since we ignore it in * SpokenFeedbackEventRewriterDelegate::HandleKeyboardEvent. */ - onKeyUp(evt) { + onKeyUp(evt: InternalKeyEvent): boolean { if (this.eatenKeyDowns_.has(evt.keyCode)) { evt.preventDefault(); evt.stopPropagation(); this.eatenKeyDowns_.delete(evt.keyCode); } - if (this.passThroughModeEnabled_) { + if (BackgroundKeyboardHandler.passThroughModeEnabled_) { this.passedThroughKeyDowns_.delete(evt.keyCode); // Assuming we have no keys held (detected by held modifiers + keys we've // eaten in key down), we can start pass through for the next keys. if (this.passThroughState_ === - KeyboardPassThroughState_.PENDING_PASS_THROUGH_SHORTCUT_KEYUPS && + KeyboardPassThroughState.PENDING_PASS_THROUGH_SHORTCUT_KEYUPS && !evt.altKey && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && this.eatenKeyDowns_.size === 0) { // All keys of the pass through shortcut command have been released. // Ready to pass through the next shortcut. this.passThroughState_ = - KeyboardPassThroughState_.PENDING_SHORTCUT_KEYUPS; + KeyboardPassThroughState.PENDING_SHORTCUT_KEYUPS; } else if ( this.passThroughState_ === - KeyboardPassThroughState_.PENDING_SHORTCUT_KEYUPS && + KeyboardPassThroughState.PENDING_SHORTCUT_KEYUPS && this.passedThroughKeyDowns_.size === 0) { // All keys of the passed through shortcut have been released. Ready to // go back to normal processing (aka no pass through). - this.passThroughModeEnabled_ = false; - this.passThroughState_ = KeyboardPassThroughState_.NO_PASS_THROUGH; + BackgroundKeyboardHandler.passThroughModeEnabled_ = false; + this.passThroughState_ = KeyboardPassThroughState.NO_PASS_THROUGH; } } return false; } } - -/** @type {BackgroundKeyboardHandler} */ -BackgroundKeyboardHandler.instance;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/command_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/command_handler.js index 18e111b..015c2c1 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/command_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/command_handler.js
@@ -46,9 +46,9 @@ import {ChromeVoxPrefs} from '../prefs.js'; import {TtsBackground} from '../tts_background.js'; +import {BackgroundKeyboardHandler} from './background_keyboard_handler.js'; import {CommandHandlerInterface} from './command_handler_interface.js'; import {GestureInterface} from './gesture_interface.js'; -import {BackgroundKeyboardHandler} from './keyboard_handler.js'; import {SmartStickyMode} from './smart_sticky_mode.js'; const AutomationNode = chrome.automation.AutomationNode;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/keyboard_handler_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/keyboard_handler_test.js index f693f04..fc099e4c 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/keyboard_handler_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/keyboard_handler_test.js
@@ -22,7 +22,7 @@ 'ChromeVoxState', '/chromevox/background/chromevox_state.js'), importModule( 'BackgroundKeyboardHandler', - '/chromevox/background/input/keyboard_handler.js'), + '/chromevox/background/input/background_keyboard_handler.js'), importModule('KeyCode', '/common/key_code.js'), ]); @@ -57,7 +57,7 @@ 'ChromeVoxBackgroundKeyboardHandlerTest', 'PassThroughMode', async function() { await this.runWithLoadedTree('<p>test</p>'); - assertFalse(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertFalse(BackgroundKeyboardHandler.passThroughModeEnabled_); assertEquals('no_pass_through', keyboardHandler.passThroughState_); assertEquals(0, keyboardHandler.eatenKeyDowns_.size); assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); @@ -69,7 +69,7 @@ assertEquals(1, keyboardHandler.eatenKeyDowns_.size); assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); assertEquals('no_pass_through', keyboardHandler.passThroughState_); - assertFalse(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertFalse(BackgroundKeyboardHandler.passThroughModeEnabled_); const searchShift = TestUtils.createMockKeyEvent( KeyCode.SHIFT, {metaKey: true, shiftKey: true}); @@ -77,7 +77,7 @@ assertEquals(2, keyboardHandler.eatenKeyDowns_.size); assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); assertEquals('no_pass_through', keyboardHandler.passThroughState_); - assertFalse(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertFalse(BackgroundKeyboardHandler.passThroughModeEnabled_); const searchShiftEsc = TestUtils.createMockKeyEvent( KeyCode.ESCAPE, {metaKey: true, shiftKey: true}); @@ -86,14 +86,14 @@ assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); assertEquals( 'pending_pass_through_keyups', keyboardHandler.passThroughState_); - assertTrue(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertTrue(BackgroundKeyboardHandler.passThroughModeEnabled_); keyboardHandler.onKeyUp(searchShiftEsc); assertEquals(2, keyboardHandler.eatenKeyDowns_.size); assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); assertEquals( 'pending_pass_through_keyups', keyboardHandler.passThroughState_); - assertTrue(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertTrue(BackgroundKeyboardHandler.passThroughModeEnabled_); const searchShiftUp = TestUtils.createMockKeyEvent( KeyCode.SHIFT, {metaKey: true, shiftKey: false}); @@ -102,7 +102,7 @@ assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); assertEquals( 'pending_pass_through_keyups', keyboardHandler.passThroughState_); - assertTrue(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertTrue(BackgroundKeyboardHandler.passThroughModeEnabled_); const searchUp = TestUtils.createMockKeyEvent(KeyCode.SEARCH, {metaKey: false}); @@ -111,7 +111,7 @@ assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); assertEquals( 'pending_shortcut_keyups', keyboardHandler.passThroughState_); - assertTrue(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertTrue(BackgroundKeyboardHandler.passThroughModeEnabled_); // Now, the next series of key downs should be passed through. // Try Search+Ctrl+M. @@ -120,7 +120,7 @@ assertEquals(1, keyboardHandler.passedThroughKeyDowns_.size); assertEquals( 'pending_shortcut_keyups', keyboardHandler.passThroughState_); - assertTrue(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertTrue(BackgroundKeyboardHandler.passThroughModeEnabled_); const searchCtrl = TestUtils.createMockKeyEvent( KeyCode.CONTROL, {metaKey: true, ctrlKey: true}); @@ -129,7 +129,7 @@ assertEquals(2, keyboardHandler.passedThroughKeyDowns_.size); assertEquals( 'pending_shortcut_keyups', keyboardHandler.passThroughState_); - assertTrue(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertTrue(BackgroundKeyboardHandler.passThroughModeEnabled_); const searchCtrlM = TestUtils.createMockKeyEvent( KeyCode.M, {metaKey: true, ctrlKey: true}); @@ -138,27 +138,27 @@ assertEquals(3, keyboardHandler.passedThroughKeyDowns_.size); assertEquals( 'pending_shortcut_keyups', keyboardHandler.passThroughState_); - assertTrue(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertTrue(BackgroundKeyboardHandler.passThroughModeEnabled_); keyboardHandler.onKeyUp(searchCtrlM); assertEquals(0, keyboardHandler.eatenKeyDowns_.size); assertEquals(2, keyboardHandler.passedThroughKeyDowns_.size); assertEquals( 'pending_shortcut_keyups', keyboardHandler.passThroughState_); - assertTrue(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertTrue(BackgroundKeyboardHandler.passThroughModeEnabled_); keyboardHandler.onKeyUp(searchCtrl); assertEquals(0, keyboardHandler.eatenKeyDowns_.size); assertEquals(1, keyboardHandler.passedThroughKeyDowns_.size); assertEquals( 'pending_shortcut_keyups', keyboardHandler.passThroughState_); - assertTrue(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertTrue(BackgroundKeyboardHandler.passThroughModeEnabled_); keyboardHandler.onKeyUp(search); assertEquals(0, keyboardHandler.eatenKeyDowns_.size); assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); assertEquals('no_pass_through', keyboardHandler.passThroughState_); - assertFalse(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertFalse(BackgroundKeyboardHandler.passThroughModeEnabled_); }); AX_TEST_F( @@ -166,7 +166,7 @@ async function() { await this.runWithLoadedTree('<p>test</p>'); function assertNoPassThrough() { - assertFalse(BackgroundKeyboardHandler.instance.passThroughModeEnabled_); + assertFalse(BackgroundKeyboardHandler.passThroughModeEnabled_); assertEquals('no_pass_through', keyboardHandler.passThroughState_); assertEquals(0, keyboardHandler.passedThroughKeyDowns_.size); } @@ -246,7 +246,7 @@ 'UnexpectedKeyDownUpPairsPassThrough', async function() { await this.runWithLoadedTree('<p>test</p>'); // Force pass through mode. - BackgroundKeyboardHandler.instance.passThroughModeEnabled_ = true; + BackgroundKeyboardHandler.passThroughModeEnabled_ = true; // Send a few key downs (which are passed through). const search =
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js index 90d4b16..e068f7bc 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js
@@ -20,7 +20,7 @@ 'ChromeVoxRange', '/chromevox/background/chromevox_range.js'), importModule( 'BackgroundKeyboardHandler', - '/chromevox/background/input/keyboard_handler.js'), + '/chromevox/background/input/background_keyboard_handler.js'), importModule( 'CommandHandlerInterface', '/chromevox/background/input/command_handler_interface.js'),
diff --git a/chrome/browser/resources/chromeos/login/login.gni b/chrome/browser/resources/chromeos/login/login.gni index ddc2d66f..c409f1b 100644 --- a/chrome/browser/resources/chromeos/login/login.gni +++ b/chrome/browser/resources/chromeos/login/login.gni
@@ -123,7 +123,7 @@ } common_screens_js_files = [ - "screens/common/adb_sideloading.js", + "screens/common/adb_sideloading.ts", "screens/common/add_child.ts", "screens/common/app_downloading.js", "screens/common/app_launch_splash.js", @@ -132,9 +132,9 @@ "screens/common/choobe.ts", "screens/common/consolidated_consent.js", "screens/common/device_disabled.js", - "screens/common/display_size.js", + "screens/common/display_size.ts", "screens/common/drive_pinning.js", - "screens/common/enable_kiosk.js", + "screens/common/enable_kiosk.ts", "screens/common/error_message.js", "screens/common/family_link_notice.js", "screens/common/gaia_info.ts",
diff --git a/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn b/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn index 33ae5ea..f4af590 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn +++ b/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn
@@ -26,7 +26,6 @@ "js_module_root=./gen/chrome/browser/resources/gaia_auth_host", ] deps = [ - ":adb_sideloading", ":app_downloading", ":app_launch_splash", @@ -34,9 +33,7 @@ ":autolaunch", ":consolidated_consent", ":device_disabled", - ":display_size", ":drive_pinning", - ":enable_kiosk", ":error_message", ":family_link_notice", ":gaia_signin", @@ -76,16 +73,6 @@ ############################### # Closure compiler libraries below -js_library("adb_sideloading") { - sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/adb_sideloading.js" ] - deps = [ - "../../components/behaviors:login_screen_behavior", - "../../components/behaviors:multi_step_behavior", - "../../components/behaviors:oobe_i18n_behavior", - "../../components/dialogs:oobe_adaptive_dialog", - ] - extra_deps = [ ":web_components" ] -} js_library("app_downloading") { sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/app_downloading.js" ] @@ -162,20 +149,6 @@ extra_deps = [ ":web_components" ] } -js_library("display_size") { - sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/display_size.js" ] - deps = [ - "../../components:oobe_display_size_selector", - "../../components/behaviors:login_screen_behavior", - "../../components/behaviors:multi_step_behavior", - "../../components/behaviors:oobe_i18n_behavior", - "../../components/dialogs:oobe_adaptive_dialog", - ] - externs_list = - [ "//ui/webui/resources/cr_elements/cr_slider/cr_slider_externs.js" ] - extra_deps = [ ":web_components" ] -} - js_library("drive_pinning") { sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/drive_pinning.js" ] deps = [ @@ -188,17 +161,6 @@ extra_deps = [ ":web_components" ] } -js_library("enable_kiosk") { - sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/enable_kiosk.js" ] - deps = [ - "../../components/behaviors:login_screen_behavior", - "../../components/behaviors:oobe_dialog_host_behavior", - "../../components/behaviors:oobe_i18n_behavior", - "../../components/dialogs:oobe_adaptive_dialog", - ] - extra_deps = [ ":web_components" ] -} - js_library("family_link_notice") { sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/family_link_notice.js" ] deps = [
diff --git a/chrome/browser/resources/chromeos/login/screens/common/adb_sideloading.html b/chrome/browser/resources/chromeos/login/screens/common/adb_sideloading.html index 1fa0a1d..56040f3 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/adb_sideloading.html +++ b/chrome/browser/resources/chromeos/login/screens/common/adb_sideloading.html
@@ -16,7 +16,7 @@ </h1> <p slot="subtitle"> [[i18nDynamic(locale, 'enableAdbSideloadingSetupMessage')]] - <a on-click="onLearnMoreTap_" class="oobe-local-link" + <a on-click="onLearnMoreClick" class="oobe-local-link" is="action-link"> [[i18nDynamic(locale, 'enableAdbSideloadingLearnMore')]] </a> @@ -26,10 +26,10 @@ </iron-icon> </div> <div slot="bottom-buttons"> - <oobe-text-button border on-click="onCancelTap_" + <oobe-text-button border on-click="onCancelClick" text-key="enableAdbSideloadingCancelButton" id="enable-adb-sideloading-cancel-button"></oobe-text-button> - <oobe-text-button inverse on-click="onEnableTap_" class="focus-on-show" + <oobe-text-button inverse on-click="onEnableClick" class="focus-on-show" text-key="enableAdbSideloadingConfirmButton" id="enable-adb-sideloading-ok-button"></oobe-text-button> </div> @@ -45,7 +45,7 @@ </h1> <p slot="subtitle"> [[i18nDynamic(locale, 'enableAdbSideloadingErrorMessage')]] - <a on-click="onLearnMoreTap_" class="oobe-local-link" is="action-link"> + <a on-click="onLearnMoreClick" class="oobe-local-link" is="action-link"> [[i18nDynamic(locale, 'enableAdbSideloadingLearnMore')]] </a> </p> @@ -54,7 +54,7 @@ </iron-icon> </div> <div slot="bottom-buttons"> - <oobe-text-button inverse on-click="onCancelTap_" class="focus-on-show" + <oobe-text-button inverse on-click="onCancelClick" class="focus-on-show" text-key="enableAdbSideloadingOkButton"></oobe-text-button> </div> </oobe-adaptive-dialog>
diff --git a/chrome/browser/resources/chromeos/login/screens/common/adb_sideloading.js b/chrome/browser/resources/chromeos/login/screens/common/adb_sideloading.js deleted file mode 100644 index d955e64f..0000000 --- a/chrome/browser/resources/chromeos/login/screens/common/adb_sideloading.js +++ /dev/null
@@ -1,137 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview Polymer element for displaying ARC ADB sideloading screen. - */ - -import '//resources/js/action_link.js'; -import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; -import '../../components/oobe_icons.html.js'; -import '../../components/common_styles/oobe_common_styles.css.js'; -import '../../components/common_styles/oobe_dialog_host_styles.css.js'; -import '../../components/dialogs/oobe_adaptive_dialog.js'; - -import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js'; -import {MultiStepBehavior, MultiStepBehaviorInterface} from '../../components/behaviors/multi_step_behavior.js'; -import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js'; -import {OobeTextButton} from '../../components/buttons/oobe_text_button.js'; - -import {getTemplate} from './adb_sideloading.html.js'; - -/** - * UI mode for the dialog. - * @enum {string} - */ -const AdbSideloadingState = { - ERROR: 'error', - SETUP: 'setup', -}; - -/** - * The constants need to be synced with EnableAdbSideloadingScreenView::UIState - * @enum {number} - */ -const ADB_SIDELOADING_SCREEN_STATE = { - ERROR: 1, - SETUP: 2, -}; - -/** - * @constructor - * @extends {PolymerElement} - * @implements {LoginScreenBehaviorInterface} - * @implements {MultiStepBehaviorInterface} - * @implements {OobeI18nBehaviorInterface} - */ -const AdbSideloadingBase = mixinBehaviors([OobeI18nBehavior, - LoginScreenBehavior, MultiStepBehavior], PolymerElement); - -/** - * @polymer - */ -class AdbSideloading extends AdbSideloadingBase { - static get is() { - return 'adb-sideloading-element'; - } - - static get template() { - return getTemplate(); - } - - constructor() { - super(); - } - - get EXTERNAL_API() { - return ['setScreenState']; - } - - get UI_STEPS() { - return AdbSideloadingState; - } - - defaultUIStep() { - return AdbSideloadingState.SETUP; - } - - ready() { - super.ready(); - this.initializeLoginScreen('EnableAdbSideloadingScreen'); - } - - /* - * Executed on language change. - */ - updateLocalizedContent() { - this.i18nUpdateLocale(); - } - - onBeforeShow() { - this.setScreenState(ADB_SIDELOADING_SCREEN_STATE.SETUP); - } - - /** - * Sets UI state for the dialog to show corresponding content. - * @param {ADB_SIDELOADING_SCREEN_STATE} state - */ - setScreenState(state) { - if (state == ADB_SIDELOADING_SCREEN_STATE.ERROR) { - this.setUIStep(AdbSideloadingState.ERROR); - } else if (state == ADB_SIDELOADING_SCREEN_STATE.SETUP) { - this.setUIStep(AdbSideloadingState.SETUP); - } - } - - /** - * On-tap event handler for enable button. - * - * @private - */ - onEnableTap_() { - this.userActed('enable-pressed'); - } - - /** - * On-tap event handler for cancel button. - * - * @private - */ - onCancelTap_() { - this.userActed('cancel-pressed'); - } - - /** - * On-tap event handler for learn more link. - * - * @private - */ - onLearnMoreTap_() { - this.userActed('learn-more-link'); - } -} - -customElements.define(AdbSideloading.is, AdbSideloading);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/adb_sideloading.ts b/chrome/browser/resources/chromeos/login/screens/common/adb_sideloading.ts new file mode 100644 index 0000000..0906b28 --- /dev/null +++ b/chrome/browser/resources/chromeos/login/screens/common/adb_sideloading.ts
@@ -0,0 +1,135 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Polymer element for displaying ARC ADB sideloading screen. + */ + +import '//resources/js/action_link.js'; +import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; +import '../../components/buttons/oobe_text_button.js'; +import '../../components/common_styles/oobe_common_styles.css.js'; +import '../../components/common_styles/oobe_dialog_host_styles.css.js'; +import '../../components/dialogs/oobe_adaptive_dialog.js'; +import '../../components/oobe_icons.html.js'; + +import {mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js'; +import {MultiStepBehavior, MultiStepBehaviorInterface} from '../../components/behaviors/multi_step_behavior.js'; +import {OobeDialogHostBehavior, OobeDialogHostBehaviorInterface} from '../../components/behaviors/oobe_dialog_host_behavior.js'; +import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js'; + +import {getTemplate} from './adb_sideloading.html.js'; + +/** + * UI mode for the dialog. + */ +enum AdbSideloadingState { + ERROR = 'error', + SETUP = 'setup', +} + +/** + * The constants need to be synced with EnableAdbSideloadingScreenView::UIState + */ +enum AdbsideloadingScreenState { + ERROR = 1, + SETUP = 2, +} + +const AdbSideloadingBase = mixinBehaviors( + [OobeI18nBehavior, + OobeDialogHostBehavior, + LoginScreenBehavior, + MultiStepBehavior], + PolymerElement) as { new (): PolymerElement + & OobeDialogHostBehaviorInterface + & OobeI18nBehaviorInterface + & LoginScreenBehaviorInterface + & MultiStepBehaviorInterface, + }; + +export class AdbSideloading extends AdbSideloadingBase { + static get is() { + return 'adb-sideloading-element' as const; + } + + static get template(): HTMLTemplateElement { + return getTemplate(); + } + + constructor() { + super(); + } + + override get EXTERNAL_API(): string[] { + return ['setScreenState']; + } + + override get UI_STEPS() { + return AdbSideloadingState; + } + + // eslint-disable-next-line @typescript-eslint/naming-convention + override defaultUIStep() { + return AdbSideloadingState.SETUP; + } + + override ready(): void { + super.ready(); + this.initializeLoginScreen('EnableAdbSideloadingScreen'); + } + + /* + * Executed on language change. + */ + override updateLocalizedContent(): void { + this.i18nUpdateLocale(); + } + + override onBeforeShow(): void { + this.setScreenState(AdbsideloadingScreenState.SETUP); + } + + /** + * Sets UI state for the dialog to show corresponding content. + */ + setScreenState(state: AdbsideloadingScreenState): void { + if (state == AdbsideloadingScreenState.ERROR) { + this.setUIStep(AdbSideloadingState.ERROR); + } else if (state == AdbsideloadingScreenState.SETUP) { + this.setUIStep(AdbSideloadingState.SETUP); + } + } + + /** + * On-tap event handler for enable button. + */ + private onEnableClick(): void { + this.userActed('enable-pressed'); + } + + /** + * On-tap event handler for cancel button. + */ + private onCancelClick(): void { + this.userActed('cancel-pressed'); + } + + /** + * On-tap event handler for learn more link. + */ + private onLearnMoreClick(): void { + this.userActed('learn-more-link'); + } +} + +declare global { + interface HTMLElementTagNameMap { + [AdbSideloading.is]: AdbSideloading; + } +} + +customElements.define(AdbSideloading.is, AdbSideloading);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/display_size.js b/chrome/browser/resources/chromeos/login/screens/common/display_size.js deleted file mode 100644 index 60b6edd..0000000 --- a/chrome/browser/resources/chromeos/login/screens/common/display_size.js +++ /dev/null
@@ -1,135 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -/** - * @fileoverview Polymer element for touchpad scroll screen. - */ - -import '//resources/cr_elements/cr_slider/cr_slider.js'; -import '//resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js'; -import '../../components/buttons/oobe_next_button.js'; -import '../../components/buttons/oobe_text_button.js'; -import '../../components/common_styles/oobe_common_styles.css.js'; -import '../../components/common_styles/oobe_dialog_host_styles.css.js'; -import '../../components/dialogs/oobe_adaptive_dialog.js'; -import '../../components/oobe_icons.html.js'; - -import {CrSliderElement} from '//resources/cr_elements/cr_slider/cr_slider.js'; -import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js'; -import {MultiStepBehavior, MultiStepBehaviorInterface} from '../../components/behaviors/multi_step_behavior.js'; -import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js'; -import {OOBE_UI_STATE} from '../../components/display_manager_types.js'; -import {OobeDisplaySizeSelector} from '../../components/oobe_display_size_selector.js'; - -import {getTemplate} from './display_size.html.js'; - -/** - * @constructor - * @extends {PolymerElement} - * @implements {LoginScreenBehaviorInterface} - * @implements {OobeI18nBehaviorInterface} - * @implements {MultiStepBehaviorInterface} - */ -const DisplaySizeScreenElementBase = mixinBehaviors( - [OobeI18nBehavior, LoginScreenBehavior, MultiStepBehavior], PolymerElement); - -/** - * Enum to represent steps on the display size screen. - * Currently there is only one step, but we still use - * MultiStepBehavior because it provides implementation of - * things like processing 'focus-on-show' class - * @enum {string} - */ -const DisplaySizeStep = { - OVERVIEW: 'overview', -}; - -/** - * Available user actions. - * @enum {string} - */ -const UserAction = { - NEXT: 'next', - RETURN: 'return', -}; - -/** - * @typedef {{ - * sizeSelector: OobeDisplaySizeSelector, - * }} - */ -DisplaySizeScreenElementBase.$; - -/** - * Data that is passed to the screen during onBeforeShow. - * @typedef {{ - * availableSizes: Array<number>, - * currentSize: number, - * shouldShowReturn: boolean, - * }} - */ -let DisplaySizeScreenData; - -/** - * @polymer - */ -class DisplaySizeScreen extends DisplaySizeScreenElementBase { - static get is() { - return 'display-size-element'; - } - - static get template() { - return getTemplate(); - } - - static get properties() { - return { - shouldShowReturn_: { - type: Boolean, - value: false, - }, - }; - } - - get EXTERNAL_API() { - return []; - } - - get UI_STEPS() { - return DisplaySizeStep; - } - - defaultUIStep() { - return DisplaySizeStep.OVERVIEW; - } - - /** @override */ - ready() { - super.ready(); - this.initializeLoginScreen('DisplaySizeScreen'); - } - - /** - * @param {DisplaySizeScreenData} data Screen init payload. - */ - onBeforeShow(data) { - this.$.sizeSelector.init(data['availableSizes'], data['currentSize']); - this.shouldShowReturn_ = data['shouldShowReturn']; - } - - getOobeUIInitialState() { - return OOBE_UI_STATE.CHOOBE; - } - - onNextClicked_() { - this.userActed([UserAction.NEXT, this.$.sizeSelector.getSelectedSize()]); - } - - onReturnClicked_() { - this.userActed([UserAction.RETURN, this.$.sizeSelector.getSelectedSize()]); - } -} - -customElements.define(DisplaySizeScreen.is, DisplaySizeScreen);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/display_size.ts b/chrome/browser/resources/chromeos/login/screens/common/display_size.ts new file mode 100644 index 0000000..6ec5433 --- /dev/null +++ b/chrome/browser/resources/chromeos/login/screens/common/display_size.ts
@@ -0,0 +1,133 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Polymer element for touchpad scroll screen. + */ + +import '//resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js'; +import '../../components/buttons/oobe_next_button.js'; +import '../../components/buttons/oobe_text_button.js'; +import '../../components/common_styles/oobe_common_styles.css.js'; +import '../../components/common_styles/oobe_dialog_host_styles.css.js'; +import '../../components/dialogs/oobe_adaptive_dialog.js'; +import '../../components/oobe_display_size_selector.js'; +import '../../components/oobe_icons.html.js'; + +import {PolymerElementProperties} from '//resources/polymer/v3_0/polymer/interfaces.js'; +import {mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js'; +import {MultiStepBehavior, MultiStepBehaviorInterface} from '../../components/behaviors/multi_step_behavior.js'; +import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js'; +import {OOBE_UI_STATE} from '../../components/display_manager_types.js'; +import type {OobeDisplaySizeSelector} from '../../components/oobe_display_size_selector.js'; + +import {getTemplate} from './display_size.html.js'; + +export const DisplaySizeScreenElementBase = + mixinBehaviors( + [OobeI18nBehavior, LoginScreenBehavior, MultiStepBehavior], + PolymerElement) as { + new (): PolymerElement & OobeI18nBehaviorInterface & + LoginScreenBehaviorInterface & MultiStepBehaviorInterface, + }; + + +/** + * Enum to represent steps on the display size screen. + * Currently there is only one step, but we still use + * MultiStepBehavior because it provides implementation of + * things like processing 'focus-on-show' class + */ +enum DisplaySizeStep { + OVERVIEW = 'overview', +} + +/** + * Available user actions. + */ +enum UserAction { + NEXT = 'next', + RETURN = 'return', +} + +interface DisplaySizeScreenData { + availableSizes: number[]; + currentSize: number; + shouldShowReturn: boolean; +} + +class DisplaySizeScreen extends DisplaySizeScreenElementBase { + static get is() { + return 'display-size-element' as const; + } + + static get template(): HTMLTemplateElement { + return getTemplate(); + } + + static get properties(): PolymerElementProperties { + return { + shouldShowReturn_: { + type: Boolean, + value: false, + }, + }; + } + + private shouldShowReturn_: boolean; + + override get UI_STEPS() { + return DisplaySizeStep; + } + + // eslint-disable-next-line @typescript-eslint/naming-convention + override defaultUIStep() { + return DisplaySizeStep.OVERVIEW; + } + + override ready(): void { + super.ready(); + this.initializeLoginScreen('DisplaySizeScreen'); + } + + /** + * @param {DisplaySizeScreenData} data Screen init payload. + */ + onBeforeShow(data: DisplaySizeScreenData): void { + this.shadowRoot!.querySelector<OobeDisplaySizeSelector>('#sizeSelector')! + .init(data['availableSizes'], data['currentSize']); + this.shouldShowReturn_ = data['shouldShowReturn']; + } + + // eslint-disable-next-line @typescript-eslint/naming-convention + override getOobeUIInitialState(): OOBE_UI_STATE { + return OOBE_UI_STATE.CHOOBE; + } + + private onNextClicked_(): void { + this.userActed([ + UserAction.NEXT, + this.shadowRoot!.querySelector<OobeDisplaySizeSelector>( + '#sizeSelector')!.getSelectedSize(), + ]); + } + + private onReturnClicked_(): void { + this.userActed([ + UserAction.RETURN, + this.shadowRoot!.querySelector<OobeDisplaySizeSelector>( + '#sizeSelector')!.getSelectedSize(), + ]); + } +} + +declare global { + interface HTMLElementTagNameMap { + [DisplaySizeScreen.is]: DisplaySizeScreen; + } +} + +customElements.define(DisplaySizeScreen.is, DisplaySizeScreen);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/enable_kiosk.js b/chrome/browser/resources/chromeos/login/screens/common/enable_kiosk.js deleted file mode 100644 index 5b7244f..0000000 --- a/chrome/browser/resources/chromeos/login/screens/common/enable_kiosk.js +++ /dev/null
@@ -1,132 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -/** - * @fileoverview Polymer element for displaying material design Enable Kiosk - * screen. - */ - -import '//resources/cr_elements/icons.html.js'; -import '../../components/buttons/oobe_text_button.js'; -import '../../components/common_styles/oobe_dialog_host_styles.css.js'; -import '../../components/dialogs/oobe_adaptive_dialog.js'; - -import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js'; -import {OobeDialogHostBehavior} from '../../components/behaviors/oobe_dialog_host_behavior.js'; -import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js'; - -import {getTemplate} from './enable_kiosk.html.js'; - - -/** - * UI mode for the dialog. - * @enum {string} - */ -const EnableKioskMode = { - CONFIRM: 'confirm', - SUCCESS: 'success', - ERROR: 'error', -}; - -/** - * @constructor - * @extends {PolymerElement} - * @implements {LoginScreenBehaviorInterface} - * @implements {OobeI18nBehaviorInterface} - */ -const EnableKioskBase = mixinBehaviors( - [OobeI18nBehavior, OobeDialogHostBehavior, LoginScreenBehavior], - PolymerElement); - -/** - * @polymer - */ -class EnableKiosk extends EnableKioskBase { - static get is() { - return 'enable-kiosk-element'; - } - - static get template() { - return getTemplate(); - } - - static get properties() { - return { - /** - * Current dialog state - * @private - */ - state_: { - type: String, - value: EnableKioskMode.CONFIRM, - }, - }; - } - - constructor() { - super(); - } - - get EXTERNAL_API() { - return ['onCompleted']; - } - - /** @override */ - ready() { - super.ready(); - this.initializeLoginScreen('KioskEnableScreen'); - } - - /** Called after resources are updated. */ - updateLocalizedContent() { - this.i18nUpdateLocale(); - } - - /** Called when dialog is shown */ - onBeforeShow() { - this.state_ = EnableKioskMode.CONFIRM; - } - - /** - * "Enable" button handler - * @private - */ - onEnableButton_(event) { - this.userActed('enable'); - } - - /** - * "Cancel" / "Ok" button handler - * @private - */ - closeDialog_(event) { - this.userActed('close'); - } - - onCompleted(success) { - this.state_ = success ? EnableKioskMode.SUCCESS : EnableKioskMode.ERROR; - } - - /** - * Simple equality comparison function. - * @private - */ - eq_(one, another) { - return one === another; - } - - /** - * - * @private - */ - primaryButtonTextKey_(state) { - if (state === EnableKioskMode.CONFIRM) { - return 'kioskOKButton'; - } - return 'kioskCancelButton'; - } -} - -customElements.define(EnableKiosk.is, EnableKiosk);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/enable_kiosk.ts b/chrome/browser/resources/chromeos/login/screens/common/enable_kiosk.ts new file mode 100644 index 0000000..b3de59f --- /dev/null +++ b/chrome/browser/resources/chromeos/login/screens/common/enable_kiosk.ts
@@ -0,0 +1,124 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +/** + * @fileoverview Polymer element for displaying material design Enable Kiosk + * screen. + */ + +import '//resources/cr_elements/icons.html.js'; +import '../../components/buttons/oobe_text_button.js'; +import '../../components/common_styles/oobe_dialog_host_styles.css.js'; +import '../../components/dialogs/oobe_adaptive_dialog.js'; + +import {PolymerElementProperties} from '//resources/polymer/v3_0/polymer/interfaces.js'; +import {mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js'; +import {OobeDialogHostBehavior, OobeDialogHostBehaviorInterface} from '../../components/behaviors/oobe_dialog_host_behavior.js'; +import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js'; + +import {getTemplate} from './enable_kiosk.html.js'; + +/** + * UI mode for the dialog. + */ +enum EnableKioskMode { + CONFIRM = 'confirm', + SUCCESS = 'success', + ERROR = 'error', +} + +export const EnableKioskBase = + mixinBehaviors( + [OobeI18nBehavior, LoginScreenBehavior, OobeDialogHostBehavior], + PolymerElement) as { + new (): PolymerElement & OobeI18nBehaviorInterface & + LoginScreenBehaviorInterface & OobeDialogHostBehaviorInterface, + }; + +export class EnableKiosk extends EnableKioskBase { + static get is() { + return 'enable-kiosk-element' as const; + } + + static get template(): HTMLTemplateElement { + return getTemplate(); + } + + static get properties(): PolymerElementProperties { + return { + /** + * Current dialog state + */ + state_: { + value: EnableKioskMode.CONFIRM, + }, + }; + } + + private state_: EnableKioskMode; + + constructor() { + super(); + } + + override get EXTERNAL_API(): string[] { + return ['onCompleted']; + } + + override ready(): void { + super.ready(); + this.initializeLoginScreen('KioskEnableScreen'); + } + + /** Called after resources are updated. */ + override updateLocalizedContent(): void { + this.i18nUpdateLocale(); + } + + /** Called when dialog is shown */ + override onBeforeShow(): void { + this.state_ = EnableKioskMode.CONFIRM; + } + + /** + * "Enable" button handler + */ + private onEnableButton_(): void { + this.userActed('enable'); + } + + /** + * "Cancel" / "Ok" button handler + */ + private closeDialog_(): void { + this.userActed('close'); + } + + onCompleted(success: boolean): void { + this.state_ = success ? EnableKioskMode.SUCCESS : EnableKioskMode.ERROR; + } + + /** + * Simple equality comparison function. + */ + private eq_(one: EnableKioskMode, another: string): boolean { + return one === another; + } + + private primaryButtonTextKey_(state: EnableKioskMode): string { + if (state === EnableKioskMode.CONFIRM) { + return 'kioskOKButton'; + } + return 'kioskCancelButton'; + } +} + +declare global { + interface HTMLElementTagNameMap { + [EnableKiosk.is]: EnableKiosk; + } +} + +customElements.define(EnableKiosk.is, EnableKiosk);
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_page.ts b/chrome/browser/resources/settings/search_engines_page/search_engines_page.ts index 8a771f20..ed4b73a 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engines_page.ts +++ b/chrome/browser/resources/settings/search_engines_page/search_engines_page.ts
@@ -236,15 +236,8 @@ private enginesChanged_(searchEnginesInfo: SearchEnginesInfo) { this.defaultEngines = searchEnginesInfo.defaults; - - // Sort |activeEngines| and |otherEngines| in alphabetical order. - this.activeEngines = searchEnginesInfo.actives.sort( - (a, b) => a.name.toLocaleLowerCase().localeCompare( - b.name.toLocaleLowerCase())); - this.otherEngines = searchEnginesInfo.others.sort( - (a, b) => a.name.toLocaleLowerCase().localeCompare( - b.name.toLocaleLowerCase())); - + this.activeEngines = searchEnginesInfo.actives; + this.otherEngines = searchEnginesInfo.others; this.extensions = searchEnginesInfo.extensions; }
diff --git a/chrome/browser/resources/tab_search/tab_organization_results.html b/chrome/browser/resources/tab_search/tab_organization_results.html index 6382fd81..cdad951e 100644 --- a/chrome/browser/resources/tab_search/tab_organization_results.html +++ b/chrome/browser/resources/tab_search/tab_organization_results.html
@@ -13,10 +13,12 @@ --cr-input-border: 1px solid var(--color-side-panel-textfield-border); --cr-input-border-bottom: none; --cr-input-border-radius: 8px; + --cr-input-error-display: none; --cr-input-padding-bottom: 9px; --cr-input-padding-top: 9px; --cr-input-underline-display: none; - margin: 0 var(--mwb-list-item-horizontal-margin); + margin: 0 var(--mwb-list-item-horizontal-margin) + 16px var(--mwb-list-item-horizontal-margin); } cr-input:focus { @@ -52,10 +54,6 @@ min-height: var(--mwb-item-height); } - .mwb-list-item.selected { - background-color: transparent; - } - .results { background-color: var(--color-tab-search-card-background); border-radius: 8px; @@ -91,6 +89,7 @@ tabindex$="[[getTabIndex_(index, lastFocusedIndex_)]]" on-close="onTabRemove_" on-focus="onTabFocus_" + on-blur="onTabBlur_" in-suggested-group> </tab-search-item> </template>
diff --git a/chrome/browser/resources/tab_search/tab_organization_results.ts b/chrome/browser/resources/tab_search/tab_organization_results.ts index 030fe1dc..df9965a 100644 --- a/chrome/browser/resources/tab_search/tab_organization_results.ts +++ b/chrome/browser/resources/tab_search/tab_organization_results.ts
@@ -175,6 +175,13 @@ this.$.selector.selected = event.model.index; } + private onTabBlur_(_event: DomRepeatEvent<TabData>) { + // Ensure the selector deselects its current selection on blur. If + // selection should move to another element in the list, this will be done + // in onTabFocus_. + this.$.selector.selectIndex(-1); + } + private onRefreshClick_() { this.dispatchEvent(new CustomEvent('refresh-click', { bubbles: true,
diff --git a/chrome/browser/safe_browsing/download_protection/PRESUBMIT.py b/chrome/browser/safe_browsing/download_protection/PRESUBMIT.py index 6fe225a..1922034b 100644 --- a/chrome/browser/safe_browsing/download_protection/PRESUBMIT.py +++ b/chrome/browser/safe_browsing/download_protection/PRESUBMIT.py
@@ -8,7 +8,6 @@ tailored_version_file_name = 'download_request_maker.cc' version_variable_name = 'kTailoredWarningVersion' - version_variable_name_with_feature = 'kTailoredWarningVersionWithImprovedDownloadBubbleWarnings' proto_path = 'components/safe_browsing/core/common/proto/csd.proto' has_changed_proto = proto_path in input_api.change.LocalPaths() @@ -24,8 +23,7 @@ has_changed_version = False for _, line in tailored_version_files[0].ChangedContents(): - if version_variable_name in line.strip( - ) or version_variable_name_with_feature in line.strip(): + if version_variable_name in line.strip(): has_changed_version = True break
diff --git a/chrome/browser/safe_browsing/download_protection/download_request_maker.cc b/chrome/browser/safe_browsing/download_protection/download_request_maker.cc index 22f3ba1..3b4ffd1 100644 --- a/chrome/browser/safe_browsing/download_protection/download_request_maker.cc +++ b/chrome/browser/safe_browsing/download_protection/download_request_maker.cc
@@ -37,8 +37,7 @@ // changing this value. // Note: The name of this variable is checked by PRESUBMIT. Please update the // PRESUBMIT script before renaming this variable. -constexpr int kTailoredWarningVersion = 1; -constexpr int kTailoredWarningVersionWithImprovedDownloadBubbleWarnings = 3; +constexpr int kTailoredWarningVersion = 3; DownloadRequestMaker::TabUrls TabUrlsFromWebContents( content::WebContents* web_contents) { @@ -300,11 +299,7 @@ void DownloadRequestMaker::PopulateTailoredInfo() { ClientDownloadRequest::TailoredInfo tailored_info; - int version = base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings) - ? kTailoredWarningVersionWithImprovedDownloadBubbleWarnings - : kTailoredWarningVersion; - tailored_info.set_version(version); + tailored_info.set_version(kTailoredWarningVersion); *request_->mutable_tailored_info() = tailored_info; }
diff --git a/chrome/browser/safe_browsing/download_protection/download_request_maker_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_request_maker_unittest.cc index a28c4be..a5285be 100644 --- a/chrome/browser/safe_browsing/download_protection/download_request_maker_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/download_request_maker_unittest.cc
@@ -368,49 +368,6 @@ } TEST_F(DownloadRequestMakerTest, PopulateTailoredInfo) { - base::test::ScopedFeatureList features; - features.InitAndDisableFeature( - safe_browsing::kImprovedDownloadBubbleWarnings); - - base::RunLoop run_loop; - base::FilePath tmp_path(FILE_PATH_LITERAL("temp_path")); - - DownloadRequestMaker request_maker( - mock_feature_extractor_, &profile_, DownloadRequestMaker::TabUrls(), - /*target_file_path=*/base::FilePath(), tmp_path, - /*source_url=*/GURL(), - /*sha256_hash=*/"", - /*length=*/0, - /*resources=*/std::vector<ClientDownloadRequest::Resource>(), - /*is_user_initiated=*/true, - /*referrer_chain_data=*/nullptr, /*password=*/absl::nullopt, - /*previous_token=*/"", base::DoNothing()); - - EXPECT_CALL(*mock_feature_extractor_, CheckSignature(tmp_path, _)) - .WillOnce(Return()); - EXPECT_CALL(*mock_feature_extractor_, ExtractImageFeatures(tmp_path, _, _, _)) - .WillRepeatedly(Return(true)); - - std::unique_ptr<ClientDownloadRequest> request; - request_maker.Start(base::BindOnce( - [](base::RunLoop* run_loop, - std::unique_ptr<ClientDownloadRequest>* request_target, - std::unique_ptr<ClientDownloadRequest> request) { - run_loop->Quit(); - *request_target = std::move(request); - }, - &run_loop, &request)); - - run_loop.Run(); - - ASSERT_NE(request, nullptr); - EXPECT_EQ(request->tailored_info().version(), 1); -} - -TEST_F(DownloadRequestMakerTest, PopulateTailoredInfo_WithImprovedWarnings) { - base::test::ScopedFeatureList features; - features.InitAndEnableFeature(safe_browsing::kImprovedDownloadBubbleWarnings); - base::RunLoop run_loop; base::FilePath tmp_path(FILE_PATH_LITERAL("temp_path"));
diff --git a/chrome/browser/segmentation_platform/ukm_database_client.cc b/chrome/browser/segmentation_platform/ukm_database_client.cc index 29fb702d..ac01c76e 100644 --- a/chrome/browser/segmentation_platform/ukm_database_client.cc +++ b/chrome/browser/segmentation_platform/ukm_database_client.cc
@@ -50,7 +50,8 @@ DCHECK(result); ukm_data_manager_->Initialize( local_data_dir.Append(FILE_PATH_LITERAL("segmentation_platform/ukm_db")), - in_memory_database, ukm_observer_.get()); + in_memory_database); + ukm_data_manager_->StartObservation(ukm_observer_.get()); } void UkmDatabaseClient::TearDownForTesting() {
diff --git a/chrome/browser/storage_access_api/api_browsertest.cc b/chrome/browser/storage_access_api/api_browsertest.cc index 4dbb081..23d6373 100644 --- a/chrome/browser/storage_access_api/api_browsertest.cc +++ b/chrome/browser/storage_access_api/api_browsertest.cc
@@ -179,28 +179,7 @@ } virtual std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() { - std::vector<base::test::FeatureRefAndParams> enabled({ - {blink::features::kStorageAccessAPI, - { - { - blink::features::kStorageAccessAPIAutoGrantInFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIAutoDenyOutsideFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIImplicitGrantLimit.name, - "0", - }, - { - blink::features:: - kStorageAccessAPIRefreshGrantsOnUserInteraction.name, - "false", - }, - }}, - }); + std::vector<base::test::FeatureRefAndParams> enabled; if (is_storage_partitioned_) { enabled.push_back({net::features::kThirdPartyStoragePartitioning, {}}); } @@ -487,7 +466,6 @@ struct TestCase { std::string test_name; - bool saa_feature_enabled; bool permission_saa_feature_enabled; }; @@ -502,32 +480,7 @@ protected: std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { - // Use a fresh feature vector here so that kStorageAccessAPI is not enabled - // by default. std::vector<base::test::FeatureRefAndParams> enabled; - if (GetParam().saa_feature_enabled) { - enabled.push_back( - {blink::features::kStorageAccessAPI, - { - { - blink::features::kStorageAccessAPIAutoGrantInFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIAutoDenyOutsideFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIImplicitGrantLimit.name, - "0", - }, - { - blink::features:: - kStorageAccessAPIRefreshGrantsOnUserInteraction.name, - "false", - }, - }}); - } if (GetParam().permission_saa_feature_enabled) { enabled.push_back( @@ -540,9 +493,6 @@ std::vector<base::test::FeatureRef> GetDisabledFeatures() override { std::vector<base::test::FeatureRef> disabled = StorageAccessAPIBaseBrowserTest::GetDisabledFeatures(); - if (!GetParam().saa_feature_enabled) { - disabled.push_back(blink::features::kStorageAccessAPI); - } if (!GetParam().permission_saa_feature_enabled) { disabled.push_back(permissions::features::kPermissionStorageAccessAPI); @@ -552,6 +502,18 @@ } }; +class StorageAccessAPIWithPromptsBrowserTest + : public StorageAccessAPIBaseBrowserTest { + public: + StorageAccessAPIWithPromptsBrowserTest() + : StorageAccessAPIBaseBrowserTest(/* is_storage_partitioned=*/true) {} + + protected: + std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { + return {{permissions::features::kPermissionStorageAccessAPI, {}}}; + } +}; + // Check default values for permissions.query on storage-access. IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, PermissionQueryDefault) { SetBlockThirdPartyCookies(true); @@ -578,7 +540,8 @@ // Test that permissions.query changes to "granted" when a storage access // request was successful. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, PermissionQueryGranted) { +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, + PermissionQueryGranted) { SetBlockThirdPartyCookies(true); NavigateToPageWithFrame(kHostA); @@ -628,7 +591,8 @@ // Test that permissions.query changes to "denied" when a storage access // request was denied. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, PermissionQueryDenied) { +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, + PermissionQueryDenied) { SetBlockThirdPartyCookies(true); EnsureUserInteractionOn(kHostB); @@ -676,7 +640,8 @@ UnorderedElementsAre(Pair(net::SchemefulSite(GURL(kOriginB)), false))); } -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, PermissionQueryCrossSite) { +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, + PermissionQueryCrossSite) { SetBlockThirdPartyCookies(true); EnsureUserInteractionOn(kHostA); @@ -734,7 +699,7 @@ // Validate that a cross-site iframe can bypass third-party cookie blocking via // the Storage Access API. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesIFrameRequestsAccess_CrossSiteIframe) { SetBlockThirdPartyCookies(true); @@ -754,8 +719,8 @@ // Validate that if an iframe obtains access, then cookies become unblocked for // just that top-level/third-party combination and are still blocked for other // combinations. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesIFrameRequestsAccess_CrossSiteIframe_UnrelatedSites) { SetBlockThirdPartyCookies(true); base::HistogramTester histogram_tester; @@ -786,8 +751,8 @@ // Validate that a nested A(B(B)) iframe can obtain cookie access, and that that // access is not shared with the "middle" B iframe. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesIFrameRequestsAccess_NestedCrossSiteIframe_InnerRequestsAccess) { SetBlockThirdPartyCookies(true); @@ -816,7 +781,7 @@ // Validate that in a A(B) frame tree, the iframe can make credentialed // same-site requests, even if the requests are cross-origin. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesIFrameRequestsAccess_CrossOriginFetch) { SetBlockThirdPartyCookies(true); @@ -837,8 +802,8 @@ // Validate that in a A(B(B)) frame tree, the middle B iframe can obtain access, // and that access is not shared with the leaf B iframe. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesIFrameRequestsAccess_NestedCrossSiteIframe_MiddleRequestsAccess) { SetBlockThirdPartyCookies(true); @@ -866,8 +831,8 @@ // Validate that in a A(B(C)) frame tree, the C leaf iframe can obtain cookie // access. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesIFrameRequestsAccess_NestedCrossSiteIframe_DistinctSites) { SetBlockThirdPartyCookies(true); EnsureUserInteractionOn(kHostC); @@ -891,7 +856,7 @@ // Validate that cross-site sibling iframes cannot take advantage of each // other's granted permission. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesCrossSiteSiblingIFrameRequestsAccess) { EnsureUserInteractionOn(kHostC); @@ -953,7 +918,7 @@ // Validate that the Storage Access API does not override any explicit user // settings to block storage access. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesIFrameThirdPartyExceptions) { SetBlockThirdPartyCookies(true); BlockAllCookiesOnHost(kHostB); @@ -971,8 +936,8 @@ // Validate that user settings take precedence for the leaf in a A(B(B)) frame // tree. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesIFrameThirdPartyExceptions_NestedSameSite) { SetBlockThirdPartyCookies(true); BlockAllCookiesOnHost(kHostB); @@ -994,8 +959,8 @@ // Validate that user settings take precedence for the leaf in a A(B(C)) frame // tree. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesIFrameThirdPartyExceptions_NestedCrossSite) { EnsureUserInteractionOn(kHostC); @@ -1019,8 +984,8 @@ // Validate that user settings take precedence for the leaf in a A(B(A)) frame // tree. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesIFrameThirdPartyExceptions_CrossSiteAncestorChain) { EnsureUserInteractionOn(kHostA); SetBlockThirdPartyCookies(true); @@ -1044,8 +1009,8 @@ // Validate that user settings take precedence for the leaf in a A(A) frame // tree. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, ThirdPartyCookiesIFrameThirdPartyExceptions_SameSiteAncestorChain) { EnsureUserInteractionOn(kHostA); SetBlockThirdPartyCookies(true); @@ -1065,7 +1030,7 @@ } // Validates that once a grant is removed access is also removed. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, ThirdPartyGrantsDeletedAccess) { SetBlockThirdPartyCookies(true); @@ -1093,7 +1058,7 @@ // Validates that if the user explicitly blocks cookies, cookie access is // blocked even with the existing grant. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, ExplicitUserSettingsBlockThirdPartyGrantsAccess) { SetBlockThirdPartyCookies(true); @@ -1119,7 +1084,8 @@ // Validate that if the iframe's origin is opaque, it cannot obtain storage // access. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, OpaqueOriginRejects) { +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, + OpaqueOriginRejects) { SetBlockThirdPartyCookies(true); NavigateToPageWithFrame(kHostA); @@ -1137,7 +1103,7 @@ // Validate that if the iframe is sandboxed and allows scripts but is missing // the Storage Access sandbox tag, the iframe cannot obtain storage access. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, MissingSandboxTokenRejects) { SetBlockThirdPartyCookies(true); @@ -1157,7 +1123,8 @@ // Validate that if the iframe is sandboxed and has the Storage Access sandbox // tag, the iframe can obtain storage access. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, SandboxTokenResolves) { +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, + SandboxTokenResolves) { SetBlockThirdPartyCookies(true); NavigateToPageWithFrame(kHostA); @@ -1175,7 +1142,8 @@ } // Validates that expired grants don't get reused. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, ThirdPartyGrantsExpiry) { +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, + ThirdPartyGrantsExpiry) { base::HistogramTester histogram_tester; SetBlockThirdPartyCookies(true); @@ -1233,7 +1201,7 @@ // Validate that if an iframe navigates itself to a same-origin endpoint, and // that navigation does not include any cross-origin redirects, the new document // can inherit storage access. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, Navigation_SelfInitiated_SameOrigin_Preserves) { SetBlockThirdPartyCookies(true); @@ -1258,8 +1226,8 @@ // Validate that if an iframe is navigated (by a cross-site initiator) to a // same-origin endpoint, and that navigation does not include any cross-origin // redirects, the new document cannot inherit storage access. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, Navigation_NonSelfInitiated_SameOriginDestination_CrossSiteInitiator) { SetBlockThirdPartyCookies(true); @@ -1285,8 +1253,8 @@ // Validate that if an iframe is navigated (by a same-site initiator) to a // same-origin endpoint (even if the navigation does not include any // cross-origin redirects), the new document cannot inherit storage access. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, Navigation_NonSelfInitiated_SameOriginDestination_SameSiteInitiator) { SetBlockThirdPartyCookies(true); @@ -1317,8 +1285,8 @@ // same-origin endpoint (even if the navigation does not include any // cross-origin redirects, and the navigated frame has obtained storage access // already), the new document cannot inherit storage access. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, Navigation_NonSelfInitiated_SameOriginDestination_SameSiteInitiator_TargetHasStorageAccess) { SetBlockThirdPartyCookies(true); @@ -1350,7 +1318,7 @@ // Validate that if an iframe navigates itself to a same-site cross-origin // endpoint, and that navigation does not include any cross-origin redirects, // the new document cannot inherit storage access. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, Navigation_SelfInitiated_SameSiteCrossOrigin) { SetBlockThirdPartyCookies(true); @@ -1377,7 +1345,7 @@ // Validate that if an iframe navigates itself to a cross-site endpoint, and // that navigation does not include any cross-origin redirects, the new document // cannot inherit storage access. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, Navigation_SelfInitiated_CrossSite) { SetBlockThirdPartyCookies(true); @@ -1401,8 +1369,8 @@ // Validate that if an iframe navigates itself to a same-origin endpoint, but // that navigation include a cross-origin redirect, the new document // cannot inherit storage access. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, Navigation_SelfInitiated_SameOrigin_CrossOriginRedirect) { SetBlockThirdPartyCookies(true); @@ -1434,8 +1402,8 @@ // that navigation includes a cross-origin redirect (even if there's a // subsequent same-origin redirect), the new document cannot inherit storage // access. -IN_PROC_BROWSER_TEST_P( - StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F( + StorageAccessAPIWithPromptsBrowserTest, Navigation_SelfInitiated_SameOrigin_CrossSiteAndSameSiteRedirects) { SetBlockThirdPartyCookies(true); @@ -1465,7 +1433,7 @@ // Validate that in a A(A) frame tree, the inner A iframe can obtain cookie // access by default. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, EmbeddedSameOriginCookieAccess) { SetBlockThirdPartyCookies(true); @@ -1483,7 +1451,7 @@ // Validate that in a A(sub.A) frame tree, the inner A iframe can obtain cookie // access by default. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, EmbeddedSameSiteCookieAccess) { SetBlockThirdPartyCookies(true); @@ -1503,7 +1471,7 @@ // Validate that in a A(B(A)) frame tree, the inner A iframe can obtain cookie // access after requesting access. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, NestedSameOriginCookieAccess_CrossSiteAncestorChain) { base::HistogramTester histogram_tester; SetBlockThirdPartyCookies(true); @@ -1530,7 +1498,7 @@ // Validate that in a A(B(sub.A)) frame tree, the inner iframe can obtain cookie // access after requesting access. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, NestedSameSiteCookieAccess_CrossSiteAncestorChain) { SetBlockThirdPartyCookies(true); @@ -1551,7 +1519,7 @@ CookieBundle("cross-site=a.test")); } -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, DedicatedWorker_InheritsStorageAccessFromDocument) { SetBlockThirdPartyCookies(true); prompt_factory()->set_response_type( @@ -1577,7 +1545,7 @@ "cross-site=b.test"); } -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, WebsocketRequestsUseStorageAccessGrants) { net::SpawnedTestServer wss_server( net::SpawnedTestServer::TYPE_WSS, @@ -1625,53 +1593,16 @@ /* no prefix */, StorageAccessAPIBrowserTest, testing::ValuesIn<TestCase>({ - {"enable_all", true, true}, - {"enable_saa", true, false}, - {"enable_permission_saa", false, true}, + {"enable_prompts", true}, + {"disable_prompts", false}, }), [](const testing::TestParamInfo<::TestCase>& info) { return info.param.test_name; }); -class StorageAccessAPIPromptBrowserTest - : public StorageAccessAPIBaseBrowserTest, - public testing::WithParamInterface<bool> { - public: - StorageAccessAPIPromptBrowserTest() - : StorageAccessAPIBaseBrowserTest( - /*is_storage_partitioned=*/false), - is_storage_access_new_UI_(GetParam()) {} - - std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { - std::vector<base::test::FeatureRefAndParams> enabled = - StorageAccessAPIBaseBrowserTest::GetEnabledFeatures(); - - if (is_storage_access_new_UI_) { - enabled.push_back( - {permissions::features::kPermissionStorageAccessAPI, {}}); - } - - return enabled; - } - - std::vector<base::test::FeatureRef> GetDisabledFeatures() override { - std::vector<base::test::FeatureRef> disabled = - StorageAccessAPIBaseBrowserTest::GetDisabledFeatures(); - - if (!is_storage_access_new_UI_) { - disabled.push_back(permissions::features::kPermissionStorageAccessAPI); - } - - return disabled; - } - - private: - const bool is_storage_access_new_UI_; -}; - // Validate that in a A(B) frame tree, the embedded B iframe can obtain cookie // access if requested and got accepted. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIPromptBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, EmbeddedCrossSiteCookieAccess_Accept) { SetBlockThirdPartyCookies(true); @@ -1689,7 +1620,7 @@ // Validate that in a A(B) frame tree, the embedded B iframe can not obtain // cookie access if requested and got denied. -IN_PROC_BROWSER_TEST_P(StorageAccessAPIPromptBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, EmbeddedCrossSiteCookieAccess_Deny) { SetBlockThirdPartyCookies(true); @@ -1705,10 +1636,6 @@ permissions::RequestType::kStorageAccess)); } -INSTANTIATE_TEST_SUITE_P(/*no prefix*/, - StorageAccessAPIPromptBrowserTest, - testing::Bool()); - class StorageAccessAPIStorageBrowserTest : public StorageAccessAPIBaseBrowserTest, public testing::WithParamInterface<std::tuple<TestType, bool>> { @@ -1894,22 +1821,7 @@ protected: std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { - std::vector<base::test::FeatureRefAndParams> enabled = { - {blink::features::kStorageAccessAPI, - { - { - blink::features::kStorageAccessAPIAutoGrantInFPS.name, - "true", - }, - { - blink::features::kStorageAccessAPIAutoDenyOutsideFPS.name, - "true", - }, - { - blink::features::kStorageAccessAPIImplicitGrantLimit.name, - "0", - }, - }}}; + std::vector<base::test::FeatureRefAndParams> enabled = {}; if (PermissionStorageAccessAPIFeatureEnabled()) { enabled.push_back( @@ -2131,22 +2043,7 @@ : public StorageAccessAPIWithFirstPartySetsBrowserTest { protected: std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { - std::vector<base::test::FeatureRefAndParams> enabled = { - {blink::features::kStorageAccessAPI, - { - { - blink::features::kStorageAccessAPIAutoGrantInFPS.name, - "true", - }, - { - blink::features::kStorageAccessAPIAutoDenyOutsideFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIImplicitGrantLimit.name, - "0", - }, - }}}; + std::vector<base::test::FeatureRefAndParams> enabled = {}; if (PermissionStorageAccessAPIFeatureEnabled()) { enabled.push_back( @@ -2188,27 +2085,13 @@ : public StorageAccessAPIBaseBrowserTest { public: StorageAccessAPIWithFirstPartySetsAndImplicitGrantsBrowserTest() - : StorageAccessAPIBaseBrowserTest(false) {} + : StorageAccessAPIBaseBrowserTest(false) { + StorageAccessGrantPermissionContext::SetImplicitGrantLimitForTesting(5); + } protected: std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { - return { - {blink::features::kStorageAccessAPI, - { - { - blink::features::kStorageAccessAPIAutoGrantInFPS.name, - "true", - }, - { - blink::features::kStorageAccessAPIAutoDenyOutsideFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIImplicitGrantLimit.name, - "5", - }, - }}, - }; + return {}; } }; @@ -2240,15 +2123,13 @@ } class StorageAccessAPIWithPartitionedCookiesBrowserTest - : public StorageAccessAPIBaseBrowserTest { + : public StorageAccessAPIWithPromptsBrowserTest { public: - StorageAccessAPIWithPartitionedCookiesBrowserTest() - : StorageAccessAPIBaseBrowserTest( - /*is_storage_partitioned=*/false) {} + StorageAccessAPIWithPartitionedCookiesBrowserTest() = default; std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { std::vector<base::test::FeatureRefAndParams> enabled = - StorageAccessAPIBaseBrowserTest::GetEnabledFeatures(); + StorageAccessAPIWithPromptsBrowserTest::GetEnabledFeatures(); enabled.push_back({net::features::kPartitionedCookies, {}}); return enabled; } @@ -2365,7 +2246,7 @@ storage::test::ExpectStorageForFrame(GetFrame(), !ExpectPartitionedStorage()); } -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, EnsureOnePromptDenialSuffices) { SetBlockThirdPartyCookies(true); NavigateToPageWithFrame(kHostA); @@ -2399,7 +2280,7 @@ } } -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, DismissalAllowsFuturePrompts) { SetBlockThirdPartyCookies(true); NavigateToPageWithFrame(kHostA); @@ -2437,7 +2318,7 @@ } } -IN_PROC_BROWSER_TEST_P(StorageAccessAPIBrowserTest, +IN_PROC_BROWSER_TEST_F(StorageAccessAPIWithPromptsBrowserTest, TopLevelUserInteractionRequired) { SetBlockThirdPartyCookies(true); @@ -2472,30 +2353,13 @@ : public StorageAccessAPIBaseBrowserTest { public: StorageAccessAPIWithImplicitGrantsBrowserTest() - : StorageAccessAPIBaseBrowserTest(/*is_storage_partitioned=*/false) {} + : StorageAccessAPIBaseBrowserTest(/*is_storage_partitioned=*/false) { + StorageAccessGrantPermissionContext::SetImplicitGrantLimitForTesting(2); + } protected: std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { - return { - {blink::features::kStorageAccessAPI, - { - { - blink::features::kStorageAccessAPIAutoGrantInFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIAutoDenyOutsideFPS.name, - "false", - }, - { - // We use a low, but nonzero, number for the limit so that we - // can verify that implicit grants are usable, and verify what - // happens when we exceed the limit. - blink::features::kStorageAccessAPIImplicitGrantLimit.name, - "2", - }, - }}, - }; + return {}; } }; @@ -2536,56 +2400,6 @@ /*sample=*/true, 3); } -class StorageAccessAPIWithNoRequiredTopLevelInteractionBrowserTest - : public StorageAccessAPIBaseBrowserTest { - public: - StorageAccessAPIWithNoRequiredTopLevelInteractionBrowserTest() - : StorageAccessAPIBaseBrowserTest(/*is_storage_partitioned=*/false) {} - - protected: - std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { - return { - {blink::features::kStorageAccessAPI, - { - { - blink::features::kStorageAccessAPIAutoGrantInFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIAutoDenyOutsideFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPITopLevelUserInteractionBound - .name, - "0s", - }, - }}, - }; - } -}; - -IN_PROC_BROWSER_TEST_F( - StorageAccessAPIWithNoRequiredTopLevelInteractionBrowserTest, - TopLevelUserInteractionNotRequired) { - SetBlockThirdPartyCookies(true); - - // The test fixture pre-seeds kHostB with top-level user interaction, but not - // the other hosts. We intentionally use kHostA as the embed, since it has not - // been seeded with a top-level user interaction. - - NavigateToPageWithFrame(kHostB); - NavigateFrameTo(EchoCookiesURL(kHostA)); - - ASSERT_EQ(ReadCookiesAndContent(GetFrame(), kHostA), NoCookiesWithContent()); - - prompt_factory()->set_response_type( - permissions::PermissionRequestManager::ACCEPT_ALL); - - EXPECT_TRUE(storage::test::RequestAndCheckStorageAccessForFrame(GetFrame())); - EXPECT_EQ(ReadCookies(GetFrame(), kHostA), CookieBundle("cross-site=a.test")); -} - // Tests to verify that when 3p cookie is allowed, the embedded iframe can // access cookie without requesting, and no prompt is shown if the iframe makes // the request.
diff --git a/chrome/browser/storage_access_api/storage_access_api_service_impl.cc b/chrome/browser/storage_access_api/storage_access_api_service_impl.cc index 8c0d998f..f72552a 100644 --- a/chrome/browser/storage_access_api/storage_access_api_service_impl.cc +++ b/chrome/browser/storage_access_api/storage_access_api_service_impl.cc
@@ -25,16 +25,9 @@ StorageAccessAPIServiceImpl::StorageAccessAPIServiceImpl( content::BrowserContext* browser_context) : browser_context_( - raw_ref<content::BrowserContext>::from_ptr(browser_context)), - grant_refreshes_enabled_( - blink::features::kStorageAccessAPIRefreshGrantsOnUserInteraction - .Get()) { + raw_ref<content::BrowserContext>::from_ptr(browser_context)) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!grant_refreshes_enabled_) { - return; - } - periodic_timer_.Start( FROM_HERE, kTimerPeriod, base::BindRepeating(&StorageAccessAPIServiceImpl::OnPeriodicTimerFired, @@ -51,8 +44,7 @@ CHECK(!embedded_origin.opaque()); CHECK(!top_frame_origin.opaque()); - if (!grant_refreshes_enabled_ || - embedded_origin.scheme() != url::kHttpsScheme || + if (embedded_origin.scheme() != url::kHttpsScheme || top_frame_origin.scheme() != url::kHttpsScheme || !updated_grants_.Insert(embedded_origin, top_frame_origin)) { return absl::nullopt; @@ -74,7 +66,6 @@ void StorageAccessAPIServiceImpl::OnPeriodicTimerFired() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK(grant_refreshes_enabled_); updated_grants_.Clear(); }
diff --git a/chrome/browser/storage_access_api/storage_access_api_service_impl.h b/chrome/browser/storage_access_api/storage_access_api_service_impl.h index 53d986c..c1197e3 100644 --- a/chrome/browser/storage_access_api/storage_access_api_service_impl.h +++ b/chrome/browser/storage_access_api/storage_access_api_service_impl.h
@@ -60,9 +60,6 @@ // Timer to periodically update state for the associated profile. base::RepeatingTimer periodic_timer_ GUARDED_BY_CONTEXT(sequence_checker_); - // Whether grant refreshes are enabled. - const bool grant_refreshes_enabled_ GUARDED_BY_CONTEXT(sequence_checker_); - SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<StorageAccessAPIServiceImpl> weak_ptr_factory_{this};
diff --git a/chrome/browser/storage_access_api/storage_access_api_service_impl_unittest.cc b/chrome/browser/storage_access_api/storage_access_api_service_impl_unittest.cc index 4c9f59f..7fd4b2d 100644 --- a/chrome/browser/storage_access_api/storage_access_api_service_impl_unittest.cc +++ b/chrome/browser/storage_access_api/storage_access_api_service_impl_unittest.cc
@@ -196,51 +196,3 @@ EXPECT_TRUE(service->RenewPermissionGrant(origin_a, origin_b)); EXPECT_FALSE(service->RenewPermissionGrant(origin_a, origin_b)); } - -class StorageAccessAPIServiceImplWithoutRefreshTest - : public StorageAccessAPIServiceImplTest { - public: - StorageAccessAPIServiceImplWithoutRefreshTest() { - features_.InitAndEnableFeatureWithParameters( - blink::features::kStorageAccessAPI, - { - {blink::features::kStorageAccessAPIRefreshGrantsOnUserInteraction - .name, - "false"}, - }); - } - - private: - base::test::ScopedFeatureList features_; -}; - -TEST_F(StorageAccessAPIServiceImplWithoutRefreshTest, NoPeriodicTasks) { - StorageAccessAPIServiceImpl* service = - StorageAccessAPIServiceFactory::GetForBrowserContext(profile()); - ASSERT_NE(nullptr, service); - - EXPECT_FALSE(service->IsTimerRunningForTesting()); - - env().FastForwardBy(base::Hours(48)); - - EXPECT_FALSE(service->IsTimerRunningForTesting()); -} - -TEST_F(StorageAccessAPIServiceImplWithoutRefreshTest, - RenewPermissionGrant_AlwaysNoop) { - StorageAccessAPIServiceImpl* service = - StorageAccessAPIServiceFactory::GetForBrowserContext(profile()); - ASSERT_NE(nullptr, service); - - url::Origin origin_a( - url::Origin::Create(GURL(base::StrCat({"https://", kHostA})))); - url::Origin origin_b( - url::Origin::Create(GURL(base::StrCat({"https://", kHostB})))); - - EXPECT_FALSE(service->RenewPermissionGrant(origin_a, origin_b)); - - // The daily cache shouldn't make any difference here. - env().FastForwardBy(base::Hours(25)); - - EXPECT_FALSE(service->RenewPermissionGrant(origin_a, origin_b)); -}
diff --git a/chrome/browser/storage_access_api/storage_access_grant_permission_context.cc b/chrome/browser/storage_access_api/storage_access_grant_permission_context.cc index 40fa74e..e968e80 100644 --- a/chrome/browser/storage_access_api/storage_access_grant_permission_context.cc +++ b/chrome/browser/storage_access_api/storage_access_grant_permission_context.cc
@@ -25,6 +25,7 @@ #include "components/content_settings/core/common/content_settings_constraints.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/content_settings/core/common/content_settings_utils.h" +#include "components/permissions/constants.h" #include "components/permissions/features.h" #include "components/permissions/permission_request_id.h" #include "content/public/browser/browser_context.h" @@ -43,28 +44,21 @@ namespace { -// `kPermissionStorageAccessAPI` enables StorageAccessAPIwithPrompts -// (https://chromestatus.com/feature/5085655327047680). StorageAccessAPI is -// considered enabled when either feature is enabled (by different field trial -// studies). -bool StorageAccessAPIEnabled() { - return base::FeatureList::IsEnabled(blink::features::kStorageAccessAPI) || - base::FeatureList::IsEnabled( - permissions::features::kPermissionStorageAccessAPI); -} +// This is mutable for testing purposes. +static int implicit_grant_limit = 0; + +// How far back to look when requiring top-level user interaction on the +// requesting site for Storage Access API permission grants. If this value is an +// empty duration (e.g. "0s"), then no top-level user interaction is required. +constexpr base::TimeDelta kStorageAccessAPITopLevelUserInteractionBound = + base::Days(30); // `kPermissionStorageAccessAPI` enables StorageAccessAPIwithPrompts // (https://chromestatus.com/feature/5085655327047680), which should not // auto-deny if FPS is irrelevant. bool ShouldAutoDenyOutsideFPS() { - return blink::features::kStorageAccessAPIAutoDenyOutsideFPS.Get() && - !base::FeatureList::IsEnabled( - permissions::features::kPermissionStorageAccessAPI); -} - -bool NeedsFirstPartySetMetadata() { - return blink::features::kStorageAccessAPIAutoGrantInFPS.Get() || - ShouldAutoDenyOutsideFPS(); + return !base::FeatureList::IsEnabled( + permissions::features::kPermissionStorageAccessAPI); } // Returns true if the request wasn't answered by the user explicitly. @@ -141,13 +135,13 @@ switch (outcome) { case RequestOutcome::kGrantedByFirstPartySet: constraints.set_lifetime( - blink::features::kStorageAccessAPIRelatedWebsiteSetsLifetime.Get()); + permissions::kStorageAccessAPIRelatedWebsiteSetsLifetime); constraints.set_session_model( content_settings::SessionModel::NonRestorableUserSession); return constraints; case RequestOutcome::kGrantedByAllowance: constraints.set_lifetime( - blink::features::kStorageAccessAPIImplicitPermissionLifetime.Get()); + permissions::kStorageAccessAPIImplicitPermissionLifetime); constraints.set_session_model( content_settings::SessionModel::UserSession); return constraints; @@ -165,7 +159,7 @@ case RequestOutcome::kGrantedByUser: case RequestOutcome::kDeniedByUser: constraints.set_lifetime( - blink::features::kStorageAccessAPIExplicitPermissionLifetime.Get()); + permissions::kStorageAccessAPIExplicitPermissionLifetime); constraints.set_session_model(content_settings::SessionModel::Durable); return constraints; } @@ -193,6 +187,17 @@ } // namespace +// static +int StorageAccessGrantPermissionContext::GetImplicitGrantLimitForTesting() { + return implicit_grant_limit; +} + +// static +void StorageAccessGrantPermissionContext::SetImplicitGrantLimitForTesting( + int limit) { + implicit_grant_limit = limit; +} + StorageAccessGrantPermissionContext::StorageAccessGrantPermissionContext( content::BrowserContext* browser_context) : PermissionContextBase( @@ -275,24 +280,15 @@ return; } - if (!request_data.user_gesture || !StorageAccessAPIEnabled()) { - if (!request_data.user_gesture) { - rfh->AddMessageToConsole( - blink::mojom::ConsoleMessageLevel::kError, - "requestStorageAccess: Must be handling a user gesture to use."); - } + if (!request_data.user_gesture) { + rfh->AddMessageToConsole( + blink::mojom::ConsoleMessageLevel::kError, + "requestStorageAccess: Must be handling a user gesture to use."); RecordOutcomeSample(RequestOutcome::kDeniedByPrerequisites); std::move(callback).Run(CONTENT_SETTING_BLOCK); return; } - if (!NeedsFirstPartySetMetadata()) { - // First-Party Sets is disabled, or Auto-grants and auto-denials are both - // disabled, so don't bother getting First-Party Sets data. - UseImplicitGrantOrPrompt(std::move(request_data), std::move(callback)); - return; - } - first_party_sets::FirstPartySetsPolicyServiceFactory::GetForBrowserContext( browser_context()) ->ComputeFirstPartySetMetadata( @@ -307,26 +303,20 @@ permissions::PermissionRequestData request_data, permissions::BrowserPermissionCallback callback, net::FirstPartySetMetadata metadata) { - // We should only run this method if something might need the FPS metadata. - CHECK(blink::features::kStorageAccessAPIAutoGrantInFPS.Get() || - ShouldAutoDenyOutsideFPS()); - if (metadata.AreSitesInSameFirstPartySet()) { - if (blink::features::kStorageAccessAPIAutoGrantInFPS.Get()) { - switch (metadata.top_frame_entry()->site_type()) { - case net::SiteType::kPrimary: - case net::SiteType::kAssociated: - // Since the sites are in the same First-Party Set, risk of abuse due - // to allowing access is considered to be low. - NotifyPermissionSetInternal( - request_data.id, request_data.requesting_origin, - request_data.embedding_origin, std::move(callback), - /*persist=*/true, CONTENT_SETTING_ALLOW, - RequestOutcome::kGrantedByFirstPartySet); - return; - case net::SiteType::kService: - break; - } + switch (metadata.top_frame_entry()->site_type()) { + case net::SiteType::kPrimary: + case net::SiteType::kAssociated: + // Since the sites are in the same First-Party Set, risk of abuse due + // to allowing access is considered to be low. + NotifyPermissionSetInternal( + request_data.id, request_data.requesting_origin, + request_data.embedding_origin, std::move(callback), + /*persist=*/true, CONTENT_SETTING_ALLOW, + RequestOutcome::kGrantedByFirstPartySet); + return; + case net::SiteType::kService: + break; } } if (ShouldAutoDenyOutsideFPS()) { @@ -393,8 +383,7 @@ // If we have fewer grants than our limit, we can just set an implicit grant // now and skip prompting the user. - if (existing_implicit_grants < - blink::features::kStorageAccessAPIImplicitGrantLimit.Get()) { + if (existing_implicit_grants < implicit_grant_limit) { NotifyPermissionSetInternal(request_data.id, request_data.requesting_origin, request_data.embedding_origin, std::move(callback), @@ -407,8 +396,7 @@ // there's one more hurdle: the user must have interacted with the requesting // site in a top-level context recently. DIPSService* dips_service = DIPSService::Get(browser_context()); - const base::TimeDelta bound = - blink::features::kStorageAccessAPITopLevelUserInteractionBound.Get(); + const base::TimeDelta bound = kStorageAccessAPITopLevelUserInteractionBound; if (bound != base::TimeDelta() && dips_service) { GURL site = request_data.requesting_origin; dips_service->DidSiteHaveInteractionSince( @@ -466,10 +454,6 @@ content::RenderFrameHost* render_frame_host, const GURL& requesting_origin, const GURL& embedding_origin) const { - if (!StorageAccessAPIEnabled()) { - return CONTENT_SETTING_BLOCK; - } - // Permission query from top-level frame should be "granted" by default. if (render_frame_host && render_frame_host->IsInPrimaryMainFrame()) { return CONTENT_SETTING_ALLOW; @@ -532,10 +516,6 @@ RequestOutcome outcome) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!StorageAccessAPIEnabled()) { - return; - } - RecordOutcomeSample(outcome); const bool permission_allowed = (content_setting == CONTENT_SETTING_ALLOW);
diff --git a/chrome/browser/storage_access_api/storage_access_grant_permission_context.h b/chrome/browser/storage_access_api/storage_access_grant_permission_context.h index cbf197e22..d4d851a 100644 --- a/chrome/browser/storage_access_api/storage_access_grant_permission_context.h +++ b/chrome/browser/storage_access_api/storage_access_grant_permission_context.h
@@ -77,6 +77,9 @@ permissions::PermissionRequestData request_data, permissions::BrowserPermissionCallback callback); + static int GetImplicitGrantLimitForTesting(); + static void SetImplicitGrantLimitForTesting(int limit); + private: // PermissionContextBase: void DecidePermission(
diff --git a/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc b/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc index e7802db..b5e4b37 100644 --- a/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc +++ b/chrome/browser/storage_access_api/storage_access_grant_permission_context_unittest.cc
@@ -23,6 +23,7 @@ #include "components/content_settings/core/common/content_settings_constraints.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/content_settings/core/common/pref_names.h" +#include "components/permissions/constants.h" #include "components/permissions/features.h" #include "components/permissions/permission_request_id.h" #include "components/permissions/permission_request_manager.h" @@ -83,40 +84,19 @@ struct TestCase { std::string test_name; - bool saa_feature_enabled; bool permission_saa_feature_enabled; }; } // namespace -class StorageAccessGrantPermissionContextTest - : public ChromeRenderViewHostTestHarness, - public testing::WithParamInterface<TestCase> { +class StorageAccessGrantPermissionContextTestBase + : public ChromeRenderViewHostTestHarness { public: - StorageAccessGrantPermissionContextTest() { + StorageAccessGrantPermissionContextTestBase() = default; + + void SetUp() override { std::vector<base::test::FeatureRefAndParams> enabled; std::vector<base::test::FeatureRef> disabled; - if (StorageAccessAPIFeatureEnabled()) { - enabled.push_back( - {blink::features::kStorageAccessAPI, - { - { - blink::features::kStorageAccessAPIAutoGrantInFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIAutoDenyOutsideFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIImplicitGrantLimit.name, - "0", - }, - }}); - } else { - disabled.push_back(blink::features::kStorageAccessAPI); - } - if (PermissionStorageAccessAPIFeatureEnabled()) { enabled.push_back( {permissions::features::kPermissionStorageAccessAPI, {}}); @@ -124,9 +104,6 @@ disabled.push_back(permissions::features::kPermissionStorageAccessAPI); } features_.InitWithFeaturesAndParameters(enabled, disabled); - } - - void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); // Ensure we are navigated to some page so that the proper views get setup. @@ -170,12 +147,7 @@ ChromeRenderViewHostTestHarness::TearDown(); } - bool StorageAccessAPIFeatureEnabled() { - return GetParam().saa_feature_enabled; - } - bool PermissionStorageAccessAPIFeatureEnabled() { - return GetParam().permission_saa_feature_enabled; - } + virtual bool PermissionStorageAccessAPIFeatureEnabled() const = 0; std::unique_ptr<base::test::TestFuture<ContentSetting>> DecidePermission( bool user_gesture) { @@ -274,8 +246,11 @@ } }; + base::HistogramTester& histogram_tester() { return histogram_tester_; } + private: base::test::ScopedFeatureList features_; + base::HistogramTester histogram_tester_; std::unique_ptr<StorageAccessGrantPermissionContext> permission_context_; std::unique_ptr<permissions::MockPermissionPromptFactory> mock_permission_prompt_factory_; @@ -284,12 +259,28 @@ first_party_sets::ScopedMockFirstPartySetsHandler first_party_sets_handler_; }; -class StorageAccessGrantPermissionContextAPIDisabledTest - : public StorageAccessGrantPermissionContextTest { +class StorageAccessGrantPermissionContextTest + : public StorageAccessGrantPermissionContextTestBase, + public testing::WithParamInterface<TestCase> { + public: + StorageAccessGrantPermissionContextTest() = default; + + bool PermissionStorageAccessAPIFeatureEnabled() const override { + return GetParam().permission_saa_feature_enabled; + } }; -TEST_P(StorageAccessGrantPermissionContextAPIDisabledTest, - InsecureOriginsDisallowed) { +class StorageAccessGrantPermissionContextWithPromptsTest + : public StorageAccessGrantPermissionContextTestBase { + public: + StorageAccessGrantPermissionContextWithPromptsTest() = default; + + bool PermissionStorageAccessAPIFeatureEnabled() const override { + return true; + } +}; + +TEST_P(StorageAccessGrantPermissionContextTest, InsecureOriginsDisallowed) { GURL insecure_url = GURL("http://www.example.com"); EXPECT_FALSE(permission_context()->IsPermissionAvailableToOrigins( insecure_url, insecure_url)); @@ -301,62 +292,9 @@ IsEmpty()); } -// When the Storage Access API feature is disabled (the default) we -// should block the permission request. -TEST_P(StorageAccessGrantPermissionContextAPIDisabledTest, PermissionBlocked) { - EXPECT_EQ(CONTENT_SETTING_BLOCK, DecidePermissionSync(/*user_gesture=*/true)); - - EXPECT_THAT(page_specific_content_settings()->GetTwoSiteRequests( - ContentSettingsType::STORAGE_ACCESS), - IsEmpty()); -} - -// When 3p cookie access is already allowed by user-agent-specific cookie -// settings, request should be allowed even when the Storage Access API feature -// is disabled. -TEST_P(StorageAccessGrantPermissionContextAPIDisabledTest, - AllowedByCookieSettings) { - base::HistogramTester histogram_tester; - // Allow 3p cookies. - profile()->GetPrefs()->SetInteger( - prefs::kCookieControlsMode, - static_cast<int>(content_settings::CookieControlsMode::kOff)); - - // User gesture is not needed. - EXPECT_EQ(CONTENT_SETTING_ALLOW, - DecidePermissionSync(/*user_gesture=*/false)); - histogram_tester.ExpectUniqueSample( - kRequestOutcomeHistogram, RequestOutcome::kAllowedByCookieSettings, 1); - - EXPECT_THAT(page_specific_content_settings()->GetTwoSiteRequests( - ContentSettingsType::STORAGE_ACCESS), - IsEmpty()); -} - -// It's a bit odd to have a parameterized test suite only check the disabled -// case. But in this case, the test cases of API being enabled by either feature -// is already covered by StorageAccessGrantPermissionContextAPIEnabledTest. -INSTANTIATE_TEST_SUITE_P( - /* no prefix */, - StorageAccessGrantPermissionContextAPIDisabledTest, - testing::ValuesIn<TestCase>({ - {"disable_all", false, false}, - }), - StorageAccessGrantPermissionContextTest::PrintToStringParamName()); - -class StorageAccessGrantPermissionContextAPIEnabledTest - : public StorageAccessGrantPermissionContextTest { - public: - - base::HistogramTester& histogram_tester() { return histogram_tester_; } - - private: - base::HistogramTester histogram_tester_; -}; - // Test that after a successful explicit storage access grant, there's a content // setting that applies on an (embedded site, top-level site) scope. -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, +TEST_F(StorageAccessGrantPermissionContextWithPromptsTest, ExplicitGrantAcceptCrossSiteContentSettings) { // Assert that all content settings are in their initial state. CheckCrossSiteContentSettings(ContentSetting::CONTENT_SETTING_ASK); @@ -388,7 +326,7 @@ // When the Storage Access API feature is enabled and we have a user gesture we // should get a decision. -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, PermissionDecided) { +TEST_F(StorageAccessGrantPermissionContextWithPromptsTest, PermissionDecided) { auto future = DecidePermission(/*user_gesture=*/true); WaitUntilPrompt(); @@ -411,7 +349,7 @@ } // No user gesture should force a permission rejection. -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, +TEST_P(StorageAccessGrantPermissionContextTest, PermissionDeniedWithoutUserGesture) { EXPECT_EQ(CONTENT_SETTING_BLOCK, DecidePermissionSync(/*user_gesture=*/false)); @@ -423,8 +361,7 @@ IsEmpty()); } -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, - PermissionGrantReused) { +TEST_P(StorageAccessGrantPermissionContextTest, PermissionGrantReused) { auto* map = HostContentSettingsMapFactory::GetForProfile(profile()); map->SetContentSettingDefaultScope(GetRequesterURL(), GetTopLevelURL(), ContentSettingsType::STORAGE_ACCESS, @@ -437,7 +374,7 @@ UnorderedElementsAre(Pair(GetRequesterSite(), true))); } -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, BlockReused) { +TEST_P(StorageAccessGrantPermissionContextTest, BlockReused) { auto* map = HostContentSettingsMapFactory::GetForProfile(profile()); map->SetContentSettingDefaultScope(GetRequesterURL(), GetTopLevelURL(), ContentSettingsType::STORAGE_ACCESS, @@ -450,7 +387,7 @@ UnorderedElementsAre(Pair(GetRequesterSite(), true))); } -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, FpsGrantReused) { +TEST_P(StorageAccessGrantPermissionContextTest, FpsGrantReused) { auto* map = HostContentSettingsMapFactory::GetForProfile(profile()); content_settings::ContentSettingConstraints constraint; constraint.set_session_model( @@ -467,16 +404,7 @@ IsEmpty()); } -TEST_P(StorageAccessGrantPermissionContextAPIDisabledTest, - PermissionStatusBlocked) { - EXPECT_EQ(PermissionStatus::DENIED, - permission_context() - ->GetPermissionStatus(/*render_frame_host=*/nullptr, - GetRequesterURL(), GetTopLevelURL()) - .status); -} - -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, +TEST_P(StorageAccessGrantPermissionContextTest, PermissionStatusAsksWhenFeatureEnabled) { EXPECT_EQ(PermissionStatus::ASK, permission_context() @@ -488,8 +416,7 @@ // When 3p cookie access is already allowed by user-agent-specific cookie // settings, request should be allowed without granting an explicit storage // access permission. -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, - AllowedByCookieSettings) { +TEST_P(StorageAccessGrantPermissionContextTest, AllowedByCookieSettings) { // Allow 3p cookies. profile()->GetPrefs()->SetInteger( prefs::kCookieControlsMode, @@ -508,8 +435,7 @@ // When 3p cookie access is blocked by user explicitly, request should be denied // without prompting. -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, - DeniedByCookieSettings) { +TEST_P(StorageAccessGrantPermissionContextTest, DeniedByCookieSettings) { HostContentSettingsMap* settings_map = HostContentSettingsMapFactory::GetForProfile(profile()); settings_map->SetContentSettingDefaultScope( @@ -529,37 +455,18 @@ INSTANTIATE_TEST_SUITE_P( /* no prefix */, - StorageAccessGrantPermissionContextAPIEnabledTest, + StorageAccessGrantPermissionContextTest, testing::ValuesIn<TestCase>({ - {"enable_all", true, true}, - {"enable_saa", true, false}, - {"enable_permission_saa", false, true}, + {"enable_prompts", true}, + {"disable_prompts", false}, }), StorageAccessGrantPermissionContextTest::PrintToStringParamName()); class StorageAccessGrantPermissionContextAPIWithImplicitGrantsTest - : public StorageAccessGrantPermissionContextAPIEnabledTest { + : public StorageAccessGrantPermissionContextWithPromptsTest { public: StorageAccessGrantPermissionContextAPIWithImplicitGrantsTest() { - features_.InitWithFeaturesAndParameters( - /*enabled_features=*/ - {{blink::features::kStorageAccessAPI, - { - { - blink::features::kStorageAccessAPIAutoGrantInFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIAutoDenyOutsideFPS.name, - "false", - }, - { - blink::features::kStorageAccessAPIImplicitGrantLimit.name, - "5", - }, - }}}, - /*disabled_features=*/{ - permissions::features::kPermissionStorageAccessAPI}); + StorageAccessGrantPermissionContext::SetImplicitGrantLimitForTesting(5); } // Helper to request storage access on enough unique embedding_origin GURLs @@ -569,7 +476,7 @@ permissions::PermissionRequestID fake_id = CreateFakeID(); const int implicit_grant_limit = - blink::features::kStorageAccessAPIImplicitGrantLimit.Get(); + StorageAccessGrantPermissionContext::GetImplicitGrantLimitForTesting(); base::test::TestFuture<const std::vector<ContentSetting>> future; auto barrier = base::BarrierCallback<ContentSetting>(implicit_grant_limit, future.GetCallback()); @@ -586,12 +493,11 @@ } private: - base::test::ScopedFeatureList features_; }; // Validate that each requesting origin has its own implicit grant limit. If // the limit for one origin is exhausted it should not affect another. -TEST_P(StorageAccessGrantPermissionContextAPIWithImplicitGrantsTest, +TEST_F(StorageAccessGrantPermissionContextAPIWithImplicitGrantsTest, ImplicitGrantLimitPerRequestingOrigin) { histogram_tester().ExpectTotalCount(kGrantIsImplicitHistogram, 0); @@ -654,7 +560,7 @@ } // Validate that each the implicit grant limit is scoped by top-level site. -TEST_P(StorageAccessGrantPermissionContextAPIWithImplicitGrantsTest, +TEST_F(StorageAccessGrantPermissionContextAPIWithImplicitGrantsTest, ImplicitGrantLimitSiteScoping) { histogram_tester().ExpectTotalCount(kGrantIsImplicitHistogram, 0); @@ -664,7 +570,7 @@ ->NavigateAndCommit(GetDummyEmbeddingUrlWithSubdomain()); int implicit_grant_limit = - blink::features::kStorageAccessAPIImplicitGrantLimit.Get(); + StorageAccessGrantPermissionContext::GetImplicitGrantLimitForTesting(); // Although the grants are exhausted, another request from a top-level origin // that is same site with an existing grant should still be auto-granted. The @@ -687,7 +593,8 @@ IsEmpty()); } -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, ExplicitGrantDenial) { +TEST_F(StorageAccessGrantPermissionContextWithPromptsTest, + ExplicitGrantDenial) { histogram_tester().ExpectTotalCount(kGrantIsImplicitHistogram, 0); histogram_tester().ExpectTotalCount(kPromptResultHistogram, 0); @@ -711,7 +618,7 @@ UnorderedElementsAre(Pair(GetRequesterSite(), false))); } -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, +TEST_F(StorageAccessGrantPermissionContextWithPromptsTest, ExplicitGrantDenialNotExposedViaQuery) { // Set the content setting to blocked, mimicking a prompt rejection by the // user. @@ -742,7 +649,8 @@ UnorderedElementsAre(Pair(GetRequesterSite(), false))); } -TEST_P(StorageAccessGrantPermissionContextAPIEnabledTest, ExplicitGrantAccept) { +TEST_F(StorageAccessGrantPermissionContextWithPromptsTest, + ExplicitGrantAccept) { histogram_tester().ExpectTotalCount(kGrantIsImplicitHistogram, 0); histogram_tester().ExpectTotalCount(kPromptResultHistogram, 0); @@ -766,42 +674,17 @@ UnorderedElementsAre(Pair(GetRequesterSite(), true))); } -// This test suite is no-op since the enablde/disabled features are hard coded. -INSTANTIATE_TEST_SUITE_P( - /* no prefix */, - StorageAccessGrantPermissionContextAPIWithImplicitGrantsTest, - testing::ValuesIn<TestCase>({ - {"enable_saa", true, false}, - }), - StorageAccessGrantPermissionContextTest::PrintToStringParamName()); - class StorageAccessGrantPermissionContextAPIWithFirstPartySetsTest - : public StorageAccessGrantPermissionContextAPIEnabledTest { + : public StorageAccessGrantPermissionContextTestBase { public: - StorageAccessGrantPermissionContextAPIWithFirstPartySetsTest() { - features_.InitWithFeaturesAndParameters( - /*enabled_features=*/ - {{blink::features::kStorageAccessAPI, - { - { - blink::features::kStorageAccessAPIAutoGrantInFPS.name, - "true", - }, - { - blink::features::kStorageAccessAPIAutoDenyOutsideFPS.name, - "true", - }, - { - blink::features::kStorageAccessAPIImplicitGrantLimit.name, - "0", - }, - }}}, - /*disabled_features=*/{ - permissions::features::kPermissionStorageAccessAPI}); + StorageAccessGrantPermissionContextAPIWithFirstPartySetsTest() = default; + + bool PermissionStorageAccessAPIFeatureEnabled() const override { + return false; } void SetUp() override { - StorageAccessGrantPermissionContextAPIEnabledTest::SetUp(); + StorageAccessGrantPermissionContextTestBase::SetUp(); // Create a FPS with https://requester.example.com as the member and // https://embedder.com as the primary. @@ -818,11 +701,10 @@ } private: - base::test::ScopedFeatureList features_; first_party_sets::ScopedMockFirstPartySetsHandler first_party_sets_handler_; }; -TEST_P(StorageAccessGrantPermissionContextAPIWithFirstPartySetsTest, +TEST_F(StorageAccessGrantPermissionContextAPIWithFirstPartySetsTest, ImplicitGrant_AutograntedWithinFPS) { base::Time expiration_lower_bound_check = base::Time::Now(); @@ -860,18 +742,9 @@ EXPECT_NE(true, setting.IsExpired()); // Check to ensure the expiration time is in expected range. EXPECT_GT(setting.metadata.expiration(), - blink::features::kStorageAccessAPIRelatedWebsiteSetsLifetime.Get() + + permissions::kStorageAccessAPIRelatedWebsiteSetsLifetime + expiration_lower_bound_check); EXPECT_LT(setting.metadata.expiration(), - blink::features::kStorageAccessAPIRelatedWebsiteSetsLifetime.Get() + + permissions::kStorageAccessAPIRelatedWebsiteSetsLifetime + base::Time::Now()); } - -// This test suite is no-op since the enablde/disabled features are hard coded. -INSTANTIATE_TEST_SUITE_P( - /* no prefix */, - StorageAccessGrantPermissionContextAPIWithFirstPartySetsTest, - testing::ValuesIn<TestCase>({ - {"enable_saa", true, false}, - }), - StorageAccessGrantPermissionContextTest::PrintToStringParamName());
diff --git a/chrome/browser/top_level_storage_access_api/request_storage_access_for_browsertest.cc b/chrome/browser/top_level_storage_access_api/request_storage_access_for_browsertest.cc index f27cd79..6922f63c 100644 --- a/chrome/browser/top_level_storage_access_api/request_storage_access_for_browsertest.cc +++ b/chrome/browser/top_level_storage_access_api/request_storage_access_for_browsertest.cc
@@ -104,7 +104,7 @@ } virtual std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() { - return {{blink::features::kStorageAccessAPI, {}}}; + return {}; } virtual std::vector<base::test::FeatureRef> GetDisabledFeatures() { @@ -414,8 +414,7 @@ protected: std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { - return {{blink::features::kStorageAccessAPIForOriginExtension, {}}, - {blink::features::kStorageAccessAPI, {}}}; + return {{blink::features::kStorageAccessAPIForOriginExtension, {}}}; } }; @@ -784,34 +783,22 @@ // explicitly disabled, or if the larger Storage Access API is disabled, it does // not leak onto the document object. class RequestStorageAccessForExplicitlyDisabledBrowserTest - : public RequestStorageAccessForBaseBrowserTest, - public testing::WithParamInterface<bool> { + : public RequestStorageAccessForBaseBrowserTest { public: - RequestStorageAccessForExplicitlyDisabledBrowserTest() - : enable_standard_storage_access_api_(GetParam()) {} + RequestStorageAccessForExplicitlyDisabledBrowserTest() = default; protected: std::vector<base::test::FeatureRef> GetDisabledFeatures() override { - if (enable_standard_storage_access_api_) { - return {blink::features::kStorageAccessAPIForOriginExtension}; - } - return {blink::features::kStorageAccessAPI, - blink::features::kStorageAccessAPIForOriginExtension}; + return {blink::features::kStorageAccessAPIForOriginExtension}; } std::vector<base::test::FeatureRefAndParams> GetEnabledFeatures() override { - // When the standard API is enabled, return the parent class's enabled - // feature list. - if (enable_standard_storage_access_api_) { - return RequestStorageAccessForBaseBrowserTest::GetEnabledFeatures(); - } - return {}; + return RequestStorageAccessForBaseBrowserTest::GetEnabledFeatures(); } private: - bool enable_standard_storage_access_api_; }; -IN_PROC_BROWSER_TEST_P(RequestStorageAccessForExplicitlyDisabledBrowserTest, +IN_PROC_BROWSER_TEST_F(RequestStorageAccessForExplicitlyDisabledBrowserTest, RsaForOriginNotPresentOnDocumentWhenExplicitlyDisabled) { NavigateToPageWithFrame(kHostA); // Ensure that the proposed extension is not available unless explicitly @@ -821,11 +808,6 @@ .ExtractBool()); } -INSTANTIATE_TEST_SUITE_P( - /* no prefix */, - RequestStorageAccessForExplicitlyDisabledBrowserTest, - testing::Bool()); - class RequestStorageAccessForWithCHIPSBrowserTest : public RequestStorageAccessForBaseBrowserTest { public:
diff --git a/chrome/browser/top_level_storage_access_api/top_level_storage_access_permission_context.cc b/chrome/browser/top_level_storage_access_api/top_level_storage_access_permission_context.cc index 52929ef..506886f 100644 --- a/chrome/browser/top_level_storage_access_api/top_level_storage_access_permission_context.cc +++ b/chrome/browser/top_level_storage_access_api/top_level_storage_access_permission_context.cc
@@ -18,6 +18,7 @@ #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_constraints.h" #include "components/content_settings/core/common/content_settings_types.h" +#include "components/permissions/constants.h" #include "components/permissions/permission_request_id.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -227,7 +228,7 @@ content_settings::ContentSettingConstraints constraints; constraints.set_lifetime( - blink::features::kStorageAccessAPIRelatedWebsiteSetsLifetime.Get()); + permissions::kStorageAccessAPIRelatedWebsiteSetsLifetime); constraints.set_session_model( content_settings::SessionModel::NonRestorableUserSession);
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java index 74ea094..d9b363095 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java
@@ -39,7 +39,6 @@ import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; import org.chromium.chrome.browser.device.DeviceClassManager; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.lens.LensController; import org.chromium.chrome.browser.lens.LensEntryPoint; @@ -1495,8 +1494,7 @@ // the scrim on the web contents, which is not desirable. if (!mUrlFocusedWithoutAnimations || mUrlCoordinator == null - || !TextUtils.isEmpty(mUrlCoordinator.getTextWithoutAutocomplete()) - || !ChromeFeatureList.isEnabled(ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT)) { + || !TextUtils.isEmpty(mUrlCoordinator.getTextWithoutAutocomplete())) { return; } handleUrlFocusAnimation(true);
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java index 9a3edd8..f90a6cf 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediatorTest.java
@@ -84,7 +84,6 @@ import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features.DisableFeatures; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.embedder_support.util.UrlUtilities; @@ -110,7 +109,6 @@ LocationBarMediatorTest.ShadowGeolocationHeader.class, LocationBarMediatorTest.ObjectAnimatorShadow.class }) -@EnableFeatures({ChromeFeatureList.ADVANCED_PERIPHERALS_SUPPORT}) @DisableFeatures({ ChromeFeatureList.ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION_V2 })
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/settings/AdaptiveToolbarSettingsFragmentTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/settings/AdaptiveToolbarSettingsFragmentTest.java index 3323f8c..9d5fa60 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/settings/AdaptiveToolbarSettingsFragmentTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/settings/AdaptiveToolbarSettingsFragmentTest.java
@@ -87,6 +87,7 @@ AdaptiveToolbarFeatures.setProfile(mProfile); VoiceRecognitionUtil.setIsVoiceSearchEnabledForTesting(true); + UnifiedConsentServiceBridge.setUrlKeyedAnonymizedDataCollectionEnabled(true); TemplateUrlServiceFactory.setInstanceForTesting(mTemplateUrlService); } @@ -357,7 +358,6 @@ @SmallTest @EnableFeatures(ChromeFeatureList.READALOUD) public void testReadAloudOption_Enabled() { - UnifiedConsentServiceBridge.setUrlKeyedAnonymizedDataCollectionEnabled(true); FragmentScenario<AdaptiveToolbarSettingsFragment> scenario = FragmentScenario.launchInContainer( AdaptiveToolbarSettingsFragment.class,
diff --git a/chrome/browser/ui/ash/download_status/notification_display_client.cc b/chrome/browser/ui/ash/download_status/notification_display_client.cc index 36ffba1..3d87644 100644 --- a/chrome/browser/ui/ash/download_status/notification_display_client.cc +++ b/chrome/browser/ui/ash/download_status/notification_display_client.cc
@@ -4,15 +4,20 @@ #include "chrome/browser/ui/ash/download_status/notification_display_client.h" +#include <array> #include <optional> #include <utility> +#include <vector> #include "ash/constants/ash_features.h" #include "ash/constants/notifier_catalogs.h" +#include "ash/public/cpp/system_notification_builder.h" #include "base/check.h" #include "base/containers/contains.h" +#include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" #include "base/strings/strcat.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/notifications/notification_display_service.h" @@ -37,14 +42,20 @@ constexpr char kNotificationOrigin[] = "chrome://downloads"; +// The commands supported by notification buttons. +// TODO(http://b/316368295): Support pause and resume. +constexpr std::array<CommandType, 1> kButtonCommands = {CommandType::kCancel}; + // DownloadNotificationDelegate ------------------------------------------------ class DownloadNotificationDelegate : public message_center::NotificationDelegate { public: - explicit DownloadNotificationDelegate( + DownloadNotificationDelegate( + std::vector<base::RepeatingClosure> button_callbacks, base::RepeatingClosure on_closed_by_user_closure) - : on_closed_by_user_closure_(std::move(on_closed_by_user_closure)) {} + : button_callbacks_(std::move(button_callbacks)), + on_closed_by_user_closure_(std::move(on_closed_by_user_closure)) {} DownloadNotificationDelegate(const DownloadNotificationDelegate&) = delete; DownloadNotificationDelegate& operator=(const DownloadNotificationDelegate&) = delete; @@ -52,14 +63,28 @@ private: // message_center::NotificationDelegate: ~DownloadNotificationDelegate() override = default; + + void Click(const std::optional<int>& button_index, + const std::optional<std::u16string>& reply) override { + if (button_index >= 0 && button_index < button_callbacks_.size()) { + button_callbacks_[*button_index].Run(); + } + + // TODO(http://b/316368295): Handle click on the notification body. + } + void Close(bool by_user) override { if (by_user) { on_closed_by_user_closure_.Run(); } } + // Callbacks for handling button click events, listed in the order of their + // corresponding buttons. + const std::vector<base::RepeatingClosure> button_callbacks_; + // Runs when the observed notification is closed by user. - base::RepeatingClosure on_closed_by_user_closure_; + const base::RepeatingClosure on_closed_by_user_closure_; }; // Helpers --------------------------------------------------------------------- @@ -87,47 +112,60 @@ return; } - message_center::RichNotificationData rich_notification_data; - rich_notification_data.should_make_spoken_feedback_for_popup_updates = false; - rich_notification_data.vector_small_image = &kNotificationDownloadIcon; + // Get button infos from `display_metadata`. + std::vector<base::RepeatingClosure> button_callbacks; + std::vector<message_center::ButtonInfo> buttons; + for (const auto& command_info : display_metadata.command_infos) { + if (base::Contains(kButtonCommands, command_info.type)) { + button_callbacks.push_back(command_info.command_callback); + buttons.emplace_back(l10n_util::GetStringUTF16(command_info.text_id)); + } + } - // TODO(http://b/310691284): Initialize `notification` with - // `display_metadata`. - message_center::Notification notification( - message_center::NOTIFICATION_TYPE_PROGRESS, - GetNotificationIdFromGuid(guid), - display_metadata.text.value_or(std::u16string()), - /*message=*/std::u16string(), - /*icon=*/ui::ImageModel(), - /*display_source=*/ - l10n_util::GetStringUTF16(IDS_DOWNLOAD_NOTIFICATION_DISPLAY_SOURCE), - GURL(kNotificationOrigin), - message_center::NotifierId( - message_center::NotifierType::SYSTEM_COMPONENT, - kNotificationNotifierId, - NotificationCatalogName::kDownloadNotification), - rich_notification_data, - base::MakeRefCounted<DownloadNotificationDelegate>(base::BindRepeating( - &NotificationDisplayClient::OnNotificationClosedByUser, - weak_ptr_factory_.GetWeakPtr(), guid))); - notification.set_fullscreen_visibility( - message_center::FullscreenVisibility::OVER_USER); - - // Set progress related properties. + // Calculate progress from `display_metadata`. + int progress = 0; const std::optional<int64_t>& received_bytes = display_metadata.received_bytes; const std::optional<int64_t>& total_bytes = display_metadata.total_bytes; if (received_bytes >= 0 && total_bytes > 0) { - notification.set_progress(*received_bytes * 100.f / *total_bytes); + progress = *received_bytes * 100.f / *total_bytes; } else { // A negative progress value shows an indeterminate progress bar. - notification.set_progress(-1); + progress = -1; } - notification.set_progress_status( - display_metadata.secondary_text.value_or(std::u16string())); + + message_center::RichNotificationData rich_notification_data; + rich_notification_data.buttons = std::move(buttons); + rich_notification_data.fullscreen_visibility = + message_center::FullscreenVisibility::OVER_USER; + rich_notification_data.progress = progress; + rich_notification_data.progress_status = + display_metadata.secondary_text.value_or(std::u16string()); + rich_notification_data.should_make_spoken_feedback_for_popup_updates = false; + rich_notification_data.vector_small_image = &kNotificationDownloadIcon; + + message_center::Notification notification = + SystemNotificationBuilder() + .SetDelegate(base::MakeRefCounted<DownloadNotificationDelegate>( + std::move(button_callbacks), + base::BindRepeating( + &NotificationDisplayClient::OnNotificationClosedByUser, + weak_ptr_factory_.GetWeakPtr(), guid))) + .SetDisplaySource(l10n_util::GetStringUTF16( + IDS_DOWNLOAD_NOTIFICATION_DISPLAY_SOURCE)) + .SetId(GetNotificationIdFromGuid(guid)) + .SetNotifierId(message_center::NotifierId( + message_center::NotifierType::SYSTEM_COMPONENT, + kNotificationNotifierId, + NotificationCatalogName::kDownloadNotification)) + .SetOptionalFields(std::move(rich_notification_data)) + .SetOriginUrl(GURL(kNotificationOrigin)) + .SetTitle(display_metadata.text.value_or(std::u16string())) + .SetType(message_center::NOTIFICATION_TYPE_PROGRESS) + .Build(/*keep_timestamp=*/false); NotificationDisplayService::GetForProfile(profile())->Display( - NotificationHandler::Type::TRANSIENT, notification, + NotificationHandler::Type::TRANSIENT, std::move(notification), /*metadata=*/nullptr); // TODO(http://b/306459683): Change this code after `DisplayMetadata` uses a
diff --git a/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.cc b/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.cc index 7975d6e..87f1d0e 100644 --- a/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.cc +++ b/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.cc
@@ -5,37 +5,48 @@ #include <set> #include <string> #include <utility> +#include <vector> #include "ash/constants/ash_features.h" #include "ash/root_window_controller.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" +#include "ash/strings/grit/ash_strings.h" #include "ash/system/message_center/ash_message_popup_collection.h" #include "ash/system/message_center/ash_notification_view.h" +#include "ash/system/message_center/message_popup_animation_waiter.h" +#include "ash/system/notification_center/notification_center_test_api.h" #include "ash/system/notification_center/notification_center_tray.h" #include "ash/system/status_area_widget.h" #include "ash/test/view_drawn_waiter.h" +#include "base/ranges/algorithm.h" #include "base/scoped_observation.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_future.h" #include "chrome/browser/ash/crosapi/crosapi_ash.h" #include "chrome/browser/ash/crosapi/crosapi_manager.h" +#include "chrome/browser/ash/crosapi/mock_download_status_updater_client.h" #include "chrome/browser/notifications/notification_display_service.h" #include "chrome/browser/notifications/notification_display_service_factory.h" #include "chrome/browser/notifications/profile_notification.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/ash_test_util.h" +#include "chrome/browser/ui/ash/download_status/display_metadata.h" #include "chrome/browser/ui/ash/download_status/display_test_util.h" #include "chrome/test/base/in_process_browser_test.h" #include "chromeos/crosapi/mojom/download_status_updater.mojom.h" #include "content/public/test/browser_test.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "testing/gmock/include/gmock/gmock.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/message_center/public/cpp/notification.h" #include "ui/message_center/views/message_popup_view.h" #include "ui/message_center/views/notification_control_buttons_view.h" +#include "ui/views/controls/button/label_button.h" +#include "ui/views/view_utils.h" namespace ash::download_status { @@ -73,6 +84,18 @@ // Helpers --------------------------------------------------------------------- +// Returns the text ID for the given `command_type`. +int GetCommandTextId(CommandType command_type) { + switch (command_type) { + case CommandType::kCancel: + return IDS_ASH_DOWNLOAD_COMMAND_TEXT_CANCEL; + case CommandType::kPause: + return IDS_ASH_DOWNLOAD_COMMAND_TEXT_PAUSE; + case CommandType::kResume: + return IDS_ASH_DOWNLOAD_COMMAND_TEXT_RESUME; + } +} + NotificationDisplayService* GetNotificationDisplayService() { return NotificationDisplayServiceFactory::GetInstance()->GetForProfile( ProfileManager::GetActiveUserProfile()); @@ -88,6 +111,32 @@ return future.Get(); } +// Returns the notification popup view specified by 'notification_id'. Returns +// `nullptr` if such a view cannot be found. +AshNotificationView* GetPopupView(Profile* profile, + const std::string& notification_id) { + // Wait until `popup_collection` becomes idle. + AshMessagePopupCollection* const popup_collection = + Shell::GetPrimaryRootWindowController() + ->shelf() + ->GetStatusAreaWidget() + ->notification_center_tray() + ->popup_collection(); + if (!popup_collection) { + return nullptr; + } + MessagePopupAnimationWaiter(popup_collection).Wait(); + + // NOTE: The notification ID associated with the view differs from + // `notification_id` as it incorporates the profile ID. + auto* const popup_view = NotificationCenterTestApi().GetPopupViewForId( + ProfileNotification::GetProfileNotificationId( + notification_id, ProfileNotification::GetProfileID(profile))); + return popup_view ? views::AsViewClass<AshNotificationView>( + popup_view->message_view()) + : nullptr; +} + } // namespace class NotificationDisplayClientBrowserTest : public InProcessBrowserTest { @@ -103,6 +152,10 @@ download_status_updater_remote_.FlushForTesting(); } + crosapi::MockDownloadStatusUpdaterClient& download_status_updater_client() { + return download_status_updater_client_; + } + MockNotificationDisplayServiceObserver& service_observer() { return service_observer_; } @@ -114,6 +167,11 @@ crosapi::CrosapiManager::Get()->crosapi_ash()->BindDownloadStatusUpdater( download_status_updater_remote_.BindNewPipeAndPassReceiver()); + download_status_updater_remote_->BindClient( + download_status_updater_client_receiver_ + .BindNewPipeAndPassRemoteWithVersion()); + download_status_updater_remote_.FlushForTesting(); + service_observation_.Observe(GetNotificationDisplayService()); } @@ -129,25 +187,90 @@ base::ScopedObservation<NotificationDisplayService, NotificationDisplayService::Observer> service_observation_{&service_observer_}; + + // The client bound to the download status updater under test. + crosapi::MockDownloadStatusUpdaterClient download_status_updater_client_; + mojo::Receiver<crosapi::mojom::DownloadStatusUpdaterClient> + download_status_updater_client_receiver_{ + &download_status_updater_client_}; }; // Verifies that when an in-progress download is cancelled, its notification // should be removed. IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest, CancelDownload) { + // Add a download that is not cancellable. Cache the notification ID. + Profile* const profile = ProfileManager::GetActiveUserProfile(); std::string notification_id; EXPECT_CALL(service_observer(), OnNotificationDisplayed) .WillOnce(WithArg<0>( [¬ification_id](const message_center::Notification& notification) { notification_id = notification.id(); })); - crosapi::mojom::DownloadStatusPtr download = CreateInProgressDownloadStatus( - ProfileManager::GetActiveUserProfile(), /*received_bytes=*/0, - /*target_bytes=*/1024); - Update(download->Clone()); + crosapi::mojom::DownloadStatusPtr uncancellable_download = + CreateInProgressDownloadStatus(profile, + /*received_bytes=*/0, + /*target_bytes=*/1024); + uncancellable_download->cancellable = false; + Update(uncancellable_download->Clone()); Mock::VerifyAndClearExpectations(&service_observer()); - download->state = crosapi::mojom::DownloadState::kCancelled; - Update(download->Clone()); + // Check that the notification view of `uncancellable_download` does not have + // a cancel button. + AshNotificationView* const uncancellable_download_notification = + GetPopupView(profile, notification_id); + ASSERT_TRUE(uncancellable_download_notification); + std::vector<views::LabelButton*> action_buttons = + uncancellable_download_notification->GetActionButtonsForTest(); + const std::u16string cancel_button_text = + l10n_util::GetStringUTF16(GetCommandTextId(CommandType::kCancel)); + auto cancel_button_iter = base::ranges::find( + action_buttons, cancel_button_text, &views::LabelButton::GetText); + EXPECT_EQ(cancel_button_iter, action_buttons.end()); + + // Add a cancellable download. Cache the notification ID. + EXPECT_CALL(service_observer(), OnNotificationDisplayed) + .WillOnce(WithArg<0>( + [¬ification_id](const message_center::Notification& notification) { + notification_id = notification.id(); + })); + crosapi::mojom::DownloadStatusPtr cancellable_download = + CreateInProgressDownloadStatus(profile, + /*received_bytes=*/0, + /*target_bytes=*/1024); + cancellable_download->cancellable = true; + Update(cancellable_download->Clone()); + Mock::VerifyAndClearExpectations(&service_observer()); + + // Implement download cancellation for the mock client. + base::RunLoop run_loop; + ON_CALL(download_status_updater_client(), + Cancel(cancellable_download->guid, _)) + .WillByDefault( + [&](const std::string& guid, + crosapi::MockDownloadStatusUpdaterClient::CancelCallback + callback) { + cancellable_download->cancellable = false; + cancellable_download->state = + crosapi::mojom::DownloadState::kCancelled; + Update(cancellable_download->Clone()); + std::move(callback).Run(/*handled=*/true); + run_loop.Quit(); + }); + + // Get the cancel button. + AshNotificationView* const cancellable_download_notification = + GetPopupView(profile, notification_id); + ASSERT_TRUE(cancellable_download_notification); + action_buttons = cancellable_download_notification->GetActionButtonsForTest(); + cancel_button_iter = base::ranges::find(action_buttons, cancel_button_text, + &views::LabelButton::GetText); + ASSERT_NE(cancel_button_iter, action_buttons.end()); + + // Click on the cancel button and wait until download is cancelled. + test::Click(*cancel_button_iter, ui::EF_NONE); + run_loop.Run(); + + // After download cancellation, the associated notification should be removed. EXPECT_THAT(GetDisplayedNotificationIds(), Not(Contains(notification_id))); } @@ -252,35 +375,16 @@ Update(download->Clone()); Mock::VerifyAndClearExpectations(&service_observer()); - // Wait until `popup_collection` becomes idle. - AshMessagePopupCollection* const popup_collection = - Shell::GetPrimaryRootWindowController() - ->shelf() - ->GetStatusAreaWidget() - ->notification_center_tray() - ->popup_collection(); - base::test::TestFuture<void> future; - popup_collection->SetAnimationIdleClosureForTest(future.GetCallback()); - future.Get(); + AshNotificationView* const notification_view = + GetPopupView(profile, notification_id); + ASSERT_TRUE(notification_view); - // NOTE: The notification ID associated with the view differs from - // `notification_id` as it incorporates the profile ID. - message_center::MessagePopupView* const popup_view = - popup_collection->GetPopupViewForNotificationID( - ProfileNotification::GetProfileNotificationId( - notification_id, ProfileNotification::GetProfileID(profile))); - ASSERT_TRUE(popup_view); - message_center::MessageView* const message_view = popup_view->message_view(); - ASSERT_TRUE(message_view); - - // Move mouse to `message_view` until `close_button` shows and then click + // Move mouse to `notification_view` until `close_button` shows and then click // `close_button` to remove the notification associated with // `notification_id`. - test::MoveMouseTo(message_view); + test::MoveMouseTo(notification_view); views::View* const close_button = - views::AsViewClass<AshNotificationView>(message_view) - ->control_buttons_view_for_test() - ->close_button(); + notification_view->control_buttons_view_for_test()->close_button(); ViewDrawnWaiter().Wait(close_button); test::Click(close_button, ui::EF_NONE);
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index d8dea9e..b322dde 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -358,7 +358,8 @@ ChromeAutofillClient::GetPaymentsAutofillClient() { if (!payments_autofill_client_) { payments_autofill_client_ = - std::make_unique<payments::ChromePaymentsAutofillClient>(); + std::make_unique<payments::ChromePaymentsAutofillClient>( + web_contents()); } return payments_autofill_client_.get(); }
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 a656c81..137b872 100644 --- a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc +++ b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc
@@ -4,9 +4,15 @@ #include "chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" + namespace autofill::payments { -ChromePaymentsAutofillClient::ChromePaymentsAutofillClient() = default; +ChromePaymentsAutofillClient::ChromePaymentsAutofillClient( + content::WebContents* web_contents) { + content::WebContentsObserver::Observe(web_contents); +} ChromePaymentsAutofillClient::~ChromePaymentsAutofillClient() = default;
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 baa28bff..9fb2a10 100644 --- a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h +++ b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h
@@ -7,14 +7,18 @@ #include "components/autofill/core/browser/payments/payments_autofill_client.h" +#include "content/public/browser/web_contents_observer.h" + namespace autofill::payments { // Chrome implementation of PaymentsAutofillClient. Used for Chrome Desktop and // Clank. Owned by the ChromeAutofillClient. Created lazily in the -// ChromeAutofillClient when it is needed. -class ChromePaymentsAutofillClient : public PaymentsAutofillClient { +// ChromeAutofillClient when it is needed, and it observes the same WebContents +// as its owning ChromeAutofillClient. +class ChromePaymentsAutofillClient : public PaymentsAutofillClient, + public content::WebContentsObserver { public: - ChromePaymentsAutofillClient(); + explicit ChromePaymentsAutofillClient(content::WebContents* web_contents); ChromePaymentsAutofillClient(const ChromePaymentsAutofillClient&) = delete; ChromePaymentsAutofillClient& operator=(const ChromePaymentsAutofillClient&) = delete;
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 2cc6c9d..4f4f15f 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -1285,6 +1285,8 @@ !guest_session); command_updater_.UpdateCommandEnabled(IDC_SHOW_PASSWORD_MANAGER, !guest_session); + command_updater_.UpdateCommandEnabled(IDC_SHOW_PASSWORD_CHECKUP, + !guest_session); command_updater_.UpdateCommandEnabled(IDC_SHOW_PAYMENT_METHODS, !guest_session); command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETTINGS, true);
diff --git a/chrome/browser/ui/color/BUILD.gn b/chrome/browser/ui/color/BUILD.gn index 2e6e358..20cb2ca 100644 --- a/chrome/browser/ui/color/BUILD.gn +++ b/chrome/browser/ui/color/BUILD.gn
@@ -54,7 +54,6 @@ "//chrome/common/themes:autogenerated_theme_util", "//components/compose:buildflags", "//components/omnibox/common:common", - "//components/safe_browsing/core/common:common", "//components/search:search", "//ui/base:buildflags", "//ui/color:color",
diff --git a/chrome/browser/ui/color/chrome_color_mixer.cc b/chrome/browser/ui/color/chrome_color_mixer.cc index 39cf739..16b2e742 100644 --- a/chrome/browser/ui/color/chrome_color_mixer.cc +++ b/chrome/browser/ui/color/chrome_color_mixer.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/ui/color/chrome_color_provider_utils.h" #include "chrome_color_id.h" #include "components/omnibox/common/omnibox_features.h" -#include "components/safe_browsing/core/common/features.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/ui_base_features.h" #include "ui/color/color_id.h" @@ -171,20 +170,12 @@ ui::kColorAlertLowSeverity, kColorDownloadShelfBackground, color_utils::kMinimumReadableContrastRatio); mixer[kColorDownloadItemIconDangerous] = {ui::kColorAlertHighSeverity}; - mixer[kColorDownloadItemIconWarning] = { - base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings) - ? ui::kColorSecondaryForeground - : ui::kColorAlertMediumSeverityIcon}; + mixer[kColorDownloadItemIconWarning] = {ui::kColorSecondaryForeground}; mixer[kColorDownloadItemProgressRingBackground] = ui::SetAlpha( kColorDownloadItemProgressRingForeground, gfx::kGoogleGreyAlpha400); mixer[kColorDownloadItemProgressRingForeground] = {ui::kColorThrobber}; mixer[kColorDownloadItemTextDangerous] = {ui::kColorAlertHighSeverity}; - mixer[kColorDownloadItemTextWarning] = { - base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings) - ? ui::kColorSecondaryForeground - : ui::kColorAlertMediumSeverityText}; + mixer[kColorDownloadItemTextWarning] = {ui::kColorSecondaryForeground}; mixer[kColorDownloadShelfBackground] = {kColorToolbar}; mixer[kColorDownloadShelfButtonBackground] = {kColorDownloadShelfBackground}; mixer[kColorDownloadShelfButtonIcon] = {kColorToolbarButtonIcon};
diff --git a/chrome/browser/ui/color/material_chrome_color_mixer.cc b/chrome/browser/ui/color/material_chrome_color_mixer.cc index 3bf7112..bcbbca55 100644 --- a/chrome/browser/ui/color/material_chrome_color_mixer.cc +++ b/chrome/browser/ui/color/material_chrome_color_mixer.cc
@@ -8,7 +8,6 @@ #include "chrome/browser/ui/color/chrome_color_provider_utils.h" #include "chrome/grit/theme_resources.h" #include "components/compose/buildflags.h" -#include "components/safe_browsing/core/common/features.h" #include "ui/color/color_id.h" #include "ui/color/color_mixer.h" #include "ui/color/color_provider.h" @@ -196,22 +195,10 @@ kColorDownloadShelfBackground), kColorDownloadShelfBackground); mixer[kColorDownloadItemIconDangerous] = {ui::kColorSysError}; - // TODO(crbug.com/1399939): use a yellow-ish CR2023 color instead for the - // non-ImprovedDownloadBubbleWarnings case. - mixer[kColorDownloadItemIconWarning] = { - base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings) - ? ui::kColorSysOnSurfaceSubtle - : ui::kColorAlertMediumSeverityIcon}; + mixer[kColorDownloadItemIconWarning] = {ui::kColorSysOnSurfaceSubtle}; mixer[kColorDownloadItemProgressRingForeground] = {ui::kColorSysPrimary}; mixer[kColorDownloadItemTextDangerous] = {ui::kColorSysError}; - // TODO(crbug.com/1399939): use a yellow-ish CR2023 color instead for the - // non-ImprovedDownloadBubbleWarnings case. - mixer[kColorDownloadItemTextWarning] = { - base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings) - ? ui::kColorSysOnSurfaceSubtle - : ui::kColorAlertMediumSeverityText}; + mixer[kColorDownloadItemTextWarning] = {ui::kColorSysOnSurfaceSubtle}; mixer[kColorDownloadShelfBackground] = {ui::kColorSysBase}; mixer[kColorDownloadShelfButtonIcon] = {kColorDownloadShelfForeground}; mixer[kColorDownloadShelfButtonIconDisabled] = {ui::kColorSysStateDisabled};
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index a69b1a3..25c63913 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -53,6 +53,7 @@ #include "components/content_settings/core/common/content_settings_utils.h" #include "components/custom_handlers/protocol_handler_registry.h" #include "components/infobars/content/content_infobar_manager.h" +#include "components/permissions/constants.h" #include "components/permissions/permission_decision_auto_blocker.h" #include "components/permissions/permission_request_manager.h" #include "components/permissions/permission_uma_util.h" @@ -777,7 +778,7 @@ auto* map = HostContentSettingsMapFactory::GetForProfile(GetProfile()); content_settings::ContentSettingConstraints constraints; constraints.set_lifetime( - blink::features::kStorageAccessAPIExplicitPermissionLifetime.Get()); + permissions::kStorageAccessAPIExplicitPermissionLifetime); map->SetNarrowestContentSetting(primary, secondary, ContentSettingsType::STORAGE_ACCESS, setting, constraints);
diff --git a/chrome/browser/ui/download/download_bubble_row_view_info.cc b/chrome/browser/ui/download/download_bubble_row_view_info.cc index 74eca17..2c027cc 100644 --- a/chrome/browser/ui/download/download_bubble_row_view_info.cc +++ b/chrome/browser/ui/download/download_bubble_row_view_info.cc
@@ -15,7 +15,6 @@ #include "chrome/browser/ui/download/download_item_mode.h" #include "chrome/grit/generated_resources.h" #include "components/download/public/common/download_danger_type.h" -#include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "components/vector_icons/vector_icons.h" #include "ui/base/l10n/l10n_util.h" @@ -151,85 +150,27 @@ switch (model_->GetDangerType()) { case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: if (model_->IsExtensionDownload()) { - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - PopulateSuspiciousUiPattern(); - return; - } - has_subpage_ = true; - icon_override_ = features::IsChromeRefresh2023() - ? &kDownloadWarningIcon - : &vector_icons::kNotSecureWarningIcon; - secondary_color_ = kColorDownloadItemIconWarning; - secondary_text_color_ = kColorDownloadItemTextWarning; + PopulateSuspiciousUiPattern(); return; } else { - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - if (WasSafeBrowsingVerdictObtained(model_->GetDownloadItem())) { - PopulateSuspiciousUiPattern(); - return; - } - if (ShouldShowWarningForNoSafeBrowsing(model_->profile())) { - PopulateForFileTypeWarningNoSafeBrowsing(); - return; - } + if (WasSafeBrowsingVerdictObtained(model_->GetDownloadItem())) { PopulateSuspiciousUiPattern(); return; } - - has_subpage_ = true; - icon_override_ = features::IsChromeRefresh2023() - ? &kDownloadWarningIcon - : &vector_icons::kNotSecureWarningIcon; - secondary_color_ = ui::kColorSecondaryForeground; - primary_button_command_ = DownloadCommands::Command::KEEP; + if (ShouldShowWarningForNoSafeBrowsing(model_->profile())) { + PopulateForFileTypeWarningNoSafeBrowsing(); + return; + } + PopulateSuspiciousUiPattern(); return; } case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT: case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE: - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - PopulateDangerousUiPattern(); - return; - } else { - has_subpage_ = true; - icon_override_ = features::IsChromeRefresh2023() - ? &vector_icons::kDangerousChromeRefreshIcon - : &vector_icons::kDangerousIcon; - secondary_color_ = kColorDownloadItemIconDangerous; - primary_button_command_ = DownloadCommands::Command::DISCARD; - return; - } case download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - PopulateDangerousUiPattern(); - return; - } else { - has_subpage_ = true; - icon_override_ = features::IsChromeRefresh2023() - ? &kDownloadWarningIcon - : &vector_icons::kNotSecureWarningIcon; - secondary_color_ = kColorDownloadItemIconWarning; - secondary_text_color_ = kColorDownloadItemTextWarning; - primary_button_command_ = DownloadCommands::Command::DISCARD; - return; - } case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - return PopulateDangerousUiPattern(); - } else { - has_subpage_ = true; - icon_override_ = features::IsChromeRefresh2023() - ? &kDownloadWarningIcon - : &vector_icons::kNotSecureWarningIcon; - secondary_color_ = kColorDownloadItemIconDangerous; - primary_button_command_ = DownloadCommands::Command::DISCARD; - return; - } + PopulateDangerousUiPattern(); + return; case download::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: { bool request_ap_verdicts = false; #if BUILDFLAG(FULL_SAFE_BROWSING) @@ -247,18 +188,7 @@ secondary_text_color_ = kColorDownloadItemTextWarning; return; } else { - if (base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings)) { - PopulateSuspiciousUiPattern(); - return; - } - has_subpage_ = true; - icon_override_ = features::IsChromeRefresh2023() - ? &kDownloadWarningIcon - : &vector_icons::kNotSecureWarningIcon; - secondary_color_ = kColorDownloadItemIconWarning; - secondary_text_color_ = kColorDownloadItemTextWarning; - primary_button_command_ = DownloadCommands::Command::DISCARD; + PopulateSuspiciousUiPattern(); return; } }
diff --git a/chrome/browser/ui/download/download_bubble_row_view_info_unittest.cc b/chrome/browser/ui/download/download_bubble_row_view_info_unittest.cc index 679927a2..39c27313 100644 --- a/chrome/browser/ui/download/download_bubble_row_view_info_unittest.cc +++ b/chrome/browser/ui/download/download_bubble_row_view_info_unittest.cc
@@ -231,49 +231,6 @@ EXPECT_FALSE(info().primary_button_command().has_value()); } -TEST_F(DownloadBubbleRowViewInfoTest, DangerousWarningBubbleUIInfo_Old) { - // TODO(crbug.com/1465966): Clean up after the base::Feature is removed. - base::test::ScopedFeatureList features; - features.InitAndDisableFeature( - safe_browsing::kImprovedDownloadBubbleWarnings); - ON_CALL(item(), GetState()) - .WillByDefault(Return(download::DownloadItem::COMPLETE)); - const struct DangerTypeTestCase { - download::DownloadDangerType danger_type; - std::optional<DownloadCommands::Command> primary_button_command; - bool has_subpage; - } kDangerTypeTestCases[] = { - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, - DownloadCommands::Command::KEEP, true}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT, - DownloadCommands::Command::DISCARD, true}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST, - DownloadCommands::Command::DISCARD, true}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE, - DownloadCommands::Command::DISCARD, true}, - {download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED, - DownloadCommands::Command::DISCARD, true}, - {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, - DownloadCommands::Command::DISCARD, true}, - {download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING, - DownloadCommands::Command::DISCARD, true}, - {download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING, std::nullopt, true}, - {download::DOWNLOAD_DANGER_TYPE_ASYNC_SCANNING, std::nullopt, true}, - }; - for (const auto& test_case : kDangerTypeTestCases) { - SCOPED_TRACE(testing::Message() - << "Failed for danger type " - << download::GetDownloadDangerTypeString(test_case.danger_type) - << std::endl); - ON_CALL(item(), GetDangerType()) - .WillByDefault(Return(test_case.danger_type)); - item().NotifyObserversDownloadUpdated(); - EXPECT_EQ(info().primary_button_command(), - test_case.primary_button_command); - EXPECT_EQ(info().has_subpage(), test_case.has_subpage); - } -} - TEST_F(DownloadBubbleRowViewInfoTest, DangerousWarningBubbleUIInfo) { ON_CALL(item(), GetState()) .WillByDefault(Return(download::DownloadItem::COMPLETE));
diff --git a/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc b/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc index e08b1b72..94aee3c 100644 --- a/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc +++ b/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/search_engines/keyword_editor_controller.h" +#include <memory> #include <string> #include "base/compiler_specific.h" @@ -331,3 +332,133 @@ ASSERT_EQ(original_row_count + 1, table_model()->RowCount()); ASSERT_TRUE(table_model()->IndexOfTemplateURL(turl).has_value()); } + +// Specifies examples for tests that verify ordering of search engines. +struct SearchEngineOrderingTestCase { + const char16_t* keyword; + const char16_t* short_name; + bool is_active; + bool created_by_site_search_policy = false; +}; + +std::unique_ptr<TemplateURL> CreateTemplateUrlForSortingTest( + SearchEngineOrderingTestCase test_case) { + TemplateURLData data; + data.SetKeyword(test_case.keyword); + data.SetShortName(test_case.short_name); + data.is_active = test_case.is_active ? TemplateURLData::ActiveStatus::kTrue + : TemplateURLData::ActiveStatus::kFalse; + data.created_by_policy = test_case.created_by_site_search_policy + ? TemplateURLData::CreatedByPolicy::kSiteSearch + : TemplateURLData::CreatedByPolicy::kNoPolicy; + return std::make_unique<TemplateURL>(data); +} + +TEST_F(KeywordEditorControllerTest, EnginesSortedByName) { + const SearchEngineOrderingTestCase kTestCases[] = { + { + .keyword = u"kw1", + .short_name = u"Active 3", + .is_active = true, + }, + { + .keyword = u"kw2", + .short_name = u"Active 1", + .is_active = true, + }, + { + .keyword = u"kw3", + .short_name = u"inactive 1", + .is_active = false, + }, + { + .keyword = u"kw4", + .short_name = u"active 2", + .is_active = true, + }, + { + .keyword = u"kw5", + .short_name = u"Inactive 2", + .is_active = false, + }, + }; + + const std::u16string kExpectedShortNamesOrder[] = { + u"Active 1", u"active 2", u"Active 3", u"inactive 1", u"Inactive 2"}; + + std::vector<TemplateURL*> engines; + for (SearchEngineOrderingTestCase test_case : kTestCases) { + engines.push_back( + util()->model()->Add(CreateTemplateUrlForSortingTest(test_case))); + // Table model should have updated. + VerifyChanged(); + } + + ASSERT_EQ(table_model()->last_active_engine_index(), + table_model()->last_search_engine_index() + 3); + ASSERT_EQ(table_model()->last_other_engine_index(), + table_model()->last_active_engine_index() + 2); + + for (size_t i = 0; i < std::size(kExpectedShortNamesOrder); ++i) { + const TemplateURL* template_url = table_model()->GetTemplateURL( + table_model()->last_search_engine_index() + i); + ASSERT_TRUE(template_url); + EXPECT_EQ(template_url->short_name(), kExpectedShortNamesOrder[i]); + } +} + +TEST_F(KeywordEditorControllerTest, EnginesSortedByNameWithManagedSiteSearch) { + const SearchEngineOrderingTestCase kTestCases[] = { + { + .keyword = u"kw1", + .short_name = u"Non-managed 3", + .is_active = true, + }, + { + .keyword = u"kw2", + .short_name = u"Non-managed 1", + .is_active = true, + }, + { + .keyword = u"kw3", + .short_name = u"policy 1", + .is_active = true, + .created_by_site_search_policy = true, + }, + { + .keyword = u"kw4", + .short_name = u"non-managed 2", + .is_active = true, + }, + { + .keyword = u"kw5", + .short_name = u"Policy 2", + .is_active = true, + .created_by_site_search_policy = true, + }, + }; + + const std::u16string kExpectedShortNamesOrder[] = { + u"policy 1", u"Policy 2", u"Non-managed 1", u"non-managed 2", + u"Non-managed 3"}; + + std::vector<TemplateURL*> engines; + for (SearchEngineOrderingTestCase test_case : kTestCases) { + engines.push_back( + util()->model()->Add(CreateTemplateUrlForSortingTest(test_case))); + // Table model should have updated. + VerifyChanged(); + } + + ASSERT_EQ(table_model()->last_active_engine_index(), + table_model()->last_search_engine_index() + 5); + ASSERT_EQ(table_model()->last_other_engine_index(), + table_model()->last_active_engine_index()); + + for (size_t i = 0; i < std::size(kExpectedShortNamesOrder); ++i) { + const TemplateURL* template_url = table_model()->GetTemplateURL( + table_model()->last_search_engine_index() + i); + ASSERT_TRUE(template_url); + EXPECT_EQ(template_url->short_name(), kExpectedShortNamesOrder[i]); + } +}
diff --git a/chrome/browser/ui/search_engines/template_url_table_model.cc b/chrome/browser/ui/search_engines/template_url_table_model.cc index 938dc744..e194939 100644 --- a/chrome/browser/ui/search_engines/template_url_table_model.cc +++ b/chrome/browser/ui/search_engines/template_url_table_model.cc
@@ -4,18 +4,92 @@ #include "chrome/browser/ui/search_engines/template_url_table_model.h" +#include <memory> +#include <string> +#include <tuple> #include <utility> #include "base/containers/contains.h" #include "base/functional/bind.h" #include "base/i18n/rtl.h" +#include "base/i18n/string_compare.h" +#include "base/ranges/algorithm.h" #include "chrome/grit/generated_resources.h" #include "components/omnibox/browser/omnibox_field_trial.h" #include "components/search_engines/template_url.h" +#include "components/search_engines/template_url_data.h" #include "components/search_engines/template_url_service.h" +#include "third_party/icu/source/common/unicode/locid.h" +#include "third_party/icu/source/i18n/unicode/coll.h" +#include "third_party/icu/source/i18n/unicode/ucol.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/table_model_observer.h" +namespace { + +// Allows sorting site search engines by group (either created by the +// SiteSearchSettings policy, or not created by policy) and alphabetically +// inside each group. +// +// Alphabetical comparison is case-insensitive according to the current locale. +// In case of loading errors for ICU, fallback to regular string comparison. +class OrderByManagedAndAlphabetically { + public: + OrderByManagedAndAlphabetically(); + + bool operator()(const TemplateURL* lhs, const TemplateURL* rhs) const; + + private: + std::string GetShortNameSortKey(const std::u16string& short_name) const; + + std::unique_ptr<icu::Collator> collator_; +}; + +OrderByManagedAndAlphabetically::OrderByManagedAndAlphabetically() { + UErrorCode error_code = U_ZERO_ERROR; + collator_.reset( + icu::Collator::createInstance(icu::Locale::getDefault(), error_code)); + if (!U_SUCCESS(error_code)) { + collator_.reset(); + } + if (collator_) { + // Case-insensitive, ignoring diacriticals. + collator_->setStrength(icu::Collator::PRIMARY); + } +} + +bool OrderByManagedAndAlphabetically::operator()(const TemplateURL* lhs, + const TemplateURL* rhs) const { + auto get_sort_key = [this](const TemplateURL* engine) { + return std::make_tuple( + // Enterprise site search engines are shown before other engines. + engine->created_by_policy() != + TemplateURLData::CreatedByPolicy::kSiteSearch, + // Try to compare short names ignoring case and diacriticals. + collator_ ? GetShortNameSortKey(engine->short_name()) : std::string(), + // If a collator is not available, fallback to regular string + // comparison. + engine->short_name()); + }; + return get_sort_key(lhs) < get_sort_key(rhs); +} + +std::string OrderByManagedAndAlphabetically::GetShortNameSortKey( + const std::u16string& short_name) const { + CHECK(collator_); + + constexpr int32_t kBufferSize = 1000; + uint8_t buffer[kBufferSize]; + icu::UnicodeString icu_str(short_name.c_str(), short_name.length()); + // Sort keys may be truncated for very long names, but that is expected to + // happen so rarely that simply ignoring those cases seems to be a + // reasonable compromise. + collator_->getSortKey(icu_str, buffer, kBufferSize); + return std::string(reinterpret_cast<const char*>(buffer)); +} + +} // namespace + TemplateURLTableModel::TemplateURLTableModel( TemplateURLService* template_url_service) : observer_(nullptr), template_url_service_(template_url_service) { @@ -39,16 +113,20 @@ for (auto* template_url : urls) { if (template_url_service_->ShowInDefaultList(template_url)) { default_entries.push_back(template_url); - } else if (template_url->type() == TemplateURL::OMNIBOX_API_EXTENSION) { - extension_entries.push_back(template_url); - } else if (template_url->is_active() == - TemplateURLData::ActiveStatus::kTrue) { - active_entries.push_back(template_url); - } else { - other_entries.push_back(template_url); + } else if (!template_url_service_->HiddenFromLists(template_url)) { + if (template_url->type() == TemplateURL::OMNIBOX_API_EXTENSION) { + extension_entries.push_back(template_url); + } else if (template_url_service_->ShowInActivesList(template_url)) { + active_entries.push_back(template_url); + } else { + other_entries.push_back(template_url); + } } } + base::ranges::sort(active_entries, OrderByManagedAndAlphabetically()); + base::ranges::sort(other_entries, OrderByManagedAndAlphabetically()); + last_search_engine_index_ = default_entries.size(); last_active_engine_index_ = last_search_engine_index_ + active_entries.size(); last_other_engine_index_ = last_active_engine_index_ + other_entries.size();
diff --git a/chrome/browser/ui/views/download/bubble/download_dialog_view.cc b/chrome/browser/ui/views/download/bubble/download_dialog_view.cc index 5e732d29..66642da 100644 --- a/chrome/browser/ui/views/download/bubble/download_dialog_view.cc +++ b/chrome/browser/ui/views/download/bubble/download_dialog_view.cc
@@ -61,16 +61,9 @@ : RichHoverButton( std::move(show_all_downloads_callback), /*main_image_icon=*/ui::ImageModel(), - base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings) - ? l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_FOOTER_LABEL) - : l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_FOOTER_LINK), + l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_FOOTER_LABEL), /*secondary_text=*/std::u16string(), - base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings) - ? l10n_util::GetStringUTF16( - IDS_DOWNLOAD_BUBBLE_FOOTER_TOOLTIP_LABEL) - : l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_FOOTER_TOOLTIP), + l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_FOOTER_TOOLTIP_LABEL), /*subtitle_text=*/std::u16string(), ui::ImageModel::FromVectorIcon( features::IsChromeRefresh2023() @@ -152,10 +145,7 @@ header->SetBorder(views::CreateEmptyBorder(GetLayoutInsets(DOWNLOAD_ROW))); auto* title = header->AddChildView(std::make_unique<views::Label>( - base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings) - ? l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_HEADER_LABEL) - : l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_HEADER_TEXT), + l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_HEADER_LABEL), views::style::CONTEXT_DIALOG_TITLE, views::style::STYLE_PRIMARY)); title->SetProperty( views::kFlexBehaviorKey,
diff --git a/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc b/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc index dfbc53e..4b29818 100644 --- a/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc +++ b/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc
@@ -611,10 +611,7 @@ auto bubble_delegate = std::make_unique<views::BubbleDialogDelegate>( this, views::BubbleBorder::TOP_RIGHT); bubble_delegate->SetTitle( - base::FeatureList::IsEnabled( - safe_browsing::kImprovedDownloadBubbleWarnings) - ? l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_HEADER_LABEL) - : l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_HEADER_TEXT)); + l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_HEADER_LABEL)); bubble_delegate->SetShowTitle(false); bubble_delegate->set_internal_name(kBubbleName); bubble_delegate->SetShowCloseButton(false);
diff --git a/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc b/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc index 9825e215..50bc46b 100644 --- a/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/web_applications/web_app_install_info.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_ui_manager.h" +#include "chrome/browser/web_applications/web_app_utils.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/ui_test_utils.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -68,7 +69,6 @@ os_hooks_suppress_.emplace(); std::vector<base::test::FeatureRef> all_disabled_features = disabled_features; #if BUILDFLAG(IS_CHROMEOS_ASH) - // TODO(crbug.com/1462253): Also test with Lacros flags enabled. base::Extend(all_disabled_features, ash::standalone_browser::GetFeatureRefs()); #endif @@ -270,6 +270,12 @@ base::TimeDelta log_time = base::TimeTicks::Now() - start_time_; test::LogDebugInfoToConsole(profile_manager->GetLoadedProfiles(), log_time); } +#if BUILDFLAG(IS_CHROMEOS_LACROS) + if (IsCrosapiEnabled()) { + // Make sure all ash browser UI are closed before the test tears down. + CloseAllAshBrowserWindows(); + } +#endif InProcessBrowserTest::TearDownOnMainThread(); } @@ -281,6 +287,12 @@ } void WebAppControllerBrowserTest::SetUpOnMainThread() { +#if BUILDFLAG(IS_CHROMEOS_LACROS) + if (IsCrosapiEnabled()) { + CHECK(IsWebAppsCrosapiEnabled()); + } +#endif + InProcessBrowserTest::SetUpOnMainThread(); host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(https_server()->Start());
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog_browsertest.cc b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog_browsertest.cc index 8afc342..4b7f559 100644 --- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog_browsertest.cc +++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog_browsertest.cc
@@ -918,6 +918,8 @@ auto* prefs = profile()->GetPrefs(); prefs->SetString(prefs::kGoogleWorkspaceCloudUpload, google_workspace_cloud_upload); + prefs->SetString(prefs::kMicrosoftOneDriveMount, + microsoft_office_cloud_upload); prefs->SetString(prefs::kMicrosoftOfficeCloudUpload, microsoft_office_cloud_upload); }
diff --git a/chrome/browser/ui/webui/chrome_web_ui_configs.cc b/chrome/browser/ui/webui/chrome_web_ui_configs.cc index 7a4366d..d0355b8 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_configs.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_configs.cc
@@ -13,6 +13,7 @@ #if !BUILDFLAG(IS_ANDROID) #include "chrome/browser/ui/webui/bookmarks/bookmarks_ui.h" #include "chrome/browser/ui/webui/downloads/downloads_ui.h" +#include "chrome/browser/ui/webui/history/history_ui.h" #endif // !BUILDFLAG(IS_ANDROID) #if BUILDFLAG(ENABLE_EXTENSIONS) @@ -41,6 +42,7 @@ #if !BUILDFLAG(IS_ANDROID) map.AddWebUIConfig(std::make_unique<BookmarksUIConfig>()); map.AddWebUIConfig(std::make_unique<DownloadsUIConfig>()); + map.AddWebUIConfig(std::make_unique<HistoryUIConfig>()); #endif // !BUILDFLAG(IS_ANDROID) #if BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index f5d9901..a45ec4b 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -548,7 +548,6 @@ #endif // !BUILDFLAG(IS_CHROMEOS) if (profile->IsGuestSession() && (url.host_piece() == chrome::kChromeUIAppLauncherPageHost || - url.host_piece() == chrome::kChromeUIHistoryHost || url.host_piece() == chrome::kChromeUINewTabPageHost || url.host_piece() == chrome::kChromeUINewTabPageThirdPartyHost || url.host_piece() == password_manager::kChromeUIPasswordManagerHost)) { @@ -626,8 +625,6 @@ return &NewWebUI<settings::SettingsUI>; if (url.host_piece() == chrome::kChromeUITabSearchHost) return &NewWebUI<TabSearchUI>; - if (url.host_piece() == chrome::kChromeUIHistoryHost) - return &NewWebUI<HistoryUI>; if (url.host_piece() == chrome::kChromeUIProfileInternalsHost) return &NewWebUI<ProfileInternalsUI>; if (url.host_piece() == chrome::kChromeUISyncFileSystemInternalsHost)
diff --git a/chrome/browser/ui/webui/history/history_ui.cc b/chrome/browser/ui/webui/history/history_ui.cc index 07a60cd..42c5c4c 100644 --- a/chrome/browser/ui/webui/history/history_ui.cc +++ b/chrome/browser/ui/webui/history/history_ui.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/ui/webui/history_clusters/history_clusters_handler.h" #include "chrome/browser/ui/webui/managed_ui_handler.h" #include "chrome/browser/ui/webui/metrics_handler.h" +#include "chrome/browser/ui/webui/page_not_available_for_guest/page_not_available_for_guest_ui.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" @@ -175,6 +176,22 @@ } // namespace +HistoryUIConfig::HistoryUIConfig() + : WebUIConfig(content::kChromeUIScheme, chrome::kChromeUIHistoryHost) {} + +HistoryUIConfig::~HistoryUIConfig() = default; + +std::unique_ptr<content::WebUIController> +HistoryUIConfig::CreateWebUIController(content::WebUI* web_ui, + const GURL& url) { + Profile* profile = Profile::FromWebUI(web_ui); + if (profile->IsGuestSession()) { + return std::make_unique<PageNotAvailableForGuestUI>( + web_ui, chrome::kChromeUIHistoryHost); + } + return std::make_unique<HistoryUI>(web_ui); +} + HistoryUI::HistoryUI(content::WebUI* web_ui) : ui::MojoWebUIController(web_ui, /*enable_chrome_send=*/true) { Profile* profile = Profile::FromWebUI(web_ui);
diff --git a/chrome/browser/ui/webui/history/history_ui.h b/chrome/browser/ui/webui/history/history_ui.h index 43004c6..c6e9530 100644 --- a/chrome/browser/ui/webui/history/history_ui.h +++ b/chrome/browser/ui/webui/history/history_ui.h
@@ -10,6 +10,7 @@ #include "base/gtest_prod_util.h" #include "components/page_image_service/mojom/page_image_service.mojom.h" #include "components/prefs/pref_change_registrar.h" +#include "content/public/browser/webui_config.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "ui/base/resource/resource_scale_factor.h" #include "ui/webui/mojo_web_ui_controller.h" @@ -27,6 +28,17 @@ class ImageServiceHandler; } +class HistoryUIConfig : public content::WebUIConfig { + public: + HistoryUIConfig(); + ~HistoryUIConfig() override; + + // content::WebUIConfig: + std::unique_ptr<content::WebUIController> CreateWebUIController( + content::WebUI* web_ui, + const GURL& url) override; +}; + class HistoryUI : public ui::MojoWebUIController { public: explicit HistoryUI(content::WebUI* web_ui);
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 20f1110..9e9551a6 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -3371,8 +3371,6 @@ IDS_SETTINGS_SITE_DATA_PAGE_ALLOW_RADIO_SUB_LABEL}, {"siteDataPageClearOnExitRadioLabel", IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_RADIO_LABEL}, - {"siteDataPageClearOnExitRadioSubLabel", - IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_RADIO_SUBLABEL}, {"siteDataPageBlockRadioLabel", IDS_SETTINGS_SITE_DATA_PAGE_BLOCK_RADIO_LABEL}, {"siteDataPageBlockRadioSublabel", @@ -3397,6 +3395,11 @@ IDS_SETTINGS_SITE_DATA_PAGE_BLOCK_CONFIRM_DIALOG_CANCEL_BUTTON}, }; html_source->AddLocalizedStrings(kLocalizedStrings); + html_source->AddLocalizedString( + "siteDataPageClearOnExitRadioSubLabel", + base::FeatureList::IsEnabled(switches::kUnoDesktop) + ? IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_WITH_EXCEPTION_RADIO_SUBLABEL + : IDS_SETTINGS_SITE_DATA_PAGE_CLEAR_ON_EXIT_RADIO_SUBLABEL); } #if !BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/webauthn/passkey_model_factory.cc b/chrome/browser/webauthn/passkey_model_factory.cc index 16d53194..66ae4ab 100644 --- a/chrome/browser/webauthn/passkey_model_factory.cc +++ b/chrome/browser/webauthn/passkey_model_factory.cc
@@ -32,9 +32,10 @@ "PasskeyModel", ProfileSelections::Builder() .WithRegular(ProfileSelection::kRedirectedToOriginal) - // TODO(crbug.com/1418376): Check if this service is needed in - // Guest mode. - .WithGuest(ProfileSelection::kRedirectedToOriginal) + // Enable PasskeyModel for guest profiles. Guest profiles are + // never signed in so they don't have have access to GPM passkeys, + // but this simplifies handling by clients. + .WithGuest(ProfileSelection::kOffTheRecordOnly) .Build()) { DependsOn(ModelTypeStoreServiceFactory::GetInstance()); if (base::FeatureList::IsEnabled( @@ -52,8 +53,11 @@ DCHECK(base::FeatureList::IsEnabled(syncer::kSyncWebauthnCredentials)); auto sync_bridge = std::make_unique<webauthn::PasskeySyncBridge>( ModelTypeStoreServiceFactory::GetForProfile(profile)->GetStoreFactory()); + // Do not instantiate the affiliation service for guest profiles, since the + // password manager does not run for them. if (base::FeatureList::IsEnabled( - password_manager::features::kPasskeysPrefetchAffiliations)) { + password_manager::features::kPasskeysPrefetchAffiliations) && + !profile->IsGuestSession()) { AffiliationsPrefetcherFactory::GetForProfile(profile)->RegisterPasskeyModel( sync_bridge.get()); }
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index b41d97d..5cb9827 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1702987189-d6b00d2e6c27d64e8becf13b1a747248c13f3749.profdata +chrome-mac-arm-main-1703001300-3d2617a1d85d263693845fd6bc397ab4cd34bfd1.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index a72011c..8fcc6c1 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1702987189-afe493d32d9b8719db2e067dbe651e015e2edfff.profdata +chrome-win64-main-1702997979-2c165bef2447ed07a44e957476851ecc21b076ed.profdata
diff --git a/chrome/common/features.gni b/chrome/common/features.gni index 9effd0b4..866f4df 100644 --- a/chrome/common/features.gni +++ b/chrome/common/features.gni
@@ -39,6 +39,7 @@ # components/policy/resources/templates/policy_definitions/: # # * CertificateManagement/CACertificates.yaml + # * CertificateManagement/CADistrustedCertificates.yaml # chrome_certificate_policies_supported = is_mac || is_win || is_linux
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 1b1e80ce..7a8dbf5 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -3992,6 +3992,12 @@ // A list of base64 encoded certificates that are to be trusted as root certs. // Only specifiable as an enterprise policy. inline constexpr char kCACertificates[] = "certificates.ca_certificates"; + +// A list of base64 encoded certificates containing SPKIs that are not to be +// trusted. +// Only specifiable as an enterprise policy. +inline constexpr char kCADistrustedCertificates[] = + "certificates.ca_distrusted_certificates"; #endif // BUILDFLAG(CHROME_CERTIFICATE_POLICIES_SUPPORTED) } // namespace prefs
diff --git a/chrome/common/privacy_budget/privacy_budget_features.cc b/chrome/common/privacy_budget/privacy_budget_features.cc index d52d8717..00018ba 100644 --- a/chrome/common/privacy_budget/privacy_budget_features.cc +++ b/chrome/common/privacy_budget/privacy_budget_features.cc
@@ -48,17 +48,4 @@ const base::FeatureParam<std::string> kIdentifiabilityStudyBlockWeights = { &kIdentifiabilityStudy, "BlockWeights", ""}; -const base::FeatureParam<std::string> kIdentifiabilityStudyReidSurfaceBlocks = { - &kIdentifiabilityStudy, "ReidBlocks", ""}; - -const base::FeatureParam<std::string> - kIdentifiabilityStudyReidSurfaceBlocksSaltsRanges = { - &kIdentifiabilityStudy, "ReidBlocksSaltsRanges", ""}; -const base::FeatureParam<std::string> - kIdentifiabilityStudyReidSurfaceBlocksBits = {&kIdentifiabilityStudy, - "ReidBlocksBits", ""}; -const base::FeatureParam<std::string> - kIdentifiabilityStudyReidBlocksNoiseProbabilities = { - &kIdentifiabilityStudy, "ReidBlocksNoiseProbabilities", ""}; - } // namespace features
diff --git a/chrome/common/privacy_budget/privacy_budget_features.h b/chrome/common/privacy_budget/privacy_budget_features.h index 8871c8f..54072377 100644 --- a/chrome/common/privacy_budget/privacy_budget_features.h +++ b/chrome/common/privacy_budget/privacy_budget_features.h
@@ -83,10 +83,6 @@ // This parameter only affects random sampling of surfaces. Setting this to 0 // will disable random sampling. // -// * For now, allow (kIdentifiabilityStudyExpectedSurfaceCount or -// kIdentifiabilityStudyBlocks) and kIdentifiabilityStudyReidSurfaceBlocks to be -// specified at the same time. -// // Parameter name: "Rho" // Parameter type: int extern const base::FeatureParam<int> kIdentifiabilityStudyExpectedSurfaceCount; @@ -235,10 +231,6 @@ // * A non-empty value for this parameter enables assigned block sampling and // disables random sampling. // -// * For now, allow (kIdentifiabilityStudyExpectedSurfaceCount or -// kIdentifiabilityStudyBlocks) and kIdentifiabilityStudyReidSurfaceBlocks to be -// specified at the same time. -// // E.g.: // * "1;2;3,4;5;6,7;8;9" : Defines three blocks: {1,2,3}, {4,5,6}, and // {7,8,9}. @@ -324,87 +316,6 @@ // this client and this client will not report any surface. constexpr double kMaxProbabilityPerSurface = 0.5; -// Reid Surface Blocks. -// -// Parameter name: "ReidBlocks" -// Parameter type: Comma separated list of blocks. Each block is a semicolon -// separated list of surfaces. See examples below. -// -// Each block is a list of surfaces for which we want to estimate the Reid -// score. For each block, we will collect and send to the server 1 bit of data. -// -// * For now, allow (kIdentifiabilityStudyExpectedSurfaceCount or -// kIdentifiabilityStudyBlocks) and kIdentifiabilityStudyReidSurfaceBlocks to be -// specified at the same time. -// -// E.g.: -// * "1;2;3,4;5;6,7;8;9" : Defines three blocks: {1,2,3}, {4,5,6}, and -// {7,8,9}. -extern const base::FeatureParam<std::string> - kIdentifiabilityStudyReidSurfaceBlocks; - -// Ranges for the random salts for the Reid Block hashes. -// -// Parameter name: "ReidBlocksSaltsRanges" -// Parameter type: Comma separated list of salts ranges expressed as integers. -// -// If this parameter is specified then it must specify a max salt for each block -// that is defined using the `ReidBlocks` parameter. The random salt used to -// calculate the Reid hash should be a number between 0 and this parameter. -// -// * All max salts must be non-zero positive integers. -// -// * There must be exactly as many Reid salts ranges as there are Reid blocks. -// If not, disable the Reid estimator feature. -// -// E.g.: -// * "1000,5000": Assigns max salt number for two Reid Blocks send in -// `ReidBlocks` parameter. -extern const base::FeatureParam<std::string> - kIdentifiabilityStudyReidSurfaceBlocksSaltsRanges; - -// Number of reported bits for the Reid Block hashes. -// -// Parameter name: "ReidBlocksBits" -// Parameter type: Comma separated list of number of bits represented as -// integers. -// -// If this parameter is specified then it must specify the number of bits that -// should be reported for each block that is defined using the `ReidBlocks` -// parameter. The number of bits should be a number between 1 and 32. -// -// * All bits must be non-zero positive integers. -// -// * There must be exactly as many Reid numbers of bits as there are Reid -// blocks. If not, disable the Reid estimator feature. -// -// E.g.: -// * "2,3": Assigns number of bits that should be reported from two Reid -// Blocks sent in the `ReidBlocks` parameter. -extern const base::FeatureParam<std::string> - kIdentifiabilityStudyReidSurfaceBlocksBits; - -// Probabilities of reporting noise in Reid estimation. -// -// Parameter name: "ReidBlocksNoiseProbabilities" -// Parameter type: Comma separated list of noise probabilities represented as -// decimals. -// -// If this parameter is specified then it must specify the probability of noise -// that should be reported for each block that is defined using the `ReidBlocks` -// parameter. The probability should be a decimal between 0 and 1. -// -// * All probabilities must be positive decimals between 0 and 1. -// -// * There must be exactly as many Reid noise probabilities as there are Reid -// blocks. If not, disable the Reid estimator feature. -// -// E.g.: -// * "0.1,0.05": Assigns probabilities of noise that should be reported from -// two Reid Blocks sent in the `ReidBlocks` parameter. -extern const base::FeatureParam<std::string> - kIdentifiabilityStudyReidBlocksNoiseProbabilities; - } // namespace features #endif // CHROME_COMMON_PRIVACY_BUDGET_PRIVACY_BUDGET_FEATURES_H_
diff --git a/chrome/common/privacy_budget/scoped_privacy_budget_config.cc b/chrome/common/privacy_budget/scoped_privacy_budget_config.cc index b7c1e071..b8d1261 100644 --- a/chrome/common/privacy_budget/scoped_privacy_budget_config.cc +++ b/chrome/common/privacy_budget/scoped_privacy_budget_config.cc
@@ -117,24 +117,6 @@ {features::kIdentifiabilityStudyBlockWeights.name, EncodeIdentifiabilityFieldTrialParam(parameters.block_weights)}); } - if (!parameters.reid_blocks.empty()) { - ftp.insert({features::kIdentifiabilityStudyReidSurfaceBlocks.name, - EncodeIdentifiabilityFieldTrialParam(parameters.reid_blocks)}); - } - if (!parameters.reid_salts_ranges.empty()) { - ftp.insert( - {features::kIdentifiabilityStudyReidSurfaceBlocksSaltsRanges.name, - EncodeIdentifiabilityFieldTrialParam(parameters.reid_salts_ranges)}); - } - if (!parameters.reid_bits.empty()) { - ftp.insert({features::kIdentifiabilityStudyReidSurfaceBlocksBits.name, - EncodeIdentifiabilityFieldTrialParam(parameters.reid_bits)}); - } - if (!parameters.reid_noise.empty()) { - ftp.insert( - {features::kIdentifiabilityStudyReidBlocksNoiseProbabilities.name, - EncodeIdentifiabilityFieldTrialParam(parameters.reid_noise)}); - } if (!parameters.per_surface_cost.empty()) { ftp.insert( {features::kIdentifiabilityStudyPerHashCost.name,
diff --git a/chrome/common/privacy_budget/scoped_privacy_budget_config.h b/chrome/common/privacy_budget/scoped_privacy_budget_config.h index ba3cba5..be206a79 100644 --- a/chrome/common/privacy_budget/scoped_privacy_budget_config.h +++ b/chrome/common/privacy_budget/scoped_privacy_budget_config.h
@@ -64,10 +64,6 @@ SurfaceSetEquivalentClassesList equivalence_classes; IdentifiableSurfaceBlocks blocks; std::vector<double> block_weights; - IdentifiableSurfaceBlocks reid_blocks; - std::vector<uint64_t> reid_salts_ranges; - std::vector<int> reid_bits; - std::vector<double> reid_noise; std::vector<blink::IdentifiableSurface::Type> allowed_random_types; };
diff --git a/chrome/renderer/accessibility/read_anything_app_model.cc b/chrome/renderer/accessibility/read_anything_app_model.cc index 303fbcf26..e97b5d6 100644 --- a/chrome/renderer/accessibility/read_anything_app_model.cc +++ b/chrome/renderer/accessibility/read_anything_app_model.cc
@@ -166,8 +166,9 @@ ui::AXNode* end_node = GetAXNode(end_node_id_); DCHECK(end_node); - // If start node or end node is ignored, the selection was invalid. - if (start_node->IsIgnored() || end_node->IsIgnored()) { + // If start node or end node is invisible or ignored, the selection was + // invalid. + if (start_node->IsInvisibleOrIgnored() || end_node->IsInvisibleOrIgnored()) { return; } @@ -269,7 +270,7 @@ // TODO(abigailbklein) This prevents the crash in crbug.com/1402788, but may // not be the correct approach. Do we need a version of // GetDeepestLastUnignoredDescendant() that works on ignored nodes? - if (!content_node || content_node->IsIgnored()) { + if (!content_node || content_node->IsInvisibleOrIgnored()) { continue; }
diff --git a/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc b/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc index f841c3a..7e9f478ef 100644 --- a/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc +++ b/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc
@@ -733,6 +733,24 @@ } TEST_F(ReadAnythingAppModelTest, + DisplayNodeIdsDoesNotContain_InvisibleOrIgnoredNodes) { + ui::AXTreeUpdate update; + SetUpdateTreeID(&update); + update.nodes.resize(3); + update.nodes[0].id = 2; + update.nodes[1].id = 3; + update.nodes[1].AddState(ax::mojom::State::kInvisible); + update.nodes[2].id = 4; + update.nodes[2].AddState(ax::mojom::State::kIgnored); + AccessibilityEventReceived({update}); + ProcessDisplayNodes({2, 3, 4}); + EXPECT_TRUE(DisplayNodeIdsContains(1)); + EXPECT_TRUE(DisplayNodeIdsContains(2)); + EXPECT_FALSE(DisplayNodeIdsContains(3)); + EXPECT_FALSE(DisplayNodeIdsContains(4)); +} + +TEST_F(ReadAnythingAppModelTest, SelectionNodeIdsContains_SelectionAndNearbyNodes) { ui::AXTreeUpdate update; SetUpdateTreeID(&update); @@ -767,6 +785,30 @@ EXPECT_TRUE(SelectionNodeIdsContains(4)); } +TEST_F(ReadAnythingAppModelTest, + SelectionNodeIdsDoesNotContain_InvisibleOrIgnoredNodes) { + ui::AXTreeUpdate update; + SetUpdateTreeID(&update); + update.nodes.resize(3); + update.nodes[0].id = 2; + update.nodes[1].id = 3; + update.nodes[1].AddState(ax::mojom::State::kInvisible); + update.nodes[2].id = 4; + update.nodes[2].AddState(ax::mojom::State::kIgnored); + update.tree_data.sel_anchor_object_id = 2; + update.tree_data.sel_focus_object_id = 4; + update.tree_data.sel_anchor_offset = 0; + update.tree_data.sel_focus_offset = 0; + update.tree_data.sel_is_backward = false; + + AccessibilityEventReceived({update}); + ProcessSelection(); + EXPECT_FALSE(DisplayNodeIdsContains(1)); + EXPECT_FALSE(SelectionNodeIdsContains(2)); + EXPECT_FALSE(SelectionNodeIdsContains(3)); + EXPECT_FALSE(SelectionNodeIdsContains(4)); +} + TEST_F(ReadAnythingAppModelTest, SetTheme_LineAndLetterSpacingCorrect) { SetLineAndLetterSpacing(read_anything::mojom::LetterSpacing::kStandard, read_anything::mojom::LineSpacing::kLoose);
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 1aafce2b..8d65ad73 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -565,11 +565,6 @@ blink::IdentifiabilityStudySettings::SetGlobalProvider( std::make_unique<PrivacyBudgetSettingsProvider>()); } - - if (base::FeatureList::IsEnabled( - permissions::features::kPermissionStorageAccessAPI)) { - blink::WebRuntimeFeatures::EnableStorageAccessAPI(true); - } } void ChromeContentRendererClient::ExposeInterfacesToBrowser(
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 09cf5b9..db0c984 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -178,8 +178,6 @@ "../browser/optimization_guide/mock_optimization_guide_keyed_service.h", "../browser/password_manager/password_manager_test_util.cc", "../browser/password_manager/password_manager_test_util.h", - "../browser/performance_manager/metrics/cpu_probe/pressure_test_support.cc", - "../browser/performance_manager/metrics/cpu_probe/pressure_test_support.h", "../browser/permissions/crowd_deny_fake_safe_browsing_database_manager.cc", "../browser/permissions/crowd_deny_fake_safe_browsing_database_manager.h", "../browser/policy/messaging_layer/public/report_client_test_util.cc", @@ -6288,7 +6286,6 @@ "../browser/performance_manager/decorators/helpers/page_live_state_decorator_helper_unittest.cc", "../browser/performance_manager/decorators/page_aggregator_unittest.cc", "../browser/performance_manager/mechanisms/page_freezer_unittest.cc", - "../browser/performance_manager/metrics/cpu_probe/cpu_probe_unittest.cc", "../browser/performance_manager/metrics/memory_pressure_metrics_unittest.cc", "../browser/performance_manager/metrics/metrics_provider_common_unittest.cc", "../browser/performance_manager/metrics/page_resource_cpu_monitor_unittest.cc", @@ -6553,12 +6550,8 @@ } if (is_linux || is_chromeos) { - sources += [ - "../browser/performance_manager/metrics/cpu_probe/core_times_unittest.cc", - "../browser/performance_manager/metrics/cpu_probe/cpu_probe_linux_unittest.cc", - "../browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser_unittest.cc", - "../browser/policy/browser_dm_token_storage_linux_unittest.cc", - ] + sources += + [ "../browser/policy/browser_dm_token_storage_linux_unittest.cc" ] } if (is_chromeos_ash) { @@ -7137,7 +7130,6 @@ "../browser/notifications/win/fake_notification_image_retainer.cc", "../browser/notifications/win/fake_notification_image_retainer.h", "../browser/notifications/win/notification_template_builder_unittest.cc", - "../browser/performance_manager/metrics/cpu_probe/cpu_probe_win_unittest.cc", "../browser/performance_monitor/metric_evaluator_helper_win_unittest.cc", "../browser/policy/browser_dm_token_storage_win_unittest.cc", "../browser/process_singleton_win_unittest.cc", @@ -7247,8 +7239,6 @@ "../browser/notifications/mac/notification_utils_unittest.cc", "../browser/notifications/mac/stub_notification_dispatcher_mac.cc", "../browser/notifications/mac/stub_notification_dispatcher_mac.h", - "../browser/performance_manager/metrics/cpu_probe/core_times_unittest.cc", - "../browser/performance_manager/metrics/cpu_probe/cpu_probe_mac_unittest.cc", "../browser/policy/browser_dm_token_storage_mac_unittest.cc", "../browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm", "../browser/ui/cocoa/applescript/apple_event_util_unittest.mm",
diff --git a/chrome/test/base/chromeos/ash_browser_test_starter.cc b/chrome/test/base/chromeos/ash_browser_test_starter.cc index 31287529..04aaf5d 100644 --- a/chrome/test/base/chromeos/ash_browser_test_starter.cc +++ b/chrome/test/base/chromeos/ash_browser_test_starter.cc
@@ -208,7 +208,8 @@ // Disable gpu sandbox in Lacros since it fails in Linux emulator environment. // See details in crbug/1483530. lacros_args.emplace_back("--disable-gpu-sandbox"); - crosapi::BrowserLauncher::AddLacrosArgumentsForTest(lacros_args); + command_line->AppendSwitchASCII(ash::switches::kLacrosChromeAdditionalArgs, + base::JoinString(lacros_args, "####")); return true; }
diff --git a/chrome/test/base/chromeos/crosier/ash_integration_test.cc b/chrome/test/base/chromeos/crosier/ash_integration_test.cc index c4699cad..9003dbb 100644 --- a/chrome/test/base/chromeos/crosier/ash_integration_test.cc +++ b/chrome/test/base/chromeos/crosier/ash_integration_test.cc
@@ -15,7 +15,6 @@ #include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "base/timer/timer.h" -#include "chrome/browser/ash/crosapi/browser_launcher.h" #include "chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/chromeos/crosier/chromeos_integration_login_mixin.h" @@ -117,5 +116,6 @@ // crbug.com/1371655. lacros_args.emplace_back(base::StringPrintf( "--%s=%s", switches::kGaiaUrl, https_server_->base_url().spec().c_str())); - crosapi::BrowserLauncher::AddLacrosArgumentsForTest(lacros_args); + command_line->AppendSwitchASCII(ash::switches::kLacrosChromeAdditionalArgs, + base::JoinString(lacros_args, "####")); }
diff --git a/chrome/test/base/chromeos/crosier/interactive_ash_test_uitest.cc b/chrome/test/base/chromeos/crosier/interactive_ash_test_uitest.cc index af05fc13..b6f1063 100644 --- a/chrome/test/base/chromeos/crosier/interactive_ash_test_uitest.cc +++ b/chrome/test/base/chromeos/crosier/interactive_ash_test_uitest.cc
@@ -10,8 +10,7 @@ using InteractiveAshTestUITest = InteractiveAshTest; -// TODO(crbug.com/1511507): Re-enable this test -IN_PROC_BROWSER_TEST_F(InteractiveAshTestUITest, DISABLED_Basics) { +IN_PROC_BROWSER_TEST_F(InteractiveAshTestUITest, Basics) { SetupContextWidget(); // Verify that installing system apps doesn't crash or flake.
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc index b9a99b2b..3636080 100644 --- a/chrome/test/base/in_process_browser_test.cc +++ b/chrome/test/base/in_process_browser_test.cc
@@ -266,12 +266,6 @@ std::unique_ptr<ScopedAshAccountManagerForTests> scoped_ash_account_manager_; }; -bool IsCrosapiEnabled() { - return !base::CommandLine::ForCurrentProcess() - ->GetSwitchValuePath("lacros-mojo-socket-for-testing") - .empty(); -} - // Returns true if crosapi::mojom::TestController is available. // Note: crosapi::mojom::TestController can be unavailable in the following // case: @@ -337,6 +331,12 @@ MaybeGetAshAccountManagerUIForTests()); } +bool InProcessBrowserTest::IsCrosapiEnabled() { + return !base::CommandLine::ForCurrentProcess() + ->GetSwitchValuePath("lacros-mojo-socket-for-testing") + .empty(); +} + base::Version InProcessBrowserTest::GetAshChromeVersion() { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); base::FilePath ash_chrome_path =
diff --git a/chrome/test/base/in_process_browser_test.h b/chrome/test/base/in_process_browser_test.h index 6c626620..8e40b95 100644 --- a/chrome/test/base/in_process_browser_test.h +++ b/chrome/test/base/in_process_browser_test.h
@@ -418,6 +418,9 @@ // as early as in test SetUp(). static base::Version GetAshChromeVersion(); + // Returns true if crosapi is enabled for the test. + bool IsCrosapiEnabled(); + // The following are the helper functions to manage Ash browser based windows // from Lacros browser tests. When running with Ash, Lacros browser tests can // create some Ash browser based UIs, such as SWA, Web UI, etc. These UIs
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/BUILD.gn b/chrome/test/data/webui/chromeos/os_feedback_ui/BUILD.gn index e6c7ad6..0e3ba4e 100644 --- a/chrome/test/data/webui/chromeos/os_feedback_ui/BUILD.gn +++ b/chrome/test/data/webui/chromeos/os_feedback_ui/BUILD.gn
@@ -15,7 +15,7 @@ ] files = [ - "confirmation_page_test.js", + "confirmation_page_test.ts", "feedback_flow_test.js", "file_attachment_test.js", "help_content_test.js",
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/confirmation_page_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/confirmation_page_test.ts similarity index 73% rename from chrome/test/data/webui/chromeos/os_feedback_ui/confirmation_page_test.js rename to chrome/test/data/webui/chromeos/os_feedback_ui/confirmation_page_test.ts index ba382c5..613ebc38 100644 --- a/chrome/test/data/webui/chromeos/os_feedback_ui/confirmation_page_test.js +++ b/chrome/test/data/webui/chromeos/os_feedback_ui/confirmation_page_test.ts
@@ -9,85 +9,62 @@ import {FeedbackFlowState} from 'chrome://os-feedback/feedback_flow.js'; import {setFeedbackServiceProviderForTesting} from 'chrome://os-feedback/mojo_interface_provider.js'; import {FeedbackAppPostSubmitAction, SendReportStatus} from 'chrome://os-feedback/os_feedback_ui.mojom-webui.js'; +import {strictQuery} from 'chrome://resources/ash/common/typescript_utils/strict_query.js'; +import {assert} from 'chrome://resources/js/assert.js'; +import {OpenWindowProxyImpl} from 'chrome://resources/js/open_window_proxy.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.js'; -import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; +import {TestOpenWindowProxy} from 'chrome://webui-test/test_open_window_proxy.js'; +import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js'; -import {eventToPromise, isVisible} from '../test_util.js'; - -/** @type {string} */ const ONLINE_TITLE = 'Thanks for your feedback'; -/** @type {string} */ const OFFLINE_TITLE = 'You\'re offline. Feedback will be sent later.'; -/** @type {string} */ const ONLINE_MESSAGE = 'Your feedback helps us improve the Chromebook experience and will be ' + 'reviewed by our team. Because of the large number of reports, ' + 'we won’t be able to send a reply.'; -/** @type {string} */ const OFFLINE_MESSAGE = 'Thanks for your feedback. Your feedback helps us improve the Chromebook ' + 'experience and will be reviewed by our team. Because of the large ' + 'number of reports, we won’t be able to send a reply.'; suite('confirmationPageTest', () => { - /** @type {?ConfirmationPageElement} */ - let page = null; + let page: ConfirmationPageElement|null = null; + let feedbackServiceProvider: FakeFeedbackServiceProvider|null = null; + let openWindowProxy: TestOpenWindowProxy; - /** @type {?FakeFeedbackServiceProvider} */ - let feedbackServiceProvider = null; + suiteSetup(function() { + openWindowProxy = new TestOpenWindowProxy(); + OpenWindowProxyImpl.setInstance(openWindowProxy); + }); setup(() => { - document.body.innerHTML = trustedTypes.emptyHTML; + document.body.innerHTML = window.trustedTypes!.emptyHTML; feedbackServiceProvider = new FakeFeedbackServiceProvider(); setFeedbackServiceProviderForTesting(feedbackServiceProvider); }); - teardown(() => { - page.remove(); - page = null; - }); - function initializePage() { - assertFalse(!!page); - page = /** @type {!ConfirmationPageElement} */ ( - document.createElement('confirmation-page')); - assertTrue(!!page); + page = document.createElement('confirmation-page'); + assert(page); page.isUserLoggedIn = true; document.body.appendChild(page); return flushTasks(); } - /** - * @param {?Element} host - * @param {string} selector - * @returns {!Element} - */ - function getElement(host, selector) { - const element = host.shadowRoot.querySelector(selector); - assertTrue(!!element); - return element; + function getElementContent(host: Element|null, selector: string): string { + const element = host!.shadowRoot!.querySelector(selector); + return element!.textContent!.trim(); } - /** - * @param {?Element} host - * @param {string} selector - * @returns {string} - */ - function getElementContent(host, selector) { - const element = getElement(host, selector); - return element.textContent.trim(); - } + function verifyRecordPostSubmitActionCalled( + isCalled: boolean, action: FeedbackAppPostSubmitAction) { + assert(feedbackServiceProvider); - /** - * @param {boolean} isCalled - * @param {FeedbackAppPostSubmitAction} action - * @private - */ - function verifyRecordPostSubmitActionCalled(isCalled, action) { isCalled ? assertTrue( feedbackServiceProvider.isRecordPostSubmitActionCalled(action)) : @@ -95,11 +72,9 @@ feedbackServiceProvider.isRecordPostSubmitActionCalled(action)); } - /** - * @param {boolean} isOnline - * @private - */ - function verifyElementsByStatus(isOnline) { + function verifyElementsByStatus(isOnline: boolean) { + assert(page); + if (isOnline) { assertEquals(ONLINE_TITLE, getElementContent(page, '.page-title')); assertEquals(ONLINE_MESSAGE, getElementContent(page, '#message')); @@ -111,8 +86,9 @@ assertTrue(page.i18nExists('thankYouNoteOffline')); } - // verify help resources exist - const helpResourcesSection = getElement(page, '#helpResources'); + // verify help resources exist. + const helpResourcesSection = + strictQuery('#helpResources', page.shadowRoot, HTMLElement); assertEquals( 'Here are some other helpful resources:', getElementContent(page, '#helpResourcesLabel')); @@ -123,9 +99,9 @@ // Verify the explore app link. const exploreLink = helpLinks[0]; + assert(exploreLink); assertTrue(isVisible(exploreLink)); - assertEquals( - 'help-resources:explore', getElement(exploreLink, '#startIcon').icon); + assertEquals('help-resources:explore', exploreLink.startIcon); assertEquals('Explore app', getElementContent(page, '#explore > .label')); assertTrue(page.i18nExists('exploreAppLabel')); assertEquals( @@ -135,10 +111,9 @@ // Verify the diagnostics app link. const diagnosticsLink = helpLinks[1]; + assert(diagnosticsLink); assertTrue(isVisible(diagnosticsLink)); - assertEquals( - 'help-resources:diagnostics', - getElement(diagnosticsLink, '#startIcon').icon); + assertEquals('help-resources:diagnostics', diagnosticsLink.startIcon); assertEquals( 'Diagnostics app', getElementContent(page, '#diagnostics > .label')); assertTrue(page.i18nExists('diagnosticsAppLabel')); @@ -149,14 +124,14 @@ // Verify the community link. const communityLink = helpLinks[2]; + assert(communityLink); if (isOnline && page.isUserLoggedIn) { assertTrue(isVisible(communityLink)); } else { assertFalse(isVisible(communityLink)); } assertEquals( - 'help-resources2:chromebook-community', - getElement(communityLink, '#startIcon').icon); + 'help-resources2:chromebook-community', communityLink.startIcon); assertEquals( 'Chromebook community', getElementContent(page, '#chromebookCommunity > .label')); @@ -180,6 +155,7 @@ // message are being used. The community link should be visible, test('onlineModeStatusSuccess', async () => { await initializePage(); + assert(page); page.sendReportStatus = SendReportStatus.kSuccess; verifyElementsByStatus(/**isOnline=*/ true); @@ -189,6 +165,7 @@ // message are being used. The community link should be visible, test('offlineModeStatusUnknown', async () => { await initializePage(); + assert(page); page.sendReportStatus = SendReportStatus.kUnknown; verifyElementsByStatus(/**isOnline=*/ true); @@ -198,6 +175,7 @@ // message are being used. The community link should be invisible, test('offlineModeStatusDelayed', async () => { await initializePage(); + assert(page); page.sendReportStatus = SendReportStatus.kDelayed; verifyElementsByStatus(/**isOnline=*/ false); @@ -209,9 +187,11 @@ */ test('userNotLoggedIn_ShouldHideHelpResourcesSection', async () => { await initializePage(); + assert(page); page.isUserLoggedIn = false; - const helpResourcesSection = getElement(page, '#helpResources'); + const helpResourcesSection = + strictQuery('#helpResources', page.shadowRoot, HTMLElement); assertFalse(isVisible(helpResourcesSection)); }); @@ -221,9 +201,11 @@ */ test('userLoggedIn_ShouldShowHelpResourcesSection', async () => { await initializePage(); + assert(page); page.isUserLoggedIn = true; - const helpResourcesSection = getElement(page, '#helpResources'); + const helpResourcesSection = + strictQuery('#helpResources', page.shadowRoot, HTMLElement); assertTrue(isVisible(helpResourcesSection)); }); @@ -233,6 +215,8 @@ */ test('SendNewReport', async () => { await initializePage(); + assert(page); + verifyRecordPostSubmitActionCalled( false, FeedbackAppPostSubmitAction.kSendNewReport); @@ -244,7 +228,8 @@ actualCurrentState = event.detail.currentState; }); - const buttonNewReport = getElement(page, '#buttonNewReport'); + const buttonNewReport = + strictQuery('#buttonNewReport', page.shadowRoot, HTMLElement); buttonNewReport.click(); await clickPromise; @@ -257,6 +242,8 @@ // Test clicking done button should close the window. test('ClickDoneButtonShouldCloseWindow', async () => { await initializePage(); + assert(page); + verifyRecordPostSubmitActionCalled( false, FeedbackAppPostSubmitAction.kClickDoneButton); @@ -269,7 +256,7 @@ }; window.close = closeMock; - const doneButton = getElement(page, '#buttonDone'); + const doneButton = strictQuery('#buttonDone', page.shadowRoot, HTMLElement); doneButton.click(); await flushTasks(); @@ -281,12 +268,15 @@ // Test clicking diagnostics app link. test('openDiagnosticsApp', async () => { await initializePage(); + assert(page); + assert(feedbackServiceProvider); + verifyRecordPostSubmitActionCalled( false, FeedbackAppPostSubmitAction.kOpenDiagnosticsApp); assertEquals(0, feedbackServiceProvider.getOpenDiagnosticsAppCallCount()); - const link = getElement(page, '#diagnostics'); + const link = strictQuery('#diagnostics', page.shadowRoot, HTMLElement); link.click(); assertEquals(1, feedbackServiceProvider.getOpenDiagnosticsAppCallCount()); @@ -294,11 +284,13 @@ true, FeedbackAppPostSubmitAction.kOpenDiagnosticsApp); // Make sure that the label and the sub-label are clickable too. - const label = link.querySelector('.label'); + const label = link.querySelector<HTMLElement>('.label'); + assert(label); label.click(); assertEquals(2, feedbackServiceProvider.getOpenDiagnosticsAppCallCount()); - const subLabel = link.querySelector('.sub-label'); + const subLabel = link.querySelector<HTMLElement>('.sub-label'); + assert(subLabel); subLabel.click(); assertEquals(3, feedbackServiceProvider.getOpenDiagnosticsAppCallCount()); }); @@ -306,12 +298,15 @@ // Test clicking explore app link. test('openExploreApp', async () => { await initializePage(); + assert(page); + assert(feedbackServiceProvider); + verifyRecordPostSubmitActionCalled( false, FeedbackAppPostSubmitAction.kOpenExploreApp); assertEquals(0, feedbackServiceProvider.getOpenExploreAppCallCount()); - const link = getElement(page, '#explore'); + const link = strictQuery('#explore', page.shadowRoot, HTMLElement); link.click(); assertEquals(1, feedbackServiceProvider.getOpenExploreAppCallCount()); @@ -319,11 +314,13 @@ true, FeedbackAppPostSubmitAction.kOpenExploreApp); // Make sure that the label and the sub-label are clickable too. - const label = link.querySelector('.label'); + const label = link.querySelector<HTMLElement>('.label'); + assert(label); label.click(); assertEquals(2, feedbackServiceProvider.getOpenExploreAppCallCount()); - const subLabel = link.querySelector('.sub-label'); + const subLabel = link.querySelector<HTMLElement>('.sub-label'); + assert(subLabel); subLabel.click(); assertEquals(3, feedbackServiceProvider.getOpenExploreAppCallCount()); }); @@ -331,47 +328,45 @@ // Test clicking openChromebookHelp link. test('openChromebookHelp', async () => { await initializePage(); + assert(page); verifyRecordPostSubmitActionCalled( false, FeedbackAppPostSubmitAction.kOpenChromebookCommunity); - const resolver = new PromiseResolver(); - let windowOpenCalled = 0; + + const expectedUrl = + 'https://support.google.com/chromebook/?hl=en#topic=3399709'; let url = ''; - let target = ''; - const openMock = (urlArg, targetArg) => { - windowOpenCalled++; - url = urlArg; - target = targetArg; - return resolver.promise; - }; - - window.open = /** @type {!function()} */ (openMock); - - const link = getElement(page, '#chromebookCommunity'); + const link = + strictQuery('#chromebookCommunity', page.shadowRoot, HTMLElement); link.click(); - await flushTasks(); - - assertEquals(1, windowOpenCalled); - assertEquals(target, '_blank'); - assertEquals( - url, 'https://support.google.com/chromebook/?hl=en#topic=3399709'); + url = await openWindowProxy.whenCalled('openUrl'); + assertEquals(url, expectedUrl); verifyRecordPostSubmitActionCalled( true, FeedbackAppPostSubmitAction.kOpenChromebookCommunity); // Make sure that the label and the sub-label are clickable too. - const label = link.querySelector('.label'); - label.click(); - assertEquals(2, windowOpenCalled); + const label = link.querySelector<HTMLElement>('.label'); + assert(label); + openWindowProxy.resetResolver('openUrl'); - const subLabel = link.querySelector('.sub-label'); + label.click(); + url = await openWindowProxy.whenCalled('openUrl'); + assertEquals(url, expectedUrl); + + const subLabel = link.querySelector<HTMLElement>('.sub-label'); + assert(subLabel); + openWindowProxy.resetResolver('openUrl'); + subLabel.click(); - assertEquals(3, windowOpenCalled); + url = await openWindowProxy.whenCalled('openUrl'); + assertEquals(url, expectedUrl); }); // Test that we only record the user's first action on confirmation page. test('recordFirstPostCompleteAction', async () => { await initializePage(); + assert(page); verifyRecordPostSubmitActionCalled( false, FeedbackAppPostSubmitAction.kOpenExploreApp); @@ -380,9 +375,10 @@ // Open explore app first then open diagnostics app, should only record // the first user action. - const exploreLink = getElement(page, '#explore'); + const exploreLink = strictQuery('#explore', page.shadowRoot, HTMLElement); exploreLink.click(); - const diagnosticsLink = getElement(page, '#diagnostics'); + const diagnosticsLink = + strictQuery('#diagnostics', page.shadowRoot, HTMLElement); diagnosticsLink.click(); await flushTasks();
diff --git a/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn b/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn index 6e692e0..a9463664 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn +++ b/chrome/test/data/webui/chromeos/personalization_app/BUILD.gn
@@ -41,6 +41,7 @@ "sea_pen_images_element_test.ts", "sea_pen_input_query_element_test.ts", "sea_pen_recent_wallpapers_element_test.ts", + "sea_pen_router_element_test.ts", "sea_pen_template_query_element_test.ts", "test_ambient_interface_provider.ts", "test_keyboard_backlight_interface_provider.ts", @@ -60,7 +61,6 @@ "wallpaper_preview_element_test.ts", "wallpaper_selected_element_test.ts", "wallpaper_subpage_element_test.ts", - "wallpaper_subpage_top_element_test.ts", "zone_customization_element_test.ts", ]
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.cc b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.cc index a385377..67b66b3 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.cc +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.cc
@@ -139,6 +139,11 @@ "mocha.run()"); } +IN_PROC_BROWSER_TEST_F(PersonalizationAppComponentTest, SeaPenRouterElement) { + RunTest("chromeos/personalization_app/sea_pen_router_element_test.js", + "mocha.run()"); +} + IN_PROC_BROWSER_TEST_F(PersonalizationAppComponentTest, SeaPenTemplateQuery) { RunTest("chromeos/personalization_app/sea_pen_template_query_element_test.js", "mocha.run()"); @@ -194,10 +199,6 @@ "mocha.run()"); } -IN_PROC_BROWSER_TEST_F(PersonalizationAppComponentTest, WallpaperSubpageTop) { - RunTest("chromeos/personalization_app/wallpaper_subpage_top_element_test.js", - "mocha.run()"); -} IN_PROC_BROWSER_TEST_F(PersonalizationAppComponentTest, ZoneCustomization) { RunTest("chromeos/personalization_app/zone_customization_element_test.js", "mocha.run()");
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js index f5ac047..86d67ac 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_browsertest.js
@@ -396,10 +396,8 @@ function getWallpaperSelected() { const subpage = getWallpaperSubpage(); - const wallpaperTop = - subpage.shadowRoot.querySelector('wallpaper-subpage-top'); const wallpaperSelected = - wallpaperTop.shadowRoot.querySelector('wallpaper-selected'); + subpage.shadowRoot.querySelector('wallpaper-selected'); assertTrue(!!wallpaperSelected, 'wallpaper-selected should exist'); return wallpaperSelected; }
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_router_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/personalization_router_element_test.ts index d20c26f..108cab49 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_router_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_router_element_test.ts
@@ -58,8 +58,8 @@ test('returns to root page when wrong path is keyed in', async () => { loadTimeData.overrideValues({'isAmbientModeAllowed': true}); - const routerElement = initElement( - PersonalizationRouterElement, {path: '/wrongpath', queryParams: {}}); + const routerElement = initElement(PersonalizationRouterElement); + routerElement.goToRoute('/wrongpath' as Paths, {}); await waitAfterNextRender(routerElement); // Due to the wrong path, only shows root page. @@ -147,4 +147,55 @@ assertFalse(params.has(isSharedParam), 'param no longer exists'); assertEquals(null, params.get(isSharedParam), 'does not exist so null'); }); + + test('hides SeaPen from ineligible users', async () => { + loadTimeData.overrideValues({isSeaPenEnabled: false}); + + const routerElement = initElement(PersonalizationRouterElement); + + for (const path of [Paths.SEA_PEN_COLLECTION, Paths.SEA_PEN_RESULTS]) { + PersonalizationRouterElement.instance().goToRoute(path); + await waitAfterNextRender(routerElement); + + // Due to the forbidden path, only shows root page. + const mainElement = + routerElement.shadowRoot!.querySelector('personalization-main'); + assertTrue(!!mainElement, 'main element exists'); + assertNotEquals( + getComputedStyle(mainElement).display, 'none', + 'main element is shown'); + + const seaPenRouterElement = + routerElement.shadowRoot!.querySelector('sea-pen-router'); + assertFalse(!!seaPenRouterElement, 'sea-pen-router does not exist'); + } + }); + + test('shows SeaPen for eligible users', async () => { + loadTimeData.overrideValues({isSeaPenEnabled: true}); + + const routerElement = initElement(PersonalizationRouterElement); + await waitAfterNextRender(routerElement); + + let seaPenRouterElement = + routerElement.shadowRoot!.querySelector('sea-pen-router'); + assertFalse(!!seaPenRouterElement, 'sea-pen-router does not exist'); + + routerElement.goToRoute(Paths.SEA_PEN_COLLECTION); + await waitAfterNextRender(routerElement); + + const mainElement = + routerElement.shadowRoot!.querySelector('personalization-main'); + assertTrue(!!mainElement); + assertEquals( + getComputedStyle(mainElement).display, 'none', + 'main element is hidden'); + + seaPenRouterElement = + routerElement.shadowRoot!.querySelector('sea-pen-router'); + assertTrue(!!seaPenRouterElement, 'sea-pen-router now exists'); + assertNotEquals( + getComputedStyle(seaPenRouterElement).display, 'none', + 'sea-pen-router is shown'); + }); });
diff --git a/chrome/test/data/webui/chromeos/personalization_app/sea_pen_input_query_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_input_query_element_test.ts index 2edd235..029f9de8 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/sea_pen_input_query_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_input_query_element_test.ts
@@ -5,7 +5,8 @@ import 'chrome://personalization/strings.m.js'; import 'chrome://webui-test/chromeos/mojo_webui_test_support.js'; -import {Paths, SeaPenInputQueryElement} from 'chrome://personalization/js/personalization_app.js'; +import {SeaPenInputQueryElement, SeaPenPaths} from 'chrome://personalization/js/personalization_app.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {assertEquals} from 'chrome://webui-test/chai_assert.js'; import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; @@ -14,14 +15,18 @@ suite('SeaPenInputQueryElementTest', function() { let seaPenInputQueryElement: SeaPenInputQueryElement|null; + setup(function() { + loadTimeData.overrideValues({isSeaPenTextInputEnabled: true}); + }); + teardown(async () => { await teardownElement(seaPenInputQueryElement); seaPenInputQueryElement = null; }); - test('displays sea pen input on collection page', async () => { - seaPenInputQueryElement = initElement( - SeaPenInputQueryElement, {'path': Paths.SEA_PEN_COLLECTION}); + test('displays search buttonon root page', async () => { + seaPenInputQueryElement = + initElement(SeaPenInputQueryElement, {path: SeaPenPaths.ROOT}); await waitAfterNextRender(seaPenInputQueryElement); const searchButton = seaPenInputQueryElement.shadowRoot!.querySelector( @@ -32,7 +37,7 @@ test('displays search again button on results page', async () => { seaPenInputQueryElement = - initElement(SeaPenInputQueryElement, {'path': Paths.SEA_PEN_RESULTS}); + initElement(SeaPenInputQueryElement, {path: SeaPenPaths.RESULTS}); await waitAfterNextRender(seaPenInputQueryElement); const searchButton = seaPenInputQueryElement.shadowRoot!.querySelector(
diff --git a/chrome/test/data/webui/chromeos/personalization_app/sea_pen_router_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_router_element_test.ts new file mode 100644 index 0000000..b466347 --- /dev/null +++ b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_router_element_test.ts
@@ -0,0 +1,58 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://personalization/strings.m.js'; + +import {SeaPenInputQueryElement, SeaPenPaths, SeaPenRecentWallpapersElement, SeaPenRouterElement, SeaPenTemplateQueryElement, SeaPenTemplatesElement} from 'chrome://personalization/js/personalization_app.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; +import {assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; + +import {baseSetup, initElement} from './personalization_app_test_utils.js'; + +suite('SeaPenRouterElementTest', function() { + setup(() => { + loadTimeData.overrideValues( + {isSeaPenEnabled: true, isSeaPenTextInputEnabled: false}); + baseSetup(); + }); + + test('shows templates and recent elements', async () => { + const router = initElement(SeaPenRouterElement, {basePath: '/base'}); + router.goToRoute(SeaPenPaths.ROOT); + await waitAfterNextRender(router); + + assertTrue( + !!router.shadowRoot!.querySelector(SeaPenTemplatesElement.is), + 'sea-pen-templates shown on root'); + assertTrue( + !!router.shadowRoot!.querySelector(SeaPenRecentWallpapersElement.is), + 'sea-pen-recent-wallpapers shown on root'); + + assertFalse( + !!router.shadowRoot!.querySelector(SeaPenInputQueryElement.is), + 'no input query element on root'); + assertFalse( + !!router.shadowRoot!.querySelector(SeaPenTemplateQueryElement.is), + 'no template query element on root'); + + router.selectSeaPenTemplate('123'); + await waitAfterNextRender(router); + + assertTrue( + !!router.shadowRoot!.querySelector(SeaPenTemplateQueryElement.is), + 'template query element is shown after selecting template'); + }); + + test('shows input query element if text input enabled', async () => { + loadTimeData.overrideValues({isSeaPenTextInputEnabled: true}); + const router = initElement(SeaPenRouterElement, {basePath: '/base'}); + router.goToRoute(SeaPenPaths.ROOT); + await waitAfterNextRender(router); + + assertTrue( + !!router.shadowRoot!.querySelector(SeaPenInputQueryElement.is), + 'input query element shown on root'); + }); +});
diff --git a/chrome/test/data/webui/chromeos/personalization_app/sea_pen_template_query_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_template_query_element_test.ts index c2ed91c..4db0c94 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/sea_pen_template_query_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_template_query_element_test.ts
@@ -5,7 +5,7 @@ import 'chrome://personalization/strings.m.js'; import 'chrome://webui-test/chromeos/mojo_webui_test_support.js'; -import {Paths, SeaPenTemplateId, SeaPenTemplateQueryElement} from 'chrome://personalization/js/personalization_app.js'; +import {SeaPenPaths, SeaPenTemplateId, SeaPenTemplateQueryElement} from 'chrome://personalization/js/personalization_app.js'; import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; @@ -21,8 +21,8 @@ test('displays sea pen template', async () => { seaPenTemplateQueryElement = initElement(SeaPenTemplateQueryElement, { - 'templateId': SeaPenTemplateId.kFlower.toString(), - 'path': Paths.SEA_PEN_COLLECTION, + path: SeaPenPaths.ROOT, + templateId: SeaPenTemplateId.kFlower.toString(), }); await waitAfterNextRender(seaPenTemplateQueryElement); @@ -51,8 +51,8 @@ test('displays search again button on results page', async () => { seaPenTemplateQueryElement = initElement(SeaPenTemplateQueryElement, { - 'templateId': SeaPenTemplateId.kFlower.toString(), - 'path': Paths.SEA_PEN_RESULTS, + path: SeaPenPaths.RESULTS, + templateId: SeaPenTemplateId.kFlower.toString(), }); await waitAfterNextRender(seaPenTemplateQueryElement); @@ -65,7 +65,7 @@ test('selects chip', async () => { seaPenTemplateQueryElement = initElement( SeaPenTemplateQueryElement, - {'templateId': SeaPenTemplateId.kFlower.toString()}); + {templateId: SeaPenTemplateId.kFlower.toString()}); await waitAfterNextRender(seaPenTemplateQueryElement); const chips = @@ -97,7 +97,7 @@ test('selecting option updates chip', async () => { seaPenTemplateQueryElement = initElement( SeaPenTemplateQueryElement, - {'templateId': SeaPenTemplateId.kFlower.toString()}); + {templateId: SeaPenTemplateId.kFlower.toString()}); await waitAfterNextRender(seaPenTemplateQueryElement); const chips = seaPenTemplateQueryElement.shadowRoot!.querySelectorAll('.clickable'); @@ -132,7 +132,7 @@ test('inspires me', async () => { seaPenTemplateQueryElement = initElement( SeaPenTemplateQueryElement, - {'templateId': SeaPenTemplateId.kFlower.toString()}); + {templateId: SeaPenTemplateId.kFlower.toString()}); await waitAfterNextRender(seaPenTemplateQueryElement); const inspireButton = seaPenTemplateQueryElement.shadowRoot!.getElementById('inspire');
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts index ad6550c1..68ebd05 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_collections_element_test.ts
@@ -4,7 +4,7 @@ import 'chrome://personalization/strings.m.js'; -import {emptyState, GooglePhotosEnablementState, kDefaultImageSymbol, PersonalizationRouterElement, WallpaperActionName, WallpaperCollection, WallpaperCollectionsElement, WallpaperGridItemElement, WallpaperImage} from 'chrome://personalization/js/personalization_app.js'; +import {emptyState, GooglePhotosEnablementState, kDefaultImageSymbol, Paths, PersonalizationRouterElement, WallpaperActionName, WallpaperCollection, WallpaperCollectionsElement, WallpaperGridItemElement, WallpaperImage} from 'chrome://personalization/js/personalization_app.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {assertDeepEquals, assertEquals, assertFalse, assertGE, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; @@ -514,6 +514,21 @@ assertTrue(!!seaPenTile, 'SeaPen tile is present'); }); + test('click on SeaPen tile navigates to SeaPen page', async () => { + loadTimeData.overrideValues({isSeaPenEnabled: true}); + + wallpaperCollectionsElement = initElement(WallpaperCollectionsElement); + await waitAfterNextRender(wallpaperCollectionsElement); + + await loadWallpapers(/* isTimeOfDayWallpaperEnabled= */ true); + wallpaperCollectionsElement.shadowRoot! + .querySelector<WallpaperGridItemElement>( + `${WallpaperGridItemElement.is}[data-sea-pen]`) + ?.click(); + const path = await routerMock.whenCalled('goToRoute'); + assertEquals(Paths.SEA_PEN_COLLECTION, path, 'navigates to SeaPen page'); + }); + test('shows promoted tiles section with SeaPen', async () => { loadTimeData.overrideValues( {isSeaPenEnabled: true, isTimeOfDayWallpaperEnabled: true});
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_subpage_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_subpage_element_test.ts index a1b00eb..f343968 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_subpage_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_subpage_element_test.ts
@@ -4,7 +4,7 @@ import 'chrome://personalization/strings.m.js'; -import {Paths, PersonalizationRouterElement, WallpaperCollectionsElement, WallpaperGridItemElement, WallpaperSubpageElement} from 'chrome://personalization/js/personalization_app.js'; +import {Paths, PersonalizationRouterElement, WallpaperSubpageElement} from 'chrome://personalization/js/personalization_app.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; @@ -40,12 +40,8 @@ await waitAfterNextRender(wallpaperSubpage); // Wallpaper Selected is displayed. - const wallpaperSubpageTopElement = - wallpaperSubpage!.shadowRoot!.querySelector( - 'wallpaper-subpage-top'); const wallpaperSelected = - wallpaperSubpageTopElement!.shadowRoot!.querySelector( - 'wallpaper-selected'); + wallpaperSubpage!.shadowRoot!.querySelector('wallpaper-selected'); assertTrue(!!wallpaperSelected); // Check whether Google Photos collection is displayed. @@ -68,72 +64,4 @@ wallpaperSubpage!.shadowRoot!.querySelector('google-photos-collection'); assertFalse(!!googlePhotosCollections); }); - - test('shows SeaPen templates', async () => { - loadTimeData.overrideValues({isSeaPenEnabled: true}); - wallpaperSubpage = - initElement(WallpaperSubpageElement, {path: Paths.SEA_PEN_COLLECTION}); - await waitAfterNextRender(wallpaperSubpage); - - // SeaPen templates is displayed. - const seaPenCollection = - wallpaperSubpage!.shadowRoot!.querySelector('sea-pen-templates'); - assertTrue(!!seaPenCollection); - }); - - test('hides SeaPen templates for ineligible users', async () => { - loadTimeData.overrideValues({isSeaPenEnabled: false}); - wallpaperSubpage = - initElement(WallpaperSubpageElement, {path: Paths.SEA_PEN_COLLECTION}); - await waitAfterNextRender(wallpaperSubpage); - - const seaPenCollection = - wallpaperSubpage!.shadowRoot!.querySelector('sea-pen-templates'); - assertFalse(!!seaPenCollection, 'SeaPen templates are not displayed'); - }); - - test('shows SeaPen results', async () => { - loadTimeData.overrideValues({isSeaPenEnabled: true}); - wallpaperSubpage = - initElement(WallpaperSubpageElement, {path: Paths.SEA_PEN_RESULTS}); - await waitAfterNextRender(wallpaperSubpage); - - const seaPenImages = - wallpaperSubpage!.shadowRoot!.querySelector('sea-pen-images'); - assertTrue(!!seaPenImages, 'SeaPen images are displayed'); - }); - - test('hides SeaPen results for ineligible users', async () => { - loadTimeData.overrideValues({isSeaPenEnabled: false}); - wallpaperSubpage = - initElement(WallpaperSubpageElement, {path: Paths.SEA_PEN_RESULTS}); - await waitAfterNextRender(wallpaperSubpage); - - const seaPenImages = - wallpaperSubpage!.shadowRoot!.querySelector('sea-pen-images'); - assertFalse(!!seaPenImages, 'sea pen images are not displayed'); - }); - - test('show promoted tiles for sea pen', async () => { - loadTimeData.overrideValues( - {isSeaPenEnabled: true, isTimeOfDayWallpaperEnabled: true}); - wallpaperSubpage = - initElement(WallpaperSubpageElement, {path: Paths.SEA_PEN_COLLECTION}); - await waitAfterNextRender(wallpaperSubpage); - - let collections: WallpaperCollectionsElement = - wallpaperSubpage!.shadowRoot!.querySelector('wallpaper-collections')!; - assertTrue(!!collections && collections.hidden, 'collections are hidden'); - - wallpaperSubpage.path = Paths.COLLECTIONS; - await waitAfterNextRender(wallpaperSubpage); - collections = - wallpaperSubpage!.shadowRoot!.querySelector('wallpaper-collections')!; - assertTrue(!!collections, 'collections are displayed'); - assertFalse(collections.hidden, 'collections are not hidden'); - const promotedTiles = - collections.shadowRoot!.querySelectorAll<WallpaperGridItemElement>( - `${WallpaperGridItemElement.is}[data-is-promoted-tile]`); - assertEquals(2, promotedTiles.length, 'two tiles are promoted'); - }); });
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_subpage_top_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_subpage_top_element_test.ts deleted file mode 100644 index c0bb900..0000000 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_subpage_top_element_test.ts +++ /dev/null
@@ -1,307 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'chrome://personalization/strings.m.js'; -import 'chrome://webui-test/chromeos/mojo_webui_test_support.js'; - -import {emptyState, Paths, PersonalizationRouterElement, QueryParams, SeaPenActionName, SeaPenState, WallpaperSubpageTopElement} from 'chrome://personalization/js/personalization_app.js'; -import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; -import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; -import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; -import {TestMock} from 'chrome://webui-test/test_mock.js'; - -import {baseSetup, initElement, teardownElement} from './personalization_app_test_utils.js'; -import {TestPersonalizationStore} from './test_personalization_store.js'; - -suite('WallpaperSubpageTopElementTest', function() { - let personalizationStore: TestPersonalizationStore; - let wallpaperSubpageTopElement: WallpaperSubpageTopElement|null; - - setup(() => { - const mocks = baseSetup(); - personalizationStore = mocks.personalizationStore; - }); - - teardown(async () => { - await teardownElement(wallpaperSubpageTopElement); - wallpaperSubpageTopElement = null; - }); - - test('hides SeaPen for ineligible users', async () => { - loadTimeData.overrideValues({isSeaPenEnabled: false}); - wallpaperSubpageTopElement = initElement( - WallpaperSubpageTopElement, {path: Paths.SEA_PEN_COLLECTION}); - await waitAfterNextRender(wallpaperSubpageTopElement); - - // wallpaper selected page is displayed. - const wallpaperSelected = - wallpaperSubpageTopElement!.shadowRoot!.querySelector( - 'wallpaper-selected'); - assertTrue( - !!wallpaperSelected, 'wallpaper selected element should be displayed'); - - // SeaPen input should not be displayed. - const seaPenInputQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-input-query'); - assertFalse(!!seaPenInputQueryElement, 'input query should not display.'); - - // SeaPen template should not be displayed. - const seaPenTemplateQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-template-query'); - assertFalse( - !!seaPenTemplateQueryElement, 'template query should not display.'); - }); - - - test('hides SeaPen input for ineligible users', async () => { - loadTimeData.overrideValues( - {isSeaPenEnabled: true, isSeaPenTextInputEnabled: false}); - wallpaperSubpageTopElement = initElement( - WallpaperSubpageTopElement, {path: Paths.SEA_PEN_COLLECTION}); - await waitAfterNextRender(wallpaperSubpageTopElement); - - // wallpaper selected page is displayed. - const wallpaperSelected = - wallpaperSubpageTopElement!.shadowRoot!.querySelector( - 'wallpaper-selected'); - assertTrue( - !!wallpaperSelected, 'wallpaper selected element should be displayed'); - - // SeaPen input should not be displayed. - const seaPenInputQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-input-query'); - assertFalse(!!seaPenInputQueryElement, 'input query should not display.'); - - // SeaPen template should not be displayed. - const seaPenTemplateQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-template-query'); - assertFalse( - !!seaPenTemplateQueryElement, 'template query should not display.'); - }); - - test('hides SeaPen on other paths', async () => { - loadTimeData.overrideValues( - {isSeaPenEnabled: true, isSeaPenTextInputEnabled: true}); - wallpaperSubpageTopElement = initElement( - WallpaperSubpageTopElement, {path: Paths.GOOGLE_PHOTOS_COLLECTION}); - await waitAfterNextRender(wallpaperSubpageTopElement); - - // wallpaper selected page is displayed. - const wallpaperSelected = - wallpaperSubpageTopElement!.shadowRoot!.querySelector( - 'wallpaper-selected'); - assertTrue( - !!wallpaperSelected, 'wallpaper selected element should be displayed'); - - // SeaPen input is not displayed. - const seaPenInputQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-input-query'); - assertFalse(!!seaPenInputQueryElement, 'input query should not display.'); - - // SeaPen template should not be displayed. - const seaPenTemplateQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-template-query'); - assertFalse( - !!seaPenTemplateQueryElement, 'template query should not display.'); - }); - - test('shows SeaPen input', async () => { - loadTimeData.overrideValues( - {isSeaPenEnabled: true, isSeaPenTextInputEnabled: true}); - wallpaperSubpageTopElement = initElement( - WallpaperSubpageTopElement, {path: Paths.SEA_PEN_COLLECTION}); - await waitAfterNextRender(wallpaperSubpageTopElement); - - // wallpaper selected page isn't displayed. - const wallpaperSelected = - wallpaperSubpageTopElement!.shadowRoot!.querySelector( - 'wallpaper-selected'); - assertFalse( - !!wallpaperSelected, - 'wallpaper selected element should not be displayed.'); - - // SeaPen input is displayed. - const seaPenInputQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-input-query'); - assertTrue(!!seaPenInputQueryElement, 'input query should be displayed.'); - // Template query should be hidden. - const templateQuery = wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-template-query'); - assertFalse(!!templateQuery, 'template query should not be displayed.'); - // Verify that the text input area and search button are displayed. - const inputQuery = - seaPenInputQueryElement!.shadowRoot!.querySelector('cr-input'); - assertTrue(!!inputQuery, 'input query should display.'); - const searchButton = seaPenInputQueryElement!.shadowRoot!.querySelector( - '#searchButton') as HTMLElement; - assertTrue(!!searchButton, 'search button should display.'); - }); - - test('shows input element on sea pen results page', async () => { - loadTimeData.overrideValues( - {isSeaPenEnabled: true, isSeaPenTextInputEnabled: true}); - wallpaperSubpageTopElement = initElement(WallpaperSubpageTopElement, { - path: Paths.SEA_PEN_RESULTS, - 'templateId': 'Query', - }); - await waitAfterNextRender(wallpaperSubpageTopElement); - - // wallpaper selected page isn't displayed. - const wallpaperSelected = - wallpaperSubpageTopElement!.shadowRoot!.querySelector( - 'wallpaper-selected'); - assertFalse( - !!wallpaperSelected, - 'wallpaper selected element should not be displayed.'); - - // SeaPen input is displayed. - const seaPenInputQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-input-query'); - assertTrue(!!seaPenInputQueryElement, 'input query should be displayed.'); - - // Template query should be hidden. - const templateQuery = wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-template-query'); - assertFalse(!!templateQuery, 'template query should not be displayed.'); - }); - - test('displays input query tab', async () => { - loadTimeData.overrideValues( - {isSeaPenEnabled: true, isSeaPenTextInputEnabled: true}); - wallpaperSubpageTopElement = initElement( - WallpaperSubpageTopElement, {path: Paths.SEA_PEN_COLLECTION}); - await waitAfterNextRender(wallpaperSubpageTopElement); - const seaPenInputQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-input-query'); - const inputQuery = - seaPenInputQueryElement!.shadowRoot!.querySelector('cr-input'); - assertTrue(!!inputQuery, 'input query should display.'); - const searchButton = seaPenInputQueryElement!.shadowRoot!.querySelector( - '#searchButton') as HTMLElement; - - // Mock singleton |PersonalizationRouter|. - const router = TestMock.fromClass(PersonalizationRouterElement); - PersonalizationRouterElement.instance = () => router; - - // Mock |PersonalizationRouter.goToRoute()|. - let selectedTemplateId: string|undefined; - router.goToRoute = (path: string, queryParams: QueryParams) => { - selectedTemplateId = queryParams.seaPenTemplateId; - assertEquals(Paths.SEA_PEN_RESULTS, path); - }; - - // Make sure state starts at expected value. - assertDeepEquals(emptyState(), personalizationStore.data); - // Actually run the reducers. - personalizationStore.setReducersEnabled(true); - personalizationStore.expectAction(SeaPenActionName.SET_SEA_PEN_THUMBNAILS); - - // Update input query and click on search button. - inputQuery.value = 'this is a test query'; - searchButton.click(); - - assertEquals('Query', selectedTemplateId); - - await personalizationStore.waitForAction( - SeaPenActionName.SET_SEA_PEN_THUMBNAILS); - - const expectedState: SeaPenState = { - loading: { - recentImageData: {}, - recentImages: false, - thumbnails: false, - currentSelected: false, - setImage: 0, - }, - recentImageData: {}, - recentImages: null, - thumbnails: [ - { - id: 1, - image: {url: 'https://sea-pen-images.googleusercontent.com/1'}, - }, - { - id: 2, - image: {url: 'https://sea-pen-images.googleusercontent.com/2'}, - }, - { - id: 3, - image: {url: 'https://sea-pen-images.googleusercontent.com/3'}, - }, - { - id: 4, - image: {url: 'https://sea-pen-images.googleusercontent.com/4'}, - }, - ], - pendingSelected: null, - currentSelected: null, - }; - assertDeepEquals( - expectedState, - personalizationStore.data.wallpaper.seaPen, - 'expected SeaPen state is set', - ); - }); - - test('displays template query content', async () => { - loadTimeData.overrideValues({isSeaPenEnabled: true}); - // Initialize |wallpaperSubpageTopElement|. - wallpaperSubpageTopElement = initElement( - WallpaperSubpageTopElement, - {path: Paths.SEA_PEN_COLLECTION, 'templateId': '4'}); - await waitAfterNextRender(wallpaperSubpageTopElement); - - const seaPenTemplateQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-template-query'); - - assertTrue( - !!seaPenTemplateQueryElement, 'template query should be displayed.'); - }); - - test('displays template query content on sea pen results page', async () => { - loadTimeData.overrideValues({isSeaPenEnabled: true}); - // Initialize |wallpaperSubpageTopElement|. - wallpaperSubpageTopElement = initElement( - WallpaperSubpageTopElement, - {path: Paths.SEA_PEN_RESULTS, 'templateId': '4'}); - await waitAfterNextRender(wallpaperSubpageTopElement); - - const seaPenTemplateQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-template-query'); - - assertTrue( - !!seaPenTemplateQueryElement, 'template query should be displayed.'); - }); - - test( - 'displays template query content when SeaPenTextInput is enabled', - async () => { - loadTimeData.overrideValues( - {isSeaPenEnabled: true, isSeaPenTextInputEnabled: true}); - // Initialize |wallpaperSubpageTopElement|. - wallpaperSubpageTopElement = initElement( - WallpaperSubpageTopElement, - {path: Paths.SEA_PEN_COLLECTION, 'templateId': '4'}); - await waitAfterNextRender(wallpaperSubpageTopElement); - - const seaPenTemplateQueryElement = - wallpaperSubpageTopElement.shadowRoot!.querySelector( - 'sea-pen-template-query'); - - assertTrue( - !!seaPenTemplateQueryElement, - 'template query should be displayed.'); - }); -});
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts index 3b05d52..b99cc92 100644 --- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts +++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts
@@ -4,11 +4,10 @@ import 'chrome://os-settings/lazy_load.js'; -import {CrostiniBrowserProxyImpl, CrostiniPortSetting, GuestOsBrowserProxyImpl, SettingsCrostiniDiskResizeDialogElement, SettingsCrostiniPageElement, SettingsCrostiniSubpageElement} from 'chrome://os-settings/lazy_load.js'; +import {CrostiniBrowserProxyImpl, CrostiniPortSetting, GuestOsBrowserProxyImpl, SettingsCrostiniDiskResizeDialogElement, SettingsCrostiniSubpageElement} from 'chrome://os-settings/lazy_load.js'; import {CrSliderElement, Router, routes, settingMojom, SettingsToggleButtonElement} from 'chrome://os-settings/os_settings.js'; import {webUIListenerCallback} from 'chrome://resources/js/cr.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; -import {getDeepActiveElement} from 'chrome://resources/js/util.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals, assertFalse, assertGE, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; @@ -19,12 +18,11 @@ import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js'; -let crostiniPage: SettingsCrostiniPageElement; let subpage: SettingsCrostiniSubpageElement; let guestOsBrowserProxy: TestGuestOsBrowserProxy; let crostiniBrowserProxy: TestCrostiniBrowserProxy; -const MIC_ALLOWED_PATH = 'prefs.crostini.mic_allowed.value'; +const MIC_ALLOWED_PREF_PATH = 'prefs.crostini.mic_allowed.value'; interface PrefParams { sharedPaths?: {[key: string]: string[]}; @@ -41,7 +39,7 @@ arcEnabled = false, bruschettaInstalled = false, }: PrefParams = {}): void { - crostiniPage.prefs = { + subpage.prefs = { arc: { enabled: {value: arcEnabled}, }, @@ -63,6 +61,10 @@ } suite('<settings-crostini-subpage>', () => { + suiteSetup(() => { + disableAnimationsAndTransitions(); + }); + setup(async () => { loadTimeData.overrideValues({ isCrostiniAllowed: true, @@ -74,60 +76,47 @@ arcAdbSideloadingSupported: true, showCrostiniExtraContainers: true, }); + crostiniBrowserProxy = new TestCrostiniBrowserProxy(); CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy); guestOsBrowserProxy = new TestGuestOsBrowserProxy(); GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy); - crostiniPage = document.createElement('settings-crostini-page'); - document.body.appendChild(crostiniPage); - flush(); - - disableAnimationsAndTransitions(); - + Router.getInstance().navigateTo(routes.CROSTINI_DETAILS); + subpage = document.createElement('settings-crostini-subpage'); + document.body.appendChild(subpage); setCrostiniPrefs(true, {arcEnabled: true}); - - Router.getInstance().navigateTo(routes.CROSTINI); - const crostiniSettingsCard = - crostiniPage.shadowRoot!.querySelector('crostini-settings-card'); - assertTrue(!!crostiniSettingsCard); - const button = - crostiniSettingsCard.shadowRoot!.querySelector<HTMLButtonElement>( - '#crostini'); - assertTrue(!!button); - button.click(); - await flushTasks(); - const subpageElement = - crostiniPage.shadowRoot!.querySelector('settings-crostini-subpage'); - assertTrue(!!subpageElement); - subpage = subpageElement; }); teardown(() => { - crostiniPage.remove(); + subpage.remove(); Router.getInstance().resetRouteForTesting(); + crostiniBrowserProxy.reset(); + guestOsBrowserProxy.reset(); }); suite('Subpage default', () => { test('Basic', () => { + assertTrue(isVisible( + subpage.shadowRoot!.querySelector('#crostiniSharedPathsRow'))); + assertTrue(isVisible( + subpage.shadowRoot!.querySelector('#crostiniSharedUsbDevicesRow'))); + assertTrue(isVisible( + subpage.shadowRoot!.querySelector('#crostiniExportImportRow'))); + assertTrue(isVisible( + subpage.shadowRoot!.querySelector('#crostiniEnableArcAdbRow'))); + assertTrue(isVisible(subpage.shadowRoot!.querySelector('#remove'))); assertTrue( - !!subpage.shadowRoot!.querySelector('#crostiniSharedPathsRow')); - assertTrue( - !!subpage.shadowRoot!.querySelector('#crostiniSharedUsbDevicesRow')); - assertTrue( - !!subpage.shadowRoot!.querySelector('#crostiniExportImportRow')); - assertTrue( - !!subpage.shadowRoot!.querySelector('#crostiniEnableArcAdbRow')); - assertTrue(!!subpage.shadowRoot!.querySelector('#remove')); - assertTrue(!!subpage.shadowRoot!.querySelector('#container-upgrade')); - assertTrue( - !!subpage.shadowRoot!.querySelector('#crostiniPortForwardingRow')); - assertTrue(!!subpage.shadowRoot!.querySelector( - '#crostini-mic-permission-toggle')); - assertTrue(!!subpage.shadowRoot!.querySelector('#crostiniDiskResizeRow')); - assertTrue( - !!subpage.shadowRoot!.querySelector('#crostiniExtraContainersRow')); + isVisible(subpage.shadowRoot!.querySelector('#container-upgrade'))); + assertTrue(isVisible( + subpage.shadowRoot!.querySelector('#crostiniPortForwardingRow'))); + assertTrue(isVisible(subpage.shadowRoot!.querySelector( + '#crostini-mic-permission-toggle'))); + assertTrue(isVisible( + subpage.shadowRoot!.querySelector('#crostiniDiskResizeRow'))); + assertTrue(isVisible( + subpage.shadowRoot!.querySelector('#crostiniExtraContainersRow'))); }); test('Shared paths', async () => { @@ -135,11 +124,10 @@ '#crostiniSharedPathsRow'); assertTrue(!!button); button.click(); + flush(); - await flushTasks(); - const sharedPathsPage = crostiniPage.shadowRoot!.querySelector( - 'settings-guest-os-shared-paths'); - assertTrue(!!sharedPathsPage); + assertEquals( + routes.CROSTINI_SHARED_PATHS, Router.getInstance().currentRoute); }); test('Container upgrade', () => { @@ -229,7 +217,7 @@ '#crostini-mic-permission-toggle'); assertTrue(!!toggle); assertTrue(toggle.checked); - assertTrue(crostiniPage.get(MIC_ALLOWED_PATH)); + assertTrue(subpage.get(MIC_ALLOWED_PREF_PATH)); }); test('Toggle crostini mic permission shutdown', async () => { @@ -264,7 +252,7 @@ '#crostini-mic-permission-toggle'); assertTrue(!!toggle); assertTrue(toggle.checked); - assertTrue(crostiniPage.get(MIC_ALLOWED_PATH)); + assertTrue(subpage.get(MIC_ALLOWED_PREF_PATH)); // Crostini is now shutdown, this means that it doesn't need to be // restarted in order for changes to take effect, therefore no dialog is @@ -274,7 +262,7 @@ assertNull( subpage.shadowRoot!.querySelector('#crostini-mic-permission-dialog')); assertFalse(toggle.checked); - assertFalse(crostiniPage.get(MIC_ALLOWED_PATH)); + assertFalse(subpage.get(MIC_ALLOWED_PREF_PATH)); }); // TODO(b/313456787) Re-enable test once fixed. @@ -319,12 +307,11 @@ assertTrue(isVisible(removeElement)); }); - test('Hide on disable', async () => { + test('Disabling crostini returns to previous route', async () => { assertEquals(routes.CROSTINI_DETAILS, Router.getInstance().currentRoute); + const popstateEventPromise = eventToPromise('popstate', window); setCrostiniPrefs(false); - - await eventToPromise('popstate', window); - assertEquals(routes.CROSTINI, Router.getInstance().currentRoute); + await popstateEventPromise; }); test('Disk resize opens when clicked', async () => { @@ -361,7 +348,7 @@ assertTrue(!!deepLinkElement); await waitAfterNextRender(deepLinkElement); assertEquals( - deepLinkElement, getDeepActiveElement(), + deepLinkElement, subpage.shadowRoot!.activeElement, `Resize disk button should be focused for settingId=${ CROSTINI_DISK_RESIZE_SETTING}.`); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index 1f61f1b..952b3f4c 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -441,6 +441,22 @@ mocha.run(); }); +var OSSettingsCrostiniPageCrostiniSubpageRevampTest = + class extends OSSettingsCrostiniPageCrostiniSubpageTest { + /** @override */ + get featureList() { + return { + enabled: super.featureList.enabled.concat([ + 'ash::features::kOsSettingsRevampWayfinding', + ]), + }; + } +}; + +TEST_F('OSSettingsCrostiniPageCrostiniSubpageRevampTest', 'AllJsTests', () => { + mocha.run(); +}); + [['AboutPage', 'os_about_page_tests.js'], ['ApnDetailDialog', 'apn_detail_dialog_test.js'], [
diff --git a/chrome/updater/README.md b/chrome/updater/README.md index c7431a5..95ec787 100644 --- a/chrome/updater/README.md +++ b/chrome/updater/README.md
@@ -3,7 +3,7 @@ * The code lives in //chrome/updater. * The documentation lives in //docs/updater. * Deprecated Design Doc: https://bit.ly/chromium-updater -* Please join chrome-updates-dev@chromium.org or +* Please join [chrome-updates-dev@chromium.org](https://groups.google.com/a/chromium.org/g/chrome-updates-dev) or https://chromium.slack.com#updater for topics related to the project. The mission of the updater is to keep Chrome (and other software) up to date.
diff --git a/chromeos/ash/components/dbus/audio/cras_audio_client.cc b/chromeos/ash/components/dbus/audio/cras_audio_client.cc index 59addbf..010ea32 100644 --- a/chromeos/ash/components/dbus/audio/cras_audio_client.cc +++ b/chromeos/ash/components/dbus/audio/cras_audio_client.cc
@@ -523,7 +523,7 @@ cras::kSetGlobalOutputChannelRemix); dbus::MessageWriter writer(&method_call); writer.AppendInt32(channels); - writer.AppendArrayOfDoubles(mixer.data(), mixer.size()); + writer.AppendArrayOfDoubles(mixer); cras_proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::DoNothing());
diff --git a/chromeos/ash/components/dbus/chaps/chaps_client.cc b/chromeos/ash/components/dbus/chaps/chaps_client.cc index 08daab0..37ca4c1 100644 --- a/chromeos/ash/components/dbus/chaps/chaps_client.cc +++ b/chromeos/ash/components/dbus/chaps/chaps_client.cc
@@ -261,7 +261,7 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kGetSlotListMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendBool(token_present); proxy_->CallMethod( @@ -277,7 +277,7 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kGetMechanismListMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(slot_id); proxy_->CallMethod( @@ -294,7 +294,7 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kOpenSessionMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(slot_id); writer.AppendUint64(flags); @@ -311,7 +311,7 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kCloseSessionMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); proxy_->CallMethod( @@ -328,9 +328,9 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kCreateObjectMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); - writer.AppendArrayOfBytes(attributes.data(), attributes.size()); + writer.AppendArrayOfBytes(attributes); proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, @@ -346,7 +346,7 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kDestroyObjectMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); writer.AppendUint64(object_handle); @@ -366,10 +366,10 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kGetAttributeValueMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); writer.AppendUint64(object_handle); - writer.AppendArrayOfBytes(attributes_query.data(), attributes_query.size()); + writer.AppendArrayOfBytes(attributes_query); proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, @@ -411,10 +411,10 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kSetAttributeValueMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); writer.AppendUint64(object_handle); - writer.AppendArrayOfBytes(attributes.data(), attributes.size()); + writer.AppendArrayOfBytes(attributes); proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, @@ -430,9 +430,9 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kFindObjectsInitMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); - writer.AppendArrayOfBytes(attributes.data(), attributes.size()); + writer.AppendArrayOfBytes(attributes); proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, @@ -448,7 +448,7 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kFindObjectsMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); writer.AppendUint64(max_object_count); @@ -465,7 +465,7 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kFindObjectsFinalMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); proxy_->CallMethod( @@ -485,11 +485,10 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kEncryptInitMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); writer.AppendUint64(mechanism_type); - writer.AppendArrayOfBytes(mechanism_parameter.data(), - mechanism_parameter.size()); + writer.AppendArrayOfBytes(mechanism_parameter); writer.AppendUint64(key_handle); proxy_->CallMethod( @@ -506,9 +505,9 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kEncryptMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); - writer.AppendArrayOfBytes(data.data(), data.size()); + writer.AppendArrayOfBytes(data); writer.AppendUint64(max_out_length); proxy_->CallMethod( @@ -528,11 +527,10 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kDecryptInitMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); writer.AppendUint64(mechanism_type); - writer.AppendArrayOfBytes(mechanism_parameter.data(), - mechanism_parameter.size()); + writer.AppendArrayOfBytes(mechanism_parameter); writer.AppendUint64(key_handle); proxy_->CallMethod( @@ -549,9 +547,9 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kDecryptMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); - writer.AppendArrayOfBytes(data.data(), data.size()); + writer.AppendArrayOfBytes(data); writer.AppendUint64(max_out_length); proxy_->CallMethod( @@ -569,11 +567,10 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kSignInitMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); writer.AppendUint64(mechanism_type); - writer.AppendArrayOfBytes(mechanism_parameter.data(), - mechanism_parameter.size()); + writer.AppendArrayOfBytes(mechanism_parameter); writer.AppendUint64(key_handle); proxy_->CallMethod( @@ -590,9 +587,9 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kSignMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); - writer.AppendArrayOfBytes(data.data(), data.size()); + writer.AppendArrayOfBytes(data); writer.AppendUint64(max_out_length); proxy_->CallMethod( @@ -613,14 +610,12 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kGenerateKeyPairMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); writer.AppendUint64(mechanism_type); - writer.AppendArrayOfBytes(mechanism_parameter.data(), - mechanism_parameter.size()); - writer.AppendArrayOfBytes(public_attributes.data(), public_attributes.size()); - writer.AppendArrayOfBytes(private_attributes.data(), - private_attributes.size()); + writer.AppendArrayOfBytes(mechanism_parameter); + writer.AppendArrayOfBytes(public_attributes); + writer.AppendArrayOfBytes(private_attributes); proxy_->CallMethod( &method_call, kDbusLongTimeoutMillis, @@ -664,11 +659,10 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kWrapKeyMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); writer.AppendUint64(mechanism_type); - writer.AppendArrayOfBytes(mechanism_parameter.data(), - mechanism_parameter.size()); + writer.AppendArrayOfBytes(mechanism_parameter); writer.AppendUint64(wrapping_key_handle); writer.AppendUint64(key_handle); writer.AppendUint64(max_out_length); @@ -690,14 +684,13 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kUnwrapKeyMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); writer.AppendUint64(mechanism_type); - writer.AppendArrayOfBytes(mechanism_parameter.data(), - mechanism_parameter.size()); + writer.AppendArrayOfBytes(mechanism_parameter); writer.AppendUint64(wrapping_key_handle); - writer.AppendArrayOfBytes(wrapped_key.data(), wrapped_key.size()); - writer.AppendArrayOfBytes(attributes.data(), attributes.size()); + writer.AppendArrayOfBytes(wrapped_key); + writer.AppendArrayOfBytes(attributes); proxy_->CallMethod( &method_call, kDbusLongTimeoutMillis, @@ -715,13 +708,12 @@ dbus::MethodCall method_call(chaps::kChapsInterface, chaps::kDeriveKeyMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kIsolateCredential, sizeof(kIsolateCredential)); + writer.AppendArrayOfBytes(kIsolateCredential); writer.AppendUint64(session_id); writer.AppendUint64(mechanism_type); - writer.AppendArrayOfBytes(mechanism_parameter.data(), - mechanism_parameter.size()); + writer.AppendArrayOfBytes(mechanism_parameter); writer.AppendUint64(base_key_handle); - writer.AppendArrayOfBytes(attributes.data(), attributes.size()); + writer.AppendArrayOfBytes(attributes); proxy_->CallMethod( &method_call, kDbusLongTimeoutMillis,
diff --git a/chromeos/ash/components/dbus/chaps/chaps_client_unittest.cc b/chromeos/ash/components/dbus/chaps/chaps_client_unittest.cc index 441124e..2abebaa 100644 --- a/chromeos/ash/components/dbus/chaps/chaps_client_unittest.cc +++ b/chromeos/ash/components/dbus/chaps/chaps_client_unittest.cc
@@ -52,7 +52,7 @@ uint32_t result_code) { auto response = dbus::Response::CreateEmpty(); dbus::MessageWriter writer(response.get()); - writer.AppendArrayOfBytes(bytes.data(), bytes.size()); + writer.AppendArrayOfBytes(bytes); writer.AppendUint32(result_code); return response; } @@ -80,7 +80,7 @@ auto response = dbus::Response::CreateEmpty(); dbus::MessageWriter writer(response.get()); writer.AppendUint64(uint64_value); - writer.AppendArrayOfBytes(bytes.data(), bytes.size()); + writer.AppendArrayOfBytes(bytes); writer.AppendUint32(result_code); return response; }
diff --git a/chromeos/ash/components/dbus/debug_daemon/debug_daemon_client.cc b/chromeos/ash/components/dbus/debug_daemon/debug_daemon_client.cc index bb08abce..7f6fff16 100644 --- a/chromeos/ash/components/dbus/debug_daemon/debug_daemon_client.cc +++ b/chromeos/ash/components/dbus/debug_daemon/debug_daemon_client.cc
@@ -539,9 +539,7 @@ writer.AppendString(name); writer.AppendString(uri); writer.AppendString(language); - writer.AppendArrayOfBytes( - reinterpret_cast<const uint8_t*>(ppd_contents.data()), - ppd_contents.size()); + writer.AppendArrayOfBytes(base::as_byte_span(ppd_contents)); debugdaemon_proxy_->CallMethodWithErrorResponse( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
diff --git a/chromeos/ash/components/dbus/easy_unlock/easy_unlock_client.cc b/chromeos/ash/components/dbus/easy_unlock/easy_unlock_client.cc index 3d8f2fe..b5cc8c1 100644 --- a/chromeos/ash/components/dbus/easy_unlock/easy_unlock_client.cc +++ b/chromeos/ash/components/dbus/easy_unlock/easy_unlock_client.cc
@@ -39,8 +39,7 @@ // Converts string to array of bytes and writes it using dbus meddage writer. void AppendStringAsByteArray(const std::string& data, dbus::MessageWriter* writer) { - writer->AppendArrayOfBytes(reinterpret_cast<const uint8_t*>(data.data()), - data.length()); + writer->AppendArrayOfBytes(base::as_byte_span(data)); } // The EasyUnlockClient used in production.
diff --git a/chromeos/ash/components/dbus/hiberman/hiberman_client.cc b/chromeos/ash/components/dbus/hiberman/hiberman_client.cc index ef2c279..610ae95 100644 --- a/chromeos/ash/components/dbus/hiberman/hiberman_client.cc +++ b/chromeos/ash/components/dbus/hiberman/hiberman_client.cc
@@ -85,9 +85,7 @@ ::hiberman::kResumeFromHibernateASMethod); dbus::MessageWriter writer(&method_call); writer.AppendString(account_id); - writer.AppendArrayOfBytes( - reinterpret_cast<const uint8_t*>(&auth_session_id[0]), - auth_session_id.length()); + writer.AppendArrayOfBytes(base::as_byte_span(auth_session_id)); // Bind with the weak pointer of |this| so the response is not // handled once |this| is already destroyed. proxy_->CallMethod(&method_call, kHibermanResumeTimeoutMs,
diff --git a/chromeos/ash/components/dbus/session_manager/session_manager_client.cc b/chromeos/ash/components/dbus/session_manager/session_manager_client.cc index 327c1160..041aa41 100644 --- a/chromeos/ash/components/dbus/session_manager/session_manager_client.cc +++ b/chromeos/ash/components/dbus/session_manager/session_manager_client.cc
@@ -263,9 +263,7 @@ writer.AppendString(key); const std::string metadata_blob = metadata.SerializeAsString(); - writer.AppendArrayOfBytes( - reinterpret_cast<const uint8_t*>(metadata_blob.data()), - metadata_blob.size()); + writer.AppendArrayOfBytes(base::as_byte_span(metadata_blob)); writer.AppendUint64(data.size()); base::ScopedFD fd = CreateSharedMemoryRegionFDWithData(data); @@ -861,9 +859,7 @@ dbus::MessageWriter writer(&method_call); const std::string descriptor_blob = descriptor.SerializeAsString(); // static_cast does not work due to signedness. - writer.AppendArrayOfBytes( - reinterpret_cast<const uint8_t*>(descriptor_blob.data()), - descriptor_blob.size()); + writer.AppendArrayOfBytes(base::as_byte_span(descriptor_blob)); session_manager_proxy_->CallMethodWithErrorResponse( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::BindOnce(&SessionManagerClientImpl::OnRetrievePolicy, @@ -881,9 +877,7 @@ dbus::MessageWriter writer(&method_call); const std::string descriptor_blob = descriptor.SerializeAsString(); // static_cast does not work due to signedness. - writer.AppendArrayOfBytes( - reinterpret_cast<const uint8_t*>(descriptor_blob.data()), - descriptor_blob.size()); + writer.AppendArrayOfBytes(base::as_byte_span(descriptor_blob)); auto result = blocking_method_caller_->CallMethodAndBlock(&method_call); RetrievePolicyResponseType response_type = RetrievePolicyResponseType::SUCCESS; @@ -908,12 +902,8 @@ dbus::MessageWriter writer(&method_call); const std::string descriptor_blob = descriptor.SerializeAsString(); // static_cast does not work due to signedness. - writer.AppendArrayOfBytes( - reinterpret_cast<const uint8_t*>(descriptor_blob.data()), - descriptor_blob.size()); - writer.AppendArrayOfBytes( - reinterpret_cast<const uint8_t*>(policy_blob.data()), - policy_blob.size()); + writer.AppendArrayOfBytes(base::as_byte_span(descriptor_blob)); + writer.AppendArrayOfBytes(base::as_byte_span(policy_blob)); // The timeout is intentionally chosen to be that big because on some // devices the operation is slow and a short timeout would lead to // unnecessary enrollment failures. See crbug.com/1155533 for context.
diff --git a/chromeos/ash/components/dbus/shill/modem_3gpp_client.cc b/chromeos/ash/components/dbus/shill/modem_3gpp_client.cc index 44159aa..e7fc650 100644 --- a/chromeos/ash/components/dbus/shill/modem_3gpp_client.cc +++ b/chromeos/ash/components/dbus/shill/modem_3gpp_client.cc
@@ -47,7 +47,7 @@ modemmanager::kModem3gppSetCarrierLock); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes((const uint8_t*)config.data(), config.size()); + writer.AppendArrayOfBytes(base::as_byte_span(config)); proxy_->CallMethodWithErrorResponse( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
diff --git a/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client.cc b/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client.cc index cd53594c..669e903 100644 --- a/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client.cc +++ b/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client.cc
@@ -263,8 +263,7 @@ dbus::MessageWriter writer(&method_call); static_assert(sizeof(uint8_t) == sizeof(char), "Can't reinterpret ip_packet if char is not 8 bit large."); - writer.AppendArrayOfBytes(reinterpret_cast<const uint8_t*>(ip_packet.data()), - ip_packet.size()); + writer.AppendArrayOfBytes(base::as_byte_span(ip_packet)); GetHelper(object_path_value) ->CallVoidMethodWithErrorCallback(&method_call, std::move(callback), std::move(error_callback));
diff --git a/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client_unittest.cc b/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client_unittest.cc index 04fc14e..e61777d8 100644 --- a/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client_unittest.cc +++ b/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client_unittest.cc
@@ -81,9 +81,7 @@ shill::kOnPacketReceivedFunction); { dbus::MessageWriter writer(&preceived_signal); - writer.AppendArrayOfBytes( - reinterpret_cast<const uint8_t*>(data_packet.data()), - data_packet.size()); + writer.AppendArrayOfBytes(base::as_byte_span(data_packet)); } // Expect each signal to be triggered once.
diff --git a/chromeos/ash/components/dbus/smbprovider/smb_provider_client.cc b/chromeos/ash/components/dbus/smbprovider/smb_provider_client.cc index b05e7cb..0347c89 100644 --- a/chromeos/ash/components/dbus/smbprovider/smb_provider_client.cc +++ b/chromeos/ash/components/dbus/smbprovider/smb_provider_client.cc
@@ -88,7 +88,7 @@ dbus::MethodCall method_call(smbprovider::kSmbProviderInterface, smbprovider::kParseNetBiosPacketMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(packet.data(), packet.size()); + writer.AppendArrayOfBytes(packet); writer.AppendUint16(transaction_id); CallMethod(&method_call, &SmbProviderClientImpl::HandleParseNetBiosPacketCallback,
diff --git a/chromeos/ash/components/dbus/typecd/typecd_client.cc b/chromeos/ash/components/dbus/typecd/typecd_client.cc index ec484f6..d1b32f998 100644 --- a/chromeos/ash/components/dbus/typecd/typecd_client.cc +++ b/chromeos/ash/components/dbus/typecd/typecd_client.cc
@@ -128,7 +128,7 @@ dbus::MethodCall method_call(typecd::kTypecdServiceInterface, typecd::kTypecdSetPortsUsingDisplaysMethod); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfUint32s(port_nums.data(), port_nums.size()); + writer.AppendArrayOfUint32s(port_nums); typecd_proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::DoNothing());
diff --git a/chromeos/ash/components/dbus/userdataauth/cryptohome_misc_client_unittest.cc b/chromeos/ash/components/dbus/userdataauth/cryptohome_misc_client_unittest.cc index a5f49f86..dd820d0 100644 --- a/chromeos/ash/components/dbus/userdataauth/cryptohome_misc_client_unittest.cc +++ b/chromeos/ash/components/dbus/userdataauth/cryptohome_misc_client_unittest.cc
@@ -165,7 +165,7 @@ // a very large value so the parsing will fail. constexpr uint8_t invalid_protobuf[] = {0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - writer.AppendArrayOfBytes(invalid_protobuf, sizeof(invalid_protobuf)); + writer.AppendArrayOfBytes(invalid_protobuf); } else if (method_call->GetMember() == ::user_data_auth::kGetSystemSalt) { writer.AppendProtoAsArrayOfBytes(expected_get_system_salt_reply_); } else if (method_call->GetMember() == @@ -198,7 +198,7 @@ // a very large value so the parsing will fail. constexpr uint8_t invalid_protobuf[] = {0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - writer.AppendArrayOfBytes(invalid_protobuf, sizeof(invalid_protobuf)); + writer.AppendArrayOfBytes(invalid_protobuf); } else if (method_call->GetMember() == ::user_data_auth::kGetSanitizedUsername) { writer.AppendProtoAsArrayOfBytes(
diff --git a/chromeos/ash/components/dbus/userdataauth/cryptohome_pkcs11_client_unittest.cc b/chromeos/ash/components/dbus/userdataauth/cryptohome_pkcs11_client_unittest.cc index 9081aed..6466fd9 100644 --- a/chromeos/ash/components/dbus/userdataauth/cryptohome_pkcs11_client_unittest.cc +++ b/chromeos/ash/components/dbus/userdataauth/cryptohome_pkcs11_client_unittest.cc
@@ -122,7 +122,7 @@ // a very large value so the parsing will fail. constexpr uint8_t invalid_protobuf[] = {0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - writer.AppendArrayOfBytes(invalid_protobuf, sizeof(invalid_protobuf)); + writer.AppendArrayOfBytes(invalid_protobuf); } else if (method_call->GetMember() == ::user_data_auth::kPkcs11IsTpmTokenReady) { writer.AppendProtoAsArrayOfBytes(
diff --git a/chromeos/ash/components/dbus/userdataauth/install_attributes_client_unittest.cc b/chromeos/ash/components/dbus/userdataauth/install_attributes_client_unittest.cc index 91fc69b5..4e73282 100644 --- a/chromeos/ash/components/dbus/userdataauth/install_attributes_client_unittest.cc +++ b/chromeos/ash/components/dbus/userdataauth/install_attributes_client_unittest.cc
@@ -179,7 +179,7 @@ // a very large value so the parsing will fail. constexpr uint8_t invalid_protobuf[] = {0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - writer.AppendArrayOfBytes(invalid_protobuf, sizeof(invalid_protobuf)); + writer.AppendArrayOfBytes(invalid_protobuf); } else if (method_call->GetMember() == ::user_data_auth::kInstallAttributesGet) { writer.AppendProtoAsArrayOfBytes(expected_install_attributes_get_reply_); @@ -222,7 +222,7 @@ // a very large value so the parsing will fail. constexpr uint8_t invalid_protobuf[] = {0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - writer.AppendArrayOfBytes(invalid_protobuf, sizeof(invalid_protobuf)); + writer.AppendArrayOfBytes(invalid_protobuf); } else if (method_call->GetMember() == ::user_data_auth::kInstallAttributesGet) { writer.AppendProtoAsArrayOfBytes(
diff --git a/chromeos/ash/components/dbus/userdataauth/userdataauth_client_unittest.cc b/chromeos/ash/components/dbus/userdataauth/userdataauth_client_unittest.cc index f83713a..5c1e372a8 100644 --- a/chromeos/ash/components/dbus/userdataauth/userdataauth_client_unittest.cc +++ b/chromeos/ash/components/dbus/userdataauth/userdataauth_client_unittest.cc
@@ -212,7 +212,7 @@ // a very large value so the parsing will fail. constexpr uint8_t invalid_protobuf[] = {0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - writer.AppendArrayOfBytes(invalid_protobuf, sizeof(invalid_protobuf)); + writer.AppendArrayOfBytes(invalid_protobuf); } else if (method_call->GetMember() == ::user_data_auth::kIsMounted) { writer.AppendProtoAsArrayOfBytes(expected_is_mounted_reply_); } else if (method_call->GetMember() == ::user_data_auth::kIsMounted) {
diff --git a/chromeos/ash/services/multidevice_setup/eligible_host_devices_provider_impl.cc b/chromeos/ash/services/multidevice_setup/eligible_host_devices_provider_impl.cc index 4efa5f98..3a9f8d9 100644 --- a/chromeos/ash/services/multidevice_setup/eligible_host_devices_provider_impl.cc +++ b/chromeos/ash/services/multidevice_setup/eligible_host_devices_provider_impl.cc
@@ -8,6 +8,7 @@ #include "base/feature_list.h" #include "base/memory/ptr_util.h" #include "base/time/time.h" +#include "chromeos/ash/components/multidevice/logging/logging.h" #include "chromeos/ash/components/multidevice/software_feature.h" #include "chromeos/ash/components/multidevice/software_feature_state.h" @@ -63,6 +64,15 @@ features::kCryptAuthV2AlwaysUseActiveEligibleHosts)) { multidevice::RemoteDeviceRefList eligible_active_devices; for (const auto& device : eligible_active_devices_from_last_sync_) { + if (device.remote_device.instance_id().empty() && + device.remote_device.GetDeviceId().empty()) { + // TODO(b/207089877): Add a metric to capture the frequency of missing + // device id. + PA_LOG(WARNING) << __func__ + << ": encountered device with missing Instance ID and " + "legacy device ID"; + continue; + } eligible_active_devices.push_back(device.remote_device); } @@ -84,6 +94,16 @@ void EligibleHostDevicesProviderImpl::UpdateEligibleDevicesSet() { eligible_devices_from_last_sync_.clear(); for (const auto& remote_device : device_sync_client_->GetSyncedDevices()) { + if (remote_device.instance_id().empty() && + remote_device.GetDeviceId().empty()) { + // TODO(b/207089877): Add a metric to capture the frequency of missing + // device id. + PA_LOG(WARNING) << __func__ + << ": encountered device with missing Instance ID and " + "legacy device ID"; + continue; + } + multidevice::SoftwareFeatureState host_state = remote_device.GetSoftwareFeatureState( multidevice::SoftwareFeature::kBetterTogetherHost);
diff --git a/chromeos/ash/services/multidevice_setup/eligible_host_devices_provider_impl_unittest.cc b/chromeos/ash/services/multidevice_setup/eligible_host_devices_provider_impl_unittest.cc index f85442b6..e9c31475 100644 --- a/chromeos/ash/services/multidevice_setup/eligible_host_devices_provider_impl_unittest.cc +++ b/chromeos/ash/services/multidevice_setup/eligible_host_devices_provider_impl_unittest.cc
@@ -173,6 +173,20 @@ EXPECT_TRUE(provider()->GetEligibleHostDevices().empty()); } +// Regression test for b/207089877 +TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest, + NoEligibleDevices_NoDeviceId) { + GetMutableRemoteDevice(test_devices()[0])->instance_id = std::string(); + GetMutableRemoteDevice(test_devices()[1])->instance_id = std::string(); + + multidevice::RemoteDeviceRefList devices{test_devices()[0], + test_devices()[1]}; + fake_device_sync_client()->set_synced_devices(devices); + fake_device_sync_client()->NotifyNewDevicesSynced(); + + EXPECT_TRUE(provider()->GetEligibleHostDevices().empty()); +} + TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest, Sorting) { SetBitsOnTestDevices();
diff --git a/chromeos/dbus/ip_peripheral/ip_peripheral_service_client.cc b/chromeos/dbus/ip_peripheral/ip_peripheral_service_client.cc index 5867304..d5d8480 100644 --- a/chromeos/dbus/ip_peripheral/ip_peripheral_service_client.cc +++ b/chromeos/dbus/ip_peripheral/ip_peripheral_service_client.cc
@@ -191,7 +191,7 @@ ip_peripheral::kGetControlMethod); dbus::MessageWriter writer(&method_call); writer.AppendString(ip); - writer.AppendArrayOfBytes(guid_le.data(), guid_le.size()); + writer.AppendArrayOfBytes(guid_le); writer.AppendByte(control_selector); writer.AppendByte(uvc_get_request); ip_peripheral_service_proxy_->CallMethod( @@ -208,9 +208,9 @@ ip_peripheral::kSetControlMethod); dbus::MessageWriter writer(&method_call); writer.AppendString(ip); - writer.AppendArrayOfBytes(guid_le.data(), guid_le.size()); + writer.AppendArrayOfBytes(guid_le); writer.AppendByte(control_selector); - writer.AppendArrayOfBytes(control_setting.data(), control_setting.size()); + writer.AppendArrayOfBytes(control_setting); ip_peripheral_service_proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::BindOnce(&OnSetControlMethod, std::move(callback)));
diff --git a/clank b/clank index 7feb1eb..e4f08e8 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 7feb1ebbf40bb986c85f970d6872415eaf686f07 +Subproject commit e4f08e8b415dc075f27de50dd82ccd0ae82b9b2c
diff --git a/components/BUILD.gn b/components/BUILD.gn index b5f2e19..60889bd 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -325,6 +325,7 @@ "//components/sync_device_info:unit_tests", "//components/sync_preferences:unit_tests", "//components/sync_user_events:unit_tests", + "//components/system_cpu:unit_tests", "//components/system_media_controls:unit_tests", "//components/test:run_all_unittests", "//components/tpcd/metadata:unit_tests", @@ -971,12 +972,12 @@ "//components/dom_distiller/core", "//components/dom_distiller/core:test_support", "//components/error_page/content/browser:browser_tests", + "//components/facilitated_payments/content/renderer:browser_tests", "//components/metrics:content", "//components/optimization_guide/content/renderer", "//components/paint_preview/renderer", "//components/password_manager/content/browser", "//components/performance_manager:browser_tests", - "//components/facilitated_payments/content/renderer:browser_tests", "//components/security_state/content", "//components/security_state/core", "//components/shared_highlighting/core/common",
diff --git a/components/autofill/PRESUBMIT.py b/components/autofill/PRESUBMIT.py index 4c6400c..4bb59680 100644 --- a/components/autofill/PRESUBMIT.py +++ b/components/autofill/PRESUBMIT.py
@@ -47,10 +47,10 @@ files) ] return [] -def _CheckNoServerFieldTypeCasts(input_api, output_api): - """Checks that no files cast (e.g., raw integers to) ServerFieldTypes.""" +def _CheckNoFieldTypeCasts(input_api, output_api): + """Checks that no files cast (e.g., raw integers to) FieldTypes.""" pattern = input_api.re.compile( - r'_cast<\s*ServerFieldType\b', + r'_cast<\s*FieldType\b', input_api.re.MULTILINE) files = [] for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): @@ -62,9 +62,9 @@ if len(files): return [ output_api.PresubmitPromptWarning( - 'Do not cast raw integers to ServerFieldType to prevent values that ' + + 'Do not cast raw integers to FieldType to prevent values that ' + 'have no corresponding enum constant or are deprecated. Use '+ - 'ToSafeServerFieldType() instead.', + 'ToSafeFieldType() instead.', files) ] return [] @@ -175,7 +175,7 @@ """Checks common to both upload and commit.""" results = [] results.extend(_CheckNoBaseTimeCalls(input_api, output_api)) - results.extend(_CheckNoServerFieldTypeCasts(input_api, output_api)) + results.extend(_CheckNoFieldTypeCasts(input_api, output_api)) results.extend(_CheckFeatureNames(input_api, output_api)) results.extend(_CheckWebViewExposedExperiments(input_api, output_api)) results.extend(_CheckModificationOfLegacyRegexPatterns(input_api, output_api))
diff --git a/components/autofill/README.md b/components/autofill/README.md index 6c11c78c..a207f6f 100644 --- a/components/autofill/README.md +++ b/components/autofill/README.md
@@ -298,7 +298,7 @@ combinations that don't make sense (street-address followed by address-line1). -Predicted types are represented as [ServerFieldTypes](https://source.chromium.org/chromium/chromium/src/+/main:components/autofill/core/browser/field_types.h;l=125;drc=bce2963801691db93bc7f05b5d320cef32effa24) +Predicted types are represented as [FieldTypes](https://source.chromium.org/chromium/chromium/src/+/main:components/autofill/core/browser/field_types.h;l=130;drc=dbd8c8bb5f830b79e9d1f0f57a3e071b81f6d28b) and types derived from the autocomplete attribute are represented as [HtmlFieldTypes](https://source.chromium.org/chromium/chromium/src/+/main:components/autofill/core/common/mojom/autofill_types.mojom;l=24;drc=f330bdbafa2714f8a6431a9dee412fdb38d5adbe). ## What about forms in iframes? @@ -317,9 +317,9 @@ ## Field type terminology -Several important subsets of ServerFieldTypes exist: +Several important subsets of FieldTypes exist: * Supported types of a [form group](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/autofill/core/browser/data_model/form_group.h): - Every form group defines which ServerFieldTypes it maintains. For example: + Every form group defines which FieldTypes it maintains. For example: * The supported type of [EmailInfo](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/autofill/core/browser/data_model/contact_info.h;l=87;drc=10009f6ff9f3b626979c9422321686f360df7cee) is [EMAIL_ADDRESS](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/autofill/core/browser/data_model/contact_info.cc;l=184;drc=59b1cf76cc21ae34bc99073e963f7d268b0a5c17). * The supported types of AutofillProfile are all name, address, phone number, etc. types. * Stored types of AutofillProfile: The set of types stored in AutofillTable,
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index a49f395..7523aaa 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -99,7 +99,7 @@ virtual void OnAfterTextFieldDidChange(AutofillManager& manager, FormGlobalId form, FieldGlobalId field, - std::u16string text_value) {} + const std::u16string& text_value) {} virtual void OnBeforeTextFieldDidScroll(AutofillManager& manager, FormGlobalId form,
diff --git a/components/autofill/core/browser/mock_autofill_manager_observer.h b/components/autofill/core/browser/mock_autofill_manager_observer.h index 10933f5..b7b1d48 100644 --- a/components/autofill/core/browser/mock_autofill_manager_observer.h +++ b/components/autofill/core/browser/mock_autofill_manager_observer.h
@@ -42,10 +42,11 @@ OnBeforeTextFieldDidChange, (AutofillManager&, FormGlobalId, FieldGlobalId), (override)); - MOCK_METHOD(void, - OnAfterTextFieldDidChange, - (AutofillManager&, FormGlobalId, FieldGlobalId, std::u16string), - (override)); + MOCK_METHOD( + void, + OnAfterTextFieldDidChange, + (AutofillManager&, FormGlobalId, FieldGlobalId, const std::u16string&), + (override)); MOCK_METHOD(void, OnBeforeTextFieldDidScroll,
diff --git a/components/autofill/core/browser/proto/server.proto b/components/autofill/core/browser/proto/server.proto index 22642f7..09021da 100644 --- a/components/autofill/core/browser/proto/server.proto +++ b/components/autofill/core/browser/proto/server.proto
@@ -540,7 +540,7 @@ message ProfileValidityMap { // Map from autofill type to the validity of its value in the profile. // - // Key should be one of the enum values from ServerFieldType. Values should be + // Key should be one of the enum values from FieldType. Values should be // from the AutofillProfile::ValidityState. Plain integers are used // instead of enums because proto2 treats unknown enum values as unknown // fields, which is confusing when the enums are in maps.
diff --git a/components/autofill/core/browser/test_autofill_manager_waiter.cc b/components/autofill/core/browser/test_autofill_manager_waiter.cc index aef3ff2..9dabf4a 100644 --- a/components/autofill/core/browser/test_autofill_manager_waiter.cc +++ b/components/autofill/core/browser/test_autofill_manager_waiter.cc
@@ -114,7 +114,7 @@ AutofillManager& manager, FormGlobalId form, FieldGlobalId field, - std::u16string text_value) { + const std::u16string& text_value) { Decrement(Event::kTextFieldDidChange); }
diff --git a/components/autofill/core/browser/test_autofill_manager_waiter.h b/components/autofill/core/browser/test_autofill_manager_waiter.h index e012e93..5c15a6b 100644 --- a/components/autofill/core/browser/test_autofill_manager_waiter.h +++ b/components/autofill/core/browser/test_autofill_manager_waiter.h
@@ -166,7 +166,7 @@ void OnAfterTextFieldDidChange(AutofillManager& manager, FormGlobalId form, FieldGlobalId field, - std::u16string text_value) override; + const std::u16string& text_value) override; void OnBeforeTextFieldDidScroll(AutofillManager& manager, FormGlobalId form, @@ -297,7 +297,7 @@ void OnAfterTextFieldDidChange(AutofillManager& manager, FormGlobalId form, FieldGlobalId field, - std::u16string text_value) override { + const std::u16string& text_value) override { MaybeQuit(&Observer::OnAfterTextFieldDidChange, manager, form, field, text_value); }
diff --git a/components/content_settings/core/browser/content_settings_provider.cc b/components/content_settings/core/browser/content_settings_provider.cc index e797766..2ff557c 100644 --- a/components/content_settings/core/browser/content_settings_provider.cc +++ b/components/content_settings/core/browser/content_settings_provider.cc
@@ -3,7 +3,9 @@ // found in the LICENSE file. #include "components/content_settings/core/browser/content_settings_provider.h" -#include "base/notreached.h" +#include "base/feature_list.h" +#include "components/content_settings/core/browser/content_settings_rule.h" +#include "components/content_settings/core/common/features.h" namespace content_settings { @@ -15,7 +17,20 @@ const PartitionKey& partition_key) const { // TODO(b/316530672): Remove default implementation when all providers are // implemented. - NOTIMPLEMENTED(); + auto it = GetRuleIterator(content_type, off_the_record, partition_key); + while (it && it->HasNext()) { + auto rule = it->Next(); + if (rule->primary_pattern.Matches(primary_url) && + rule->secondary_pattern.Matches(secondary_url) && + (base::FeatureList::IsEnabled( + content_settings::features::kActiveContentSettingExpiry) || + rule->metadata.expiration().is_null() || + rule->metadata.expiration() >= base::Time::Now())) { + return std::make_unique<OwnedRule>( + std::move(rule->primary_pattern), std::move(rule->secondary_pattern), + rule->TakeValue(), std::move(rule->metadata)); + } + } return nullptr; }
diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc index a5e61efa..64e48d0 100644 --- a/components/content_settings/core/browser/content_settings_registry.cc +++ b/components/content_settings/core/browser/content_settings_registry.cc
@@ -448,7 +448,8 @@ Register(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD, "file-system-write-guard", CONTENT_SETTING_ASK, - WebsiteSettingsInfo::UNSYNCABLE, /*allowlisted_primary_schemes=*/{}, + WebsiteSettingsInfo::UNSYNCABLE, + /*allowlisted_primary_schemes=*/{kChromeDevToolsScheme}, /*valid_settings=*/ {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK}, WebsiteSettingsInfo::TOP_ORIGIN_ONLY_SCOPE,
diff --git a/components/content_settings/core/browser/cookie_settings.cc b/components/content_settings/core/browser/cookie_settings.cc index 704c8a7..a57270e6 100644 --- a/components/content_settings/core/browser/cookie_settings.cc +++ b/components/content_settings/core/browser/cookie_settings.cc
@@ -362,9 +362,7 @@ // the feature here, we should rely on CookieSettingsFactory to plumb in this // boolean instead. #if BUILDFLAG(USE_BLINK) - return base::FeatureList::IsEnabled(blink::features::kStorageAccessAPI) || - base::FeatureList::IsEnabled( - permissions::features::kPermissionStorageAccessAPI); + return true; #else return false; #endif
diff --git a/components/content_settings/core/browser/cookie_settings_unittest.cc b/components/content_settings/core/browser/cookie_settings_unittest.cc index 8e521671..6a96f11c 100644 --- a/components/content_settings/core/browser/cookie_settings_unittest.cc +++ b/components/content_settings/core/browser/cookie_settings_unittest.cc
@@ -164,12 +164,6 @@ enabled_features.push_back({features::kTpcdHeuristicsGrants, {{"TpcdReadHeuristicsGrants", "true"}}}); -#if !BUILDFLAG(IS_IOS) - if (IsStorageAccessGrantEligible() || - IsTopLevelStorageAccessGrantEligible()) { - enabled_features.push_back({blink::features::kStorageAccessAPI, {}}); - } -#endif feature_list_.InitWithFeaturesAndParameters(enabled_features, disabled_features); @@ -359,12 +353,6 @@ base::test::ScopedFeatureList feature_list_; }; -#if !BUILDFLAG(IS_IOS) -TEST(CookieSettings, TestDefaultStorageAccessSetting) { - EXPECT_TRUE(base::FeatureList::IsEnabled(blink::features::kStorageAccessAPI)); -} -#endif - TEST_P(CookieSettingsTest, UserBypassPermanentExceptions) { // Bypass shouldn't be enabled. EXPECT_FALSE(
diff --git a/components/content_settings/core/browser/host_content_settings_map.cc b/components/content_settings/core/browser/host_content_settings_map.cc index a841d88..9d2b89c 100644 --- a/components/content_settings/core/browser/host_content_settings_map.cc +++ b/components/content_settings/core/browser/host_content_settings_map.cc
@@ -1096,27 +1096,52 @@ CHECK(provider); if (include_incognito) { - // Check incognito-only specific settings. It's essential that the - // |RuleIterator| gets out of scope before we get a rule iterator for the - // normal mode. - std::unique_ptr<content_settings::RuleIterator> incognito_rule_iterator( - provider->GetRuleIterator( - content_type, true /* incognito */, - content_settings::PartitionKey::WipGetDefault())); - base::Value value = GetContentSettingValueAndPatterns( - incognito_rule_iterator.get(), primary_url, secondary_url, - primary_pattern, secondary_pattern, metadata, clock); - if (!value.is_none()) - return value; + if (base::FeatureList::IsEnabled( + content_settings::features::kIndexedHostContentSettingsMap)) { + auto rule = provider->GetRule( + primary_url, secondary_url, content_type, /*off_the_record=*/true, + content_settings::PartitionKey::WipGetDefault()); + if (rule) { + return GetContentSettingValueAndPatterns(rule.get(), primary_pattern, + secondary_pattern, metadata); + } + } else { + // Check incognito-only specific settings. It's essential that the + // |RuleIterator| gets out of scope before we get a rule iterator for the + // normal mode. + std::unique_ptr<content_settings::RuleIterator> incognito_rule_iterator( + provider->GetRuleIterator( + content_type, true /* incognito */, + content_settings::PartitionKey::WipGetDefault())); + base::Value value = GetContentSettingValueAndPatterns( + incognito_rule_iterator.get(), primary_url, secondary_url, + primary_pattern, secondary_pattern, metadata, clock); + if (!value.is_none()) { + return value; + } + } } + // No settings from the incognito; use the normal mode. - std::unique_ptr<content_settings::RuleIterator> rule_iterator( - provider->GetRuleIterator( - content_type, false /* incognito */, - content_settings::PartitionKey::WipGetDefault())); - base::Value value = GetContentSettingValueAndPatterns( - rule_iterator.get(), primary_url, secondary_url, primary_pattern, - secondary_pattern, metadata, clock); + base::Value value; + if (base::FeatureList::IsEnabled( + content_settings::features::kIndexedHostContentSettingsMap)) { + auto rule = provider->GetRule( + primary_url, secondary_url, content_type, /*off_the_record=*/false, + content_settings::PartitionKey::WipGetDefault()); + if (rule) { + value = GetContentSettingValueAndPatterns(rule.get(), primary_pattern, + secondary_pattern, metadata); + } + } else { + std::unique_ptr<content_settings::RuleIterator> rule_iterator( + provider->GetRuleIterator( + content_type, false /* incognito */, + content_settings::PartitionKey::WipGetDefault())); + value = GetContentSettingValueAndPatterns( + rule_iterator.get(), primary_url, secondary_url, primary_pattern, + secondary_pattern, metadata, clock); + } if (!value.is_none() && include_incognito) { value = ProcessIncognitoInheritanceBehavior(content_type, std::move(value)); } @@ -1143,19 +1168,33 @@ content_settings::features::kActiveContentSettingExpiry) || (rule->metadata.expiration().is_null() || (rule->metadata.expiration() > clock->Now())))) { - if (primary_pattern) - *primary_pattern = rule->primary_pattern; - if (secondary_pattern) - *secondary_pattern = rule->secondary_pattern; - if (metadata) - *metadata = rule->metadata; - return rule->TakeValue(); + return GetContentSettingValueAndPatterns(rule.get(), primary_pattern, + secondary_pattern, metadata); } } } return base::Value(); } +// static +base::Value HostContentSettingsMap::GetContentSettingValueAndPatterns( + content_settings::Rule* rule, + ContentSettingsPattern* primary_pattern, + ContentSettingsPattern* secondary_pattern, + content_settings::RuleMetaData* metadata) { + if (primary_pattern) { + *primary_pattern = std::move(rule->primary_pattern); + } + if (secondary_pattern) { + *secondary_pattern = std::move(rule->secondary_pattern); + } + if (metadata) { + *metadata = std::move(rule->metadata); + } + DCHECK(!rule->value().is_none()); + return rule->TakeValue(); +} + void HostContentSettingsMap:: MigrateSettingsPrecedingPermissionDelegationActivation() { auto* content_settings_registry =
diff --git a/components/content_settings/core/browser/host_content_settings_map.h b/components/content_settings/core/browser/host_content_settings_map.h index 4efa6df5..1db9e65 100644 --- a/components/content_settings/core/browser/host_content_settings_map.h +++ b/components/content_settings/core/browser/host_content_settings_map.h
@@ -478,6 +478,12 @@ content_settings::RuleMetaData* metadata, base::Clock* clock); + static base::Value GetContentSettingValueAndPatterns( + content_settings::Rule* rule, + ContentSettingsPattern* primary_pattern, + ContentSettingsPattern* secondary_pattern, + content_settings::RuleMetaData* metadata); + // Migrate requesting and top level origin content settings to remove all // settings that have a top level pattern. If there is a pattern set for // (http://x.com, http://y.com) this will remove that pattern and also remove
diff --git a/components/content_settings/core/common/features.cc b/components/content_settings/core/common/features.cc index e5995fb6..6455329 100644 --- a/components/content_settings/core/common/features.cc +++ b/components/content_settings/core/common/features.cc
@@ -100,5 +100,9 @@ const base::FeatureParam<int> kMetadataGrantsThreshold{ &kHostIndexedMetadataGrants, kMetadataGrantsThresholdName, 1}; +BASE_FEATURE(kIndexedHostContentSettingsMap, + "IndexedHostContentSettingsMap", + base::FEATURE_DISABLED_BY_DEFAULT); + } // namespace features } // namespace content_settings
diff --git a/components/content_settings/core/common/features.h b/components/content_settings/core/common/features.h index d6621a2..bcb8ed3 100644 --- a/components/content_settings/core/common/features.h +++ b/components/content_settings/core/common/features.h
@@ -129,6 +129,11 @@ COMPONENT_EXPORT(CONTENT_SETTINGS_FEATURES) extern const base::FeatureParam<int> kMetadataGrantsThreshold; +// Enable indexing HostContentSettings to allow for faster lookups of content +// setting rules. +COMPONENT_EXPORT(CONTENT_SETTINGS_FEATURES) +BASE_DECLARE_FEATURE(kIndexedHostContentSettingsMap); + } // namespace features } // namespace content_settings
diff --git a/components/dbus/menu/menu.cc b/components/dbus/menu/menu.cc index be50e15b..4d0becd 100644 --- a/components/dbus/menu/menu.cc +++ b/components/dbus/menu/menu.cc
@@ -291,9 +291,9 @@ } // IDs of updates needed (none). - response->Writer().AppendArrayOfInt32s(nullptr, 0); + response->Writer().AppendArrayOfInt32s({}); // Invalid IDs. - response->Writer().AppendArrayOfInt32s(id_errors.data(), id_errors.size()); + response->Writer().AppendArrayOfInt32s(id_errors); } void DbusMenu::OnEvent(ScopedMethodResponse* response) { @@ -320,7 +320,7 @@ } } - response->Writer().AppendArrayOfInt32s(id_errors.data(), id_errors.size()); + response->Writer().AppendArrayOfInt32s(id_errors); } void DbusMenu::OnGetGroupProperties(ScopedMethodResponse* response) {
diff --git a/components/dbus/properties/types.cc b/components/dbus/properties/types.cc index a47598f9..888ebf8 100644 --- a/components/dbus/properties/types.cc +++ b/components/dbus/properties/types.cc
@@ -151,7 +151,7 @@ } void DbusByteArray::Write(dbus::MessageWriter* writer) const { - writer->AppendArrayOfBytes(value_->front(), value_->size()); + writer->AppendArrayOfBytes(*value_); } // static
diff --git a/components/enterprise/idle/idle_pref_names.cc b/components/enterprise/idle/idle_pref_names.cc index 1f862dee..25db81a 100644 --- a/components/enterprise/idle/idle_pref_names.cc +++ b/components/enterprise/idle/idle_pref_names.cc
@@ -20,7 +20,16 @@ // The last active time updated based on taps registered in // `browser_view_controller.cc` const char kLastActiveTimestamp[] = "idle_timeout_last_active_timestamp"; + // The time when the browser was last marked as idle. Used with // `kLastActiveTimestamp` to calculate the idle time on start-up. const char kLastIdleTimestamp[] = "idle_timeout_last_idle_timestamp"; + +// If true and a data clearing action is set, data will only be cleared for the +// duration the user was signed in. The policy will also clear data on signout +// since this data will not be accessible on the next timeout when the user +// signs in again with the policy set. +const char kIdleTimeoutPolicyAppliesToUserOnly[] = + "idle_timeout_applies_to_user_only"; + } // namespace enterprise_idle::prefs
diff --git a/components/enterprise/idle/idle_pref_names.h b/components/enterprise/idle/idle_pref_names.h index 3ee606d..3af1081c 100644 --- a/components/enterprise/idle/idle_pref_names.h +++ b/components/enterprise/idle/idle_pref_names.h
@@ -12,6 +12,7 @@ extern const char kLastActiveTimestamp[]; extern const char kLastIdleTimestamp[]; +extern const char kIdleTimeoutPolicyAppliesToUserOnly[]; } // namespace enterprise_idle::prefs #endif // COMPONENTS_ENTERPRISE_IDLE_IDLE_PREF_NAMES_H_
diff --git a/components/enterprise/idle/idle_timeout_policy_handler.cc b/components/enterprise/idle/idle_timeout_policy_handler.cc index e4861db6..1d54856 100644 --- a/components/enterprise/idle/idle_timeout_policy_handler.cc +++ b/components/enterprise/idle/idle_timeout_policy_handler.cc
@@ -123,6 +123,15 @@ if (!log_message.empty()) { LOG_POLICY(INFO, POLICY_PROCESSING) << log_message; } + +#if BUILDFLAG(IS_IOS) + // Set the `kIdleTimeoutPolicyAppliesToUserOnly`pref if the policy is set as a + // user policy. This will determine whether data should be cleared for + // `TimePeriod::ALL_TIME` or only for the time the user was signed in. + bool user_policy = + policies.Get(policy_name())->scope == policy::POLICY_SCOPE_USER; + prefs->SetBoolean(prefs::kIdleTimeoutPolicyAppliesToUserOnly, user_policy); +#endif // BUILDFLAG(IS_IOS) } bool IdleTimeoutActionsPolicyHandler::CheckPolicySettings(
diff --git a/components/enterprise/idle/idle_timeout_policy_handler_unittest.cc b/components/enterprise/idle/idle_timeout_policy_handler_unittest.cc index 7c3f7b6f..f9daf31 100644 --- a/components/enterprise/idle/idle_timeout_policy_handler_unittest.cc +++ b/components/enterprise/idle/idle_timeout_policy_handler_unittest.cc
@@ -40,10 +40,11 @@ SetPolicyValue(policy::key::kSyncDisabled, base::Value(true)); } - void SetPolicyValue(const std::string& policy, base::Value value) { - policies_.Set(policy, policy::POLICY_LEVEL_MANDATORY, - policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_PLATFORM, - std::move(value), nullptr); + void SetPolicyValue(const std::string& policy, + base::Value value, + policy::PolicyScope scope = policy::POLICY_SCOPE_USER) { + policies_.Set(policy, policy::POLICY_LEVEL_MANDATORY, scope, + policy::POLICY_SOURCE_PLATFORM, std::move(value), nullptr); } bool CheckPolicySettings() { @@ -458,4 +459,39 @@ prefs().GetBoolean(syncer::prefs::internal::kSyncPasswords, &enabled)); EXPECT_FALSE(enabled); } + +#if BUILDFLAG(IS_IOS) +TEST_F(IdleTimeoutPolicyHandlerTest, + IdleTimeoutPolicyAppliesToUserOnlyPrefSetCorrectly) { + // Initialize the pref to false to detect the pref changes when the policy is + // set. + prefs().SetBoolean(syncer::prefs::internal::kSyncAutofill, true); + + base::Value::List list; + list.Append("clear_browsing_history"); + list.Append("clear_cookies_and_other_site_data"); + + // Set the policy scope to user and check that + // `kIdleTimeoutPolicyAppliesToUserOnly` is set to true. + SetPolicyValue(policy::key::kIdleTimeout, base::Value(15)); + SetPolicyValue(policy::key::kIdleTimeoutActions, + base::Value(std::move(list))); + CheckAndApplyPolicySettings(); + bool enabled; + ASSERT_TRUE( + prefs().GetBoolean(prefs::kIdleTimeoutPolicyAppliesToUserOnly, &enabled)); + EXPECT_TRUE(enabled); + + // Reset the policy scope to machine and check that + // `kIdleTimeoutPolicyAppliesToUserOnly` is reset to false. + SetPolicyValue(policy::key::kIdleTimeoutActions, base::Value(std::move(list)), + policy::POLICY_SCOPE_MACHINE); + CheckAndApplyPolicySettings(); + ASSERT_TRUE( + prefs().GetBoolean(prefs::kIdleTimeoutPolicyAppliesToUserOnly, &enabled)); + EXPECT_FALSE(enabled); +} + +#endif // BUILDFLAG(IS_IOS) + } // namespace enterprise_idle
diff --git a/components/feedback/redaction_tool/redaction_tool.cc b/components/feedback/redaction_tool/redaction_tool.cc index 8be265a..a021e83 100644 --- a/components/feedback/redaction_tool/redaction_tool.cc +++ b/components/feedback/redaction_tool/redaction_tool.cc
@@ -174,6 +174,11 @@ // log entries from ChromeOS's crash_sender program. {"Crash ID", R"xxx((Crash report receipt ID )([0-9a-fA-F]+)(.+?))xxx", PIIType::kCrashId}, + + // Names of ChromeOS cryptohome logical volumes and device mapper devices, + // which include a partial hash of the user id. + {"UID", R"xxx(((?:cryptohome|dmcrypt)-+)([0-9a-fA-F]+)(-+))xxx", + PIIType::kStableIdentifier}, }; bool MaybeUnmapAddress(IPAddress* addr) {
diff --git a/components/feedback/redaction_tool/redaction_tool_unittest.cc b/components/feedback/redaction_tool/redaction_tool_unittest.cc index 82f20638..32afa73 100644 --- a/components/feedback/redaction_tool/redaction_tool_unittest.cc +++ b/components/feedback/redaction_tool/redaction_tool_unittest.cc
@@ -331,6 +331,12 @@ EXPECT_EQ("(HASH:1122 1)", redactor_.Redact("11223344556677889900AABBCCDDEEFF")); + // Make sure (partial) user id hash in cryptohome devices is redacted. + EXPECT_EQ("dmcrypt-(UID: 1)-cache", + redactor_.Redact("dmcrypt-123abcde-cache")); + EXPECT_EQ("FOO-cryptohome--(UID: 1)--cache", + redactor_.Redact("FOO-cryptohome--123abcde--cache")); + // Make sure custom pattern redaction is invoked. EXPECT_EQ("Cell ID: '(CellID: 1)'", RedactCustomPatterns("Cell ID: 'A1B2'"));
diff --git a/components/metrics/generate_expired_histograms_array.gni b/components/metrics/generate_expired_histograms_array.gni index 2e250f3..2929ae0 100644 --- a/components/metrics/generate_expired_histograms_array.gni +++ b/components/metrics/generate_expired_histograms_array.gni
@@ -197,6 +197,7 @@ "//tools/metrics/histograms/metadata/quickstart/enums.xml", "//tools/metrics/histograms/metadata/quickstart/histograms.xml", "//tools/metrics/histograms/metadata/quota/histograms.xml", + "//tools/metrics/histograms/metadata/readaloud/enums.xml", "//tools/metrics/histograms/metadata/readaloud/histograms.xml", "//tools/metrics/histograms/metadata/renderer/histograms.xml", "//tools/metrics/histograms/metadata/renderer4/histograms.xml",
diff --git a/components/optimization_guide/core/hints_processing_util.cc b/components/optimization_guide/core/hints_processing_util.cc index 4982022..e873af16 100644 --- a/components/optimization_guide/core/hints_processing_util.cc +++ b/components/optimization_guide/core/hints_processing_util.cc
@@ -108,6 +108,11 @@ return "CapitalOneCreditCardEntertainmentBenefits"; case proto::OptimizationType::CAPITAL_ONE_CREDIT_CARD_STREAMING_BENEFITS: return "CapitalOneCreditCardStreamingBenefits"; + case proto::OptimizationType::AMERICAN_EXPRESS_CREDIT_CARD_FLIGHT_BENEFITS: + return "AmericanExpressCreditCardFlightBenefits"; + case proto::OptimizationType:: + AMERICAN_EXPRESS_CREDIT_CARD_SUBSCRIPTION_BENEFITS: + return "AmericanExpressCreditCardSubscriptionBenefits"; } // The returned string is used to record histograms for the optimization type.
diff --git a/components/optimization_guide/proto/autofill_field_classification_model_metadata.proto b/components/optimization_guide/proto/autofill_field_classification_model_metadata.proto index 0b86020f..6f6b7ae 100644 --- a/components/optimization_guide/proto/autofill_field_classification_model_metadata.proto +++ b/components/optimization_guide/proto/autofill_field_classification_model_metadata.proto
@@ -19,7 +19,7 @@ repeated string input_token = 1; // The mapping from the model's outputs to the (integer representation of) the - // corresponding `autofill::ServerFieldType`. + // corresponding `autofill::FieldType`. repeated fixed32 output_type = 2; // For every field, the model outputs a list of confidences for every
diff --git a/components/optimization_guide/proto/hints.proto b/components/optimization_guide/proto/hints.proto index c29acae..c592a07 100644 --- a/components/optimization_guide/proto/hints.proto +++ b/components/optimization_guide/proto/hints.proto
@@ -217,6 +217,10 @@ CAPITAL_ONE_CREDIT_CARD_GROCERY_BENEFITS = 44; CAPITAL_ONE_CREDIT_CARD_ENTERTAINMENT_BENEFITS = 45; CAPITAL_ONE_CREDIT_CARD_STREAMING_BENEFITS = 46; + // The below optimizations provide information about merchant URLs that only + // American Express supports for credit card category benefits. + AMERICAN_EXPRESS_CREDIT_CARD_FLIGHT_BENEFITS = 47; + AMERICAN_EXPRESS_CREDIT_CARD_SUBSCRIPTION_BENEFITS = 48; } // Presents semantics for how page load URLs should be matched.
diff --git a/components/os_crypt/sync/kwallet_dbus.cc b/components/os_crypt/sync/kwallet_dbus.cc index 5f35519..475caf9b 100644 --- a/components/os_crypt/sync/kwallet_dbus.cc +++ b/components/os_crypt/sync/kwallet_dbus.cc
@@ -342,11 +342,11 @@ int* return_code_ptr) { dbus::MethodCall method_call(kKWalletInterface, "writeEntry"); dbus::MessageWriter builder(&method_call); - builder.AppendInt32(wallet_handle); // handle - builder.AppendString(folder_name); // folder - builder.AppendString(key); // key - builder.AppendArrayOfBytes(data, length); // value - builder.AppendString(app_name); // appid + builder.AppendInt32(wallet_handle); // handle + builder.AppendString(folder_name); // folder + builder.AppendString(key); // key + builder.AppendArrayOfBytes(base::make_span(data, length)); // value + builder.AppendString(app_name); // appid std::unique_ptr<dbus::Response> response( kwallet_proxy_ ->CallMethodAndBlock(&method_call,
diff --git a/components/os_crypt/sync/kwallet_dbus_unittest.cc b/components/os_crypt/sync/kwallet_dbus_unittest.cc index 625be73..e1f0def 100644 --- a/components/os_crypt/sync/kwallet_dbus_unittest.cc +++ b/components/os_crypt/sync/kwallet_dbus_unittest.cc
@@ -48,7 +48,7 @@ const std::vector<uint8_t>& bytes) { std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); dbus::MessageWriter writer(response.get()); - writer.AppendArrayOfBytes(bytes.data(), bytes.size()); + writer.AppendArrayOfBytes(bytes); return response; }
diff --git a/components/page_info/page_info.cc b/components/page_info/page_info.cc index cd36a2b..ff6b49f 100644 --- a/components/page_info/page_info.cc +++ b/components/page_info/page_info.cc
@@ -37,6 +37,7 @@ #include "components/content_settings/core/common/features.h" #include "components/page_info/page_info_delegate.h" #include "components/page_info/page_info_ui.h" +#include "components/permissions/constants.h" #include "components/permissions/features.h" #include "components/permissions/object_permission_context_base.h" #include "components/permissions/origin_keyed_permission_action_service.h" @@ -663,7 +664,7 @@ } if (type == ContentSettingsType::STORAGE_ACCESS) { constraints.set_lifetime( - blink::features::kStorageAccessAPIExplicitPermissionLifetime.Get()); + permissions::kStorageAccessAPIExplicitPermissionLifetime); } map->SetNarrowestContentSetting(primary_url, site_url_, type, setting,
diff --git a/components/password_manager/core/browser/mock_password_reuse_manager.h b/components/password_manager/core/browser/mock_password_reuse_manager.h index f5dfbfb8..9def184 100644 --- a/components/password_manager/core/browser/mock_password_reuse_manager.h +++ b/components/password_manager/core/browser/mock_password_reuse_manager.h
@@ -68,6 +68,11 @@ (std::unique_ptr<PasswordStoreSigninNotifier> notifier), (override)); MOCK_METHOD(void, ScheduleEnterprisePasswordURLUpdate, (), (override)); + MOCK_METHOD(void, + MaybeSavePasswordHash, + (const PasswordForm* submitted_form, + PasswordManagerClient* client), + (override)); }; } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index 10e20f4..ad24b33 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -475,7 +475,13 @@ PasswordFormManager* manager = GetSubmittedManager(); if (manager && manager->GetSubmittedForm() ->form_data.is_gaia_with_skip_save_password_form) { - MaybeSavePasswordHash(manager); + password_manager::PasswordReuseManager* reuse_manager = + client_->GetPasswordReuseManager(); + // May be null in tests. + if (reuse_manager) { + reuse_manager->MaybeSavePasswordHash(manager->GetSubmittedForm(), + client_); + } } } @@ -1149,7 +1155,13 @@ if (!able_to_save_passwords) return; - MaybeSavePasswordHash(submitted_manager); + password_manager::PasswordReuseManager* reuse_manager = + client_->GetPasswordReuseManager(); + // May be null in tests. + if (reuse_manager) { + reuse_manager->MaybeSavePasswordHash(submitted_manager->GetSubmittedForm(), + client_); + } // TODO(https://crbug.com/831123): Implement checking whether to save with // PasswordFormManager. @@ -1208,71 +1220,6 @@ ResetSubmittedManager(); } -void PasswordManager::MaybeSavePasswordHash( - PasswordFormManager* submitted_manager) { - if (!base::FeatureList::IsEnabled(features::kPasswordReuseDetectionEnabled)) { - return; - } - - const PasswordForm* submitted_form = submitted_manager->GetSubmittedForm(); - // When |username_value| is empty, it's not clear whether the submitted - // credentials are really Gaia or enterprise credentials. Don't save - // password hash in that case. - std::string username = base::UTF16ToUTF8(submitted_form->username_value); - if (username.empty()) - return; - - password_manager::PasswordReuseManager* reuse_manager = - client_->GetPasswordReuseManager(); - // May be null in tests. - if (!reuse_manager) - return; - - bool should_save_enterprise_pw = - client_->GetStoreResultFilter()->ShouldSaveEnterprisePasswordHash( - *submitted_form); - bool should_save_gaia_pw = - client_->GetStoreResultFilter()->ShouldSaveGaiaPasswordHash( - *submitted_form); - - if (!should_save_enterprise_pw && !should_save_gaia_pw) - return; - - if (password_manager_util::IsLoggingActive(client_)) { - BrowserSavePasswordProgressLogger logger(client_->GetLogManager()); - logger.LogMessage(Logger::STRING_SAVE_PASSWORD_HASH); - } - - // Canonicalizes username if it is an email. - if (username.find('@') != std::string::npos) - username = gaia::CanonicalizeEmail(username); - bool is_password_change = !submitted_form->new_password_element.empty(); - const std::u16string password = is_password_change - ? submitted_form->new_password_value - : submitted_form->password_value; - - if (should_save_enterprise_pw) { - reuse_manager->SaveEnterprisePasswordHash(username, password); - return; - } - - DCHECK(should_save_gaia_pw); - bool is_sync_account_email = - client_->GetStoreResultFilter()->IsSyncAccountEmail(username); - metrics_util::GaiaPasswordHashChange event = - is_sync_account_email - ? (is_password_change - ? metrics_util::GaiaPasswordHashChange::CHANGED_IN_CONTENT_AREA - : metrics_util::GaiaPasswordHashChange::SAVED_IN_CONTENT_AREA) - : (is_password_change - ? metrics_util::GaiaPasswordHashChange:: - NOT_SYNC_PASSWORD_CHANGE - : metrics_util::GaiaPasswordHashChange::SAVED_IN_CONTENT_AREA); - reuse_manager->SaveGaiaPasswordHash( - username, password, - /*is_sync_password_for_metrics=*/is_sync_account_email, event); -} - void PasswordManager::ProcessAutofillPredictions( PasswordManagerDriver* driver, const autofill::FormData& form,
diff --git a/components/password_manager/core/browser/password_manager.h b/components/password_manager/core/browser/password_manager.h index ffb93a0..9346bb08 100644 --- a/components/password_manager/core/browser/password_manager.h +++ b/components/password_manager/core/browser/password_manager.h
@@ -262,10 +262,6 @@ // appropriate. void OnLoginSuccessful(); - // Helper function called inside OnLoginSuccessful() to save password hash - // data from |submitted_manager| for password reuse detection purpose. - void MaybeSavePasswordHash(PasswordFormManager* submitted_manager); - // Checks for every form in |forms_data| whether |pending_login_managers_| // already contain a manager for that form. If not, adds a manager for each // such form.
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index 44dce4d..b419fef 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -1480,11 +1480,7 @@ .WillByDefault(Return(true)); ON_CALL(*client_.GetStoreResultFilter(), IsSyncAccountEmail(_)) .WillByDefault(Return(true)); - EXPECT_CALL(reuse_manager_, - SaveGaiaPasswordHash( - "googleuser", form_data.fields[1].value, - /*is_primary_account=*/true, - metrics_util::GaiaPasswordHashChange::SAVED_IN_CONTENT_AREA)); + EXPECT_CALL(reuse_manager_, MaybeSavePasswordHash(_, _)); EXPECT_CALL(client_, IsSavingAndFillingEnabled(form_data.url)) .WillRepeatedly(Return(true)); @@ -1525,11 +1521,7 @@ EXPECT_CALL(client_, PromptUserToSaveOrUpdatePassword).Times(0); - EXPECT_CALL(reuse_manager_, - SaveGaiaPasswordHash( - "googleuser", form_data.fields[1].value, - /*is_primary_account=*/true, - metrics_util::GaiaPasswordHashChange::SAVED_IN_CONTENT_AREA)); + EXPECT_CALL(reuse_manager_, MaybeSavePasswordHash(_, _)); OnPasswordFormSubmitted(form_data); observed.clear(); @@ -1553,12 +1545,7 @@ .WillByDefault(Return(false)); ON_CALL(*client_.GetStoreResultFilter(), IsSyncAccountEmail(_)) .WillByDefault(Return(true)); - - EXPECT_CALL(reuse_manager_, - SaveGaiaPasswordHash( - "googleuser", form_data.fields[1].value, - /*is_primary_account=*/true, - metrics_util::GaiaPasswordHashChange::SAVED_IN_CONTENT_AREA)); + EXPECT_CALL(reuse_manager_, MaybeSavePasswordHash(_, _)); EXPECT_CALL(client_, IsNewTabPage()).WillRepeatedly(Return(true)); OnPasswordFormSubmitted(form_data); @@ -1627,11 +1614,7 @@ .WillByDefault(Return(true)); ON_CALL(*client_.GetStoreResultFilter(), IsSyncAccountEmail(_)) .WillByDefault(Return(true)); - EXPECT_CALL( - reuse_manager_, - SaveGaiaPasswordHash( - "googleuser", form.password_value, /*is_primary_account=*/true, - metrics_util::GaiaPasswordHashChange::SAVED_IN_CONTENT_AREA)); + EXPECT_CALL(reuse_manager_, MaybeSavePasswordHash(_, _)); manager()->OnPasswordFormSubmitted(&driver_, form.form_data); @@ -2562,8 +2545,6 @@ // Simulate that this credentials which is similar to be sync credentials. client_.FilterAllResultsForSaving(); - // Check that no Gaia credential password hash is saved. - EXPECT_CALL(reuse_manager_, SaveGaiaPasswordHash).Times(0); OnPasswordFormSubmitted(form_data); observed.clear(); manager()->OnPasswordFormsRendered(&driver_, observed); @@ -2581,10 +2562,6 @@ EXPECT_CALL(client_, IsSavingAndFillingEnabled(form_data.url)) .WillRepeatedly(Return(true)); - // Check that no Gaia credential password hash is saved since these - // credentials are eligible for saving. - EXPECT_CALL(reuse_manager_, SaveGaiaPasswordHash).Times(0); - std::unique_ptr<PasswordFormManagerForUI> form_manager_to_save; EXPECT_CALL(client_, PromptUserToSaveOrUpdatePassword) .WillOnce(MoveArgAndReturn<0>(&form_manager_to_save, true)); @@ -2733,12 +2710,7 @@ .WillByDefault(Return(true)); ON_CALL(*client_.GetStoreResultFilter(), IsSyncAccountEmail(_)) .WillByDefault(Return(true)); - EXPECT_CALL( - reuse_manager_, - SaveGaiaPasswordHash( - "googleuser", form_data.fields[1].value, - /*is_primary_account=*/true, - metrics_util::GaiaPasswordHashChange::CHANGED_IN_CONTENT_AREA)); + EXPECT_CALL(reuse_manager_, MaybeSavePasswordHash(_, _)); client_.FilterAllResultsForSaving(); OnPasswordFormSubmitted(form_data); @@ -2765,11 +2737,7 @@ ON_CALL(*client_.GetStoreResultFilter(), ShouldSaveGaiaPasswordHash(_)) .WillByDefault(Return(true)); - EXPECT_CALL( - reuse_manager_, - SaveGaiaPasswordHash( - "googleuser", form_data.fields[1].value, /*is_primary_account=*/false, - metrics_util::GaiaPasswordHashChange::SAVED_IN_CONTENT_AREA)); + EXPECT_CALL(reuse_manager_, MaybeSavePasswordHash(_, _)); client_.FilterAllResultsForSaving(); OnPasswordFormSubmitted(form_data); @@ -2795,11 +2763,7 @@ ON_CALL(*client_.GetStoreResultFilter(), ShouldSaveGaiaPasswordHash(_)) .WillByDefault(Return(true)); - EXPECT_CALL( - reuse_manager_, - SaveGaiaPasswordHash( - "googleuser", form_data.fields[1].value, /*is_primary_account=*/false, - metrics_util::GaiaPasswordHashChange::NOT_SYNC_PASSWORD_CHANGE)); + EXPECT_CALL(reuse_manager_, MaybeSavePasswordHash(_, _)); client_.FilterAllResultsForSaving(); OnPasswordFormSubmitted(form_data); @@ -2829,8 +2793,7 @@ .WillByDefault(Return(true)); ON_CALL(*client_.GetStoreResultFilter(), IsSyncAccountEmail(_)) .WillByDefault(Return(false)); - EXPECT_CALL(reuse_manager_, SaveEnterprisePasswordHash( - "googleuser", form_data.fields[1].value)); + EXPECT_CALL(reuse_manager_, MaybeSavePasswordHash(_, _)); client_.FilterAllResultsForSaving(); OnPasswordFormSubmitted(form_data);
diff --git a/components/password_manager/core/browser/password_reuse_manager.h b/components/password_manager/core/browser/password_reuse_manager.h index 7281487..1970e17 100644 --- a/components/password_manager/core/browser/password_reuse_manager.h +++ b/components/password_manager/core/browser/password_reuse_manager.h
@@ -22,8 +22,10 @@ namespace password_manager { +class PasswordManagerClient; class PasswordStoreInterface; class PasswordStoreSigninNotifier; +struct PasswordForm; // Per-store class responsible for detection of password reuse, i.e. that the // user input on some site contains the password saved on another site. @@ -103,6 +105,11 @@ // Schedules the update of enterprise login and change password URLs. // These URLs are used in enterprise password reuse detection. virtual void ScheduleEnterprisePasswordURLUpdate() = 0; + + // Saves the hash version of a password if it corresponds to an + // enterprise or gaia password. + virtual void MaybeSavePasswordHash(const PasswordForm* submitted_form, + PasswordManagerClient* client) = 0; }; } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_reuse_manager_impl.cc b/components/password_manager/core/browser/password_reuse_manager_impl.cc index 84e4486..5c2523c 100644 --- a/components/password_manager/core/browser/password_reuse_manager_impl.cc +++ b/components/password_manager/core/browser/password_reuse_manager_impl.cc
@@ -12,13 +12,20 @@ #include "base/functional/bind.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" +#include "base/strings/utf_string_conversions.h" #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool.h" +#include "components/autofill/core/common/save_password_progress_logger.h" +#include "components/password_manager/core/browser/browser_save_password_progress_logger.h" +#include "components/password_manager/core/browser/password_form.h" +#include "components/password_manager/core/browser/password_manager_client.h" +#include "components/password_manager/core/browser/password_manager_util.h" #include "components/password_manager/core/browser/password_store_signin_notifier.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/signin/public/base/consent_level.h" +#include "google_apis/gaia/gaia_auth_util.h" #include "third_party/abseil-cpp/absl/types/optional.h" #if BUILDFLAG(IS_ANDROID) @@ -491,4 +498,66 @@ } #endif } + +void PasswordReuseManagerImpl::MaybeSavePasswordHash( + const PasswordForm* submitted_form, + PasswordManagerClient* client) { + if (!base::FeatureList::IsEnabled(features::kPasswordReuseDetectionEnabled)) { + return; + } + // When |username_value| is empty, it's not clear whether the submitted + // credentials are really Gaia or enterprise credentials. Don't save + // password hash in that case. + std::string username = base::UTF16ToUTF8(submitted_form->username_value); + if (username.empty()) { + return; + } + + bool should_save_enterprise_pw = + client->GetStoreResultFilter()->ShouldSaveEnterprisePasswordHash( + *submitted_form); + bool should_save_gaia_pw = + client->GetStoreResultFilter()->ShouldSaveGaiaPasswordHash( + *submitted_form); + + if (!should_save_enterprise_pw && !should_save_gaia_pw) { + return; + } + + if (password_manager_util::IsLoggingActive(client)) { + BrowserSavePasswordProgressLogger logger(client->GetLogManager()); + logger.LogMessage( + autofill::SavePasswordProgressLogger::STRING_SAVE_PASSWORD_HASH); + } + + // Canonicalizes username if it is an email. + if (username.find('@') != std::string::npos) { + username = gaia::CanonicalizeEmail(username); + } + bool is_password_change = !submitted_form->new_password_element.empty(); + const std::u16string password = is_password_change + ? submitted_form->new_password_value + : submitted_form->password_value; + + if (should_save_enterprise_pw) { + SaveEnterprisePasswordHash(username, password); + return; + } + + CHECK(should_save_gaia_pw); + bool is_sync_account_email = + client->GetStoreResultFilter()->IsSyncAccountEmail(username); + metrics_util::GaiaPasswordHashChange event = + is_sync_account_email + ? (is_password_change + ? metrics_util::GaiaPasswordHashChange::CHANGED_IN_CONTENT_AREA + : metrics_util::GaiaPasswordHashChange::SAVED_IN_CONTENT_AREA) + : (is_password_change + ? metrics_util::GaiaPasswordHashChange:: + NOT_SYNC_PASSWORD_CHANGE + : metrics_util::GaiaPasswordHashChange::SAVED_IN_CONTENT_AREA); + SaveGaiaPasswordHash(username, password, + /*is_sync_password_for_metrics=*/is_sync_account_email, + event); +} } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_reuse_manager_impl.h b/components/password_manager/core/browser/password_reuse_manager_impl.h index a737c2e4..d9f3021 100644 --- a/components/password_manager/core/browser/password_reuse_manager_impl.h +++ b/components/password_manager/core/browser/password_reuse_manager_impl.h
@@ -71,6 +71,8 @@ void SetPasswordStoreSigninNotifier( std::unique_ptr<PasswordStoreSigninNotifier> notifier) override; void ScheduleEnterprisePasswordURLUpdate() override; + void MaybeSavePasswordHash(const PasswordForm* submitted_form, + PasswordManagerClient* client) override; private: // Schedules the update of password hashes used by reuse detector.
diff --git a/components/password_manager/core/browser/password_reuse_manager_impl_unittest.cc b/components/password_manager/core/browser/password_reuse_manager_impl_unittest.cc index 8aec40875..9d0866c 100644 --- a/components/password_manager/core/browser/password_reuse_manager_impl_unittest.cc +++ b/components/password_manager/core/browser/password_reuse_manager_impl_unittest.cc
@@ -14,6 +14,8 @@ #include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_store/test_password_store.h" #include "components/password_manager/core/browser/password_store_signin_notifier.h" +#include "components/password_manager/core/browser/stub_credentials_filter.h" +#include "components/password_manager/core/browser/stub_password_manager_client.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/prefs/pref_registry_simple.h" @@ -76,6 +78,31 @@ MOCK_METHOD(void, SetCredentials, (const std::string&), (override)); }; +class MockStoreResultFilter : public StubCredentialsFilter { + public: + MOCK_METHOD(bool, + ShouldSaveGaiaPasswordHash, + (const PasswordForm&), + (const override)); + MOCK_METHOD(bool, + ShouldSaveEnterprisePasswordHash, + (const PasswordForm&), + (const override)); +}; + +class MockPasswordManagerClient : public StubPasswordManagerClient { + public: + MockPasswordManagerClient() { + ON_CALL(*this, GetStoreResultFilter()).WillByDefault(Return(&filter_)); + } + MOCK_METHOD(const MockStoreResultFilter*, + GetStoreResultFilter, + (), + (const, override)); + + private: + testing::NiceMock<MockStoreResultFilter> filter_; +}; class PasswordReuseManagerImplTest : public testing::Test { public: PasswordReuseManagerImplTest() = default; @@ -472,6 +499,53 @@ RunUntilIdle(); } +TEST_F(PasswordReuseManagerImplTest, MaybeSavePasswordHashNoHashSaved) { + PasswordForm submitted_form = + CreateForm("http://yahoo.com", u"user@yahoo.com", u"password", + PasswordForm::Store::kAccountStore); + MockPasswordManagerClient client; + reuse_manager()->MaybeSavePasswordHash(&submitted_form, &client); + + RunUntilIdle(); + EXPECT_EQ(0u, prefs().GetList(prefs::kPasswordHashDataList).size()); +} + +TEST_F(PasswordReuseManagerImplTest, MaybeSavePasswordHashGaiaHashSaved) { + PasswordForm submitted_form = + CreateForm("http://google.com", u"user@gmail.com", u"password", + PasswordForm::Store::kAccountStore); + MockPasswordManagerClient client; + ON_CALL(*client.GetStoreResultFilter(), ShouldSaveGaiaPasswordHash(_)) + .WillByDefault(Return(true)); + reuse_manager()->MaybeSavePasswordHash(&submitted_form, &client); + + RunUntilIdle(); + // Check that right pref has been saved. + PasswordHashData password_hash_data = + ConvertToPasswordHashData( + prefs().GetList(prefs::kPasswordHashDataList)[0]) + .value(); + EXPECT_TRUE(password_hash_data.is_gaia_password); +} + +TEST_F(PasswordReuseManagerImplTest, MaybeSavePasswordHashEnterpriseHashSaved) { + PasswordForm submitted_form = + CreateForm("http://somecorp.com", u"user@somecorp.com", u"password", + PasswordForm::Store::kAccountStore); + MockPasswordManagerClient client; + ON_CALL(*client.GetStoreResultFilter(), ShouldSaveEnterprisePasswordHash(_)) + .WillByDefault(Return(true)); + reuse_manager()->MaybeSavePasswordHash(&submitted_form, &client); + + RunUntilIdle(); + // Check that right pref has been saved. + PasswordHashData password_hash_data = + ConvertToPasswordHashData( + prefs().GetList(prefs::kPasswordHashDataList)[0]) + .value(); + EXPECT_FALSE(password_hash_data.is_gaia_password); +} + #if BUILDFLAG(IS_ANDROID) TEST_F(PasswordReuseManagerImplTest, GaiaPasswordSavedFromSharedPref) { ON_CALL(*shared_pref_delegate_android(), GetCredentials(_))
diff --git a/components/permissions/constants.cc b/components/permissions/constants.cc index ef5cd98..fe4eac9 100644 --- a/components/permissions/constants.cc +++ b/components/permissions/constants.cc
@@ -61,4 +61,14 @@ // from Android builds. const char kRevokedKey[] = "revoked"; + +const base::TimeDelta kStorageAccessAPIExplicitPermissionLifetime = + base::Days(30); + +const base::TimeDelta kStorageAccessAPIImplicitPermissionLifetime = + base::Hours(24); + +const base::TimeDelta kStorageAccessAPIRelatedWebsiteSetsLifetime = + base::Days(30); + } // namespace permissions
diff --git a/components/permissions/constants.h b/components/permissions/constants.h index cc71378..510c7ba 100644 --- a/components/permissions/constants.h +++ b/components/permissions/constants.h
@@ -79,6 +79,21 @@ COMPONENT_EXPORT(PERMISSIONS_COMMON) extern const char kRevokedKey[]; +// How long an explicit Storage Access API permission grant/denial should last +// (not taking renewals into account). +COMPONENT_EXPORT(PERMISSIONS_COMMON) +extern const base::TimeDelta kStorageAccessAPIExplicitPermissionLifetime; + +// How long an implicit Storage Access API permission grant/denial should last +// (not taking renewals into account). +COMPONENT_EXPORT(PERMISSIONS_COMMON) +extern const base::TimeDelta kStorageAccessAPIImplicitPermissionLifetime; + +// How long a Related Website Sets Storage Access API permission +// grant/denial should last (not taking renewals into account). +COMPONENT_EXPORT(PERMISSIONS_COMMON) +extern const base::TimeDelta kStorageAccessAPIRelatedWebsiteSetsLifetime; + } // namespace permissions #endif // COMPONENTS_PERMISSIONS_CONSTANTS_H_
diff --git a/components/plus_addresses/resources/internal b/components/plus_addresses/resources/internal index 65376fc..8babd9d 160000 --- a/components/plus_addresses/resources/internal +++ b/components/plus_addresses/resources/internal
@@ -1 +1 @@ -Subproject commit 65376fc4825ef797744bbdda81d2e571ded37ad8 +Subproject commit 8babd9da0911bfc8afe09c49358d10be85a2558e
diff --git a/components/policy/resources/templates/policies.yaml b/components/policy/resources/templates/policies.yaml index 06c7137..a936bdf3 100644 --- a/components/policy/resources/templates/policies.yaml +++ b/components/policy/resources/templates/policies.yaml
@@ -1190,6 +1190,7 @@ 1189: ListenToThisPageEnabled 1190: AlwaysOnVpnPreConnectUrlAllowlist 1191: CACertificates + 1192: CADistrustedCertificates atomic_groups: 1: Homepage 2: RemoteAccess
diff --git a/components/policy/resources/templates/policy_definitions/CertificateManagement/CACertificates.yaml b/components/policy/resources/templates/policy_definitions/CertificateManagement/CACertificates.yaml index 21d3e2f6..0f1684eb 100644 --- a/components/policy/resources/templates/policy_definitions/CertificateManagement/CACertificates.yaml +++ b/components/policy/resources/templates/policy_definitions/CertificateManagement/CACertificates.yaml
@@ -1,7 +1,7 @@ -caption: TLS server certificates that should be trusted by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> +caption: TLS certificates that should be trusted by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> for server authentication default: null desc: |- - A list of TLS certificates that should be trusted by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. + A list of TLS certificates that should be trusted by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> for server authentication. Certificates should be base64-encoded. example_value: - MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/JdmZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X
diff --git a/components/policy/resources/templates/policy_definitions/CertificateManagement/CADistrustedCertificates.yaml b/components/policy/resources/templates/policy_definitions/CertificateManagement/CADistrustedCertificates.yaml new file mode 100644 index 0000000..e11caad --- /dev/null +++ b/components/policy/resources/templates/policy_definitions/CertificateManagement/CADistrustedCertificates.yaml
@@ -0,0 +1,32 @@ +caption: TLS certificates that should be distrusted by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> for server authentication +default: null +desc: |- + A list of certificate public keys that should be distrusted by <ph + name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> for TLS server + authentication. + + The policy value is a list of base64-encoded X.509 certificates. Any + certificate with a matching SPKI (SubjectPublicKeyInfo) will be distrusted. +example_value: + - MIIB/TCCAaOgAwIBAgIUQthnWVsd1jWpUCNBf/uILjXC+t4wCgYIKoZIzj0EAwIwVDELMAkGA1UEBhMCVVMxETAPBgNVBAgMCFZpcmdpbmlhMQ8wDQYDVQQHDAZSZXN0b24xITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMzEyMDcxNjE5NTVaFw0yMzEyMjExNjE5NTVaMFQxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhWaXJnaW5pYTEPMA0GA1UEBwwGUmVzdG9uMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ9Akav/KB0aVA9FM1QK4J1CEHn5rFOyY/nxcr5HG3+Fom0Kwu5zTR/kz9eOYgtG/1NmCzbiEKaULDfzA8V9aJ7o1MwUTAdBgNVHQ4EFgQUq37bLKiuw8Y/G+rurMf46hw7EekwHwYDVR0jBBgwFoAUq37bLKiuw8Y/G+rurMf46hw7EekwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEA/JhtLSgtVOcXkgFJ9V5Vb6lhGdiKQFfzO9wTxPeCxCECIFePYPucys2n/r9MOBMHiX/8068ssv+uceqokzUg0mAb +features: + dynamic_refresh: true + per_profile: true +owners: +- dadrian@chromium.org +- davidben@chromium.org +- hchao@chromium.org +- mattm@chromium.org +schema: + items: + type: string + type: array +# Supported platforms should be kept in sync with the +# chrome_certificate_policies_supported build flag in +# chrome/common/features.gni +future_on: +- chrome.linux +- chrome.mac +- chrome.win +tags: [] +type: list
diff --git a/components/policy/test/data/pref_mapping/CADistrustedCertificates.json b/components/policy/test/data/pref_mapping/CADistrustedCertificates.json new file mode 100644 index 0000000..e03f377a --- /dev/null +++ b/components/policy/test/data/pref_mapping/CADistrustedCertificates.json
@@ -0,0 +1,41 @@ +[ + { + "os": [ + "win", + "mac", + "linux" + ], + "policy_pref_mapping_tests": [ + { + "note": "Default value (no policies set).", + "prefs": { + "certificates.ca_distrusted_certificates": { + "default_value": [] + } + } + }, + { + "note": "One value.", + "policies": { + "CADistrustedCertificates": [ "cert1" ] + }, + "prefs": { + "certificates.ca_distrusted_certificates": { + "value": [ "cert1" ] + } + } + }, + { + "note": "Multiple values.", + "policies": { + "CADistrustedCertificates": [ "cert1", "cert2", "cert3" ] + }, + "prefs": { + "certificates.ca_distrusted_certificates": { + "value": [ "cert1", "cert2", "cert3" ] + } + } + } + ] + } +]
diff --git a/components/reading_list/core/BUILD.gn b/components/reading_list/core/BUILD.gn index 7dbd0fc2..e9330eb7 100644 --- a/components/reading_list/core/BUILD.gn +++ b/components/reading_list/core/BUILD.gn
@@ -27,6 +27,7 @@ deps = [ "//components/keyed_service/core", "//components/prefs", + "//components/reading_list/features:flags", "//components/sync", "//net", "//url",
diff --git a/components/reading_list/core/dual_reading_list_model.cc b/components/reading_list/core/dual_reading_list_model.cc index 3a764c50..773bef0 100644 --- a/components/reading_list/core/dual_reading_list_model.cc +++ b/components/reading_list/core/dual_reading_list_model.cc
@@ -11,6 +11,7 @@ #include "base/strings/string_util.h" #include "components/reading_list/core/reading_list_entry.h" #include "components/reading_list/core/reading_list_model_impl.h" +#include "components/reading_list/features/reading_list_switches.h" #include "components/sync/base/features.h" #include "google_apis/gaia/core_account_id.h" #include "url/gurl.h" @@ -67,7 +68,8 @@ // TODO(crbug.com/1402200): This logic should be moved to a controller and // made more sophisticated by enabling it only if the user opted in (possibly // pref-based). - if (syncer::IsReadingListAccountStorageEnabled()) { + if (base::FeatureList::IsEnabled( + syncer::kReadingListEnableSyncTransportModeUponSignIn)) { return account_model_->GetSyncControllerDelegate(); }
diff --git a/components/reading_list/features/reading_list_switches.cc b/components/reading_list/features/reading_list_switches.cc index 36fe376..07b402c 100644 --- a/components/reading_list/features/reading_list_switches.cc +++ b/components/reading_list/features/reading_list_switches.cc
@@ -17,5 +17,10 @@ "ReadLaterBackendMigration", base::FEATURE_DISABLED_BY_DEFAULT); +bool IsReadingListAccountStorageUIEnabled() { + return base::FeatureList::IsEnabled( + syncer::kReadingListEnableSyncTransportModeUponSignIn); +} + } // namespace switches } // namespace reading_list
diff --git a/components/reading_list/features/reading_list_switches.h b/components/reading_list/features/reading_list_switches.h index b6874efd..24835fb1 100644 --- a/components/reading_list/features/reading_list_switches.h +++ b/components/reading_list/features/reading_list_switches.h
@@ -19,6 +19,10 @@ // details. BASE_DECLARE_FEATURE(kReadLaterBackendMigration); +// Returns whether reading list storage related UI can be enabled, by testing +// `kReadingListEnableSyncTransportModeUponSignIn`. +bool IsReadingListAccountStorageUIEnabled(); + } // namespace reading_list::switches #endif // COMPONENTS_READING_LIST_FEATURES_READING_LIST_SWITCHES_H_
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc index 22d0bb3..c459ce6f 100644 --- a/components/safe_browsing/core/common/features.cc +++ b/components/safe_browsing/core/common/features.cc
@@ -147,10 +147,6 @@ &kHashRealTimeOverOhttp, "SafeBrowsingHashRealTimeOverOhttpRelayUrl", /*default_value=*/""}; -BASE_FEATURE(kImprovedDownloadBubbleWarnings, - "ImprovedDownloadBubbleWarnings", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kImprovedDownloadPageWarnings, "ImprovedDownloadPageWarnings", base::FEATURE_DISABLED_BY_DEFAULT); @@ -344,7 +340,6 @@ {&kExtensionTelemetryTabsExecuteScriptSignal, true}, {&kHashPrefixRealTimeLookups, true}, {&kHashRealTimeOverOhttp, true}, - {&kImprovedDownloadBubbleWarnings, true}, {&kImprovedDownloadPageWarnings, true}, {&kLogAccountEnhancedProtectionStateInProtegoPings, true}, {&kMmapSafeBrowsingDatabase, true},
diff --git a/components/safe_browsing/core/common/features.h b/components/safe_browsing/core/common/features.h index af27244..b149a6be 100644 --- a/components/safe_browsing/core/common/features.h +++ b/components/safe_browsing/core/common/features.h
@@ -140,9 +140,7 @@ // kHashRealTimeOverOhttp feature. extern const base::FeatureParam<std::string> kHashRealTimeOverOhttpRelayUrl; -// UX improvements to download warnings in the download bubble and -// chrome://downloads page, respectively. -BASE_DECLARE_FEATURE(kImprovedDownloadBubbleWarnings); +// UX improvements to download warnings on chrome://downloads page. BASE_DECLARE_FEATURE(kImprovedDownloadPageWarnings); // Enable logging of the account enhanced protection setting in Protego pings.
diff --git a/components/search_engines/site_search_policy_handler.cc b/components/search_engines/site_search_policy_handler.cc index 1902c832..7b8696e 100644 --- a/components/search_engines/site_search_policy_handler.cc +++ b/components/search_engines/site_search_policy_handler.cc
@@ -65,7 +65,8 @@ dict.Set(DefaultSearchManager::kCreatedByPolicy, static_cast<int>(TemplateURLData::CreatedByPolicy::kSiteSearch)); dict.Set(DefaultSearchManager::kEnforcedByPolicy, false); - dict.Set(DefaultSearchManager::kIsActive, true); + dict.Set(DefaultSearchManager::kIsActive, + static_cast<int>(TemplateURLData::ActiveStatus::kTrue)); // TODO(b/307543761): Create a new field `featured_by_policy` and setting // according to the corresponding dictionary field.
diff --git a/components/search_engines/site_search_policy_handler_unittest.cc b/components/search_engines/site_search_policy_handler_unittest.cc index 593a2b64..bb2137d 100644 --- a/components/search_engines/site_search_policy_handler_unittest.cc +++ b/components/search_engines/site_search_policy_handler_unittest.cc
@@ -306,7 +306,8 @@ DefaultSearchManager::kCreatedByPolicy, static_cast<int>(TemplateURLData::CreatedByPolicy::kSiteSearch)), HasBooleanField(DefaultSearchManager::kEnforcedByPolicy, false), - HasBooleanField(DefaultSearchManager::kIsActive, true), + HasIntegerField(DefaultSearchManager::kIsActive, + static_cast<int>(TemplateURLData::ActiveStatus::kTrue)), HasStringField(DefaultSearchManager::kFaviconURL, std::string(test_case.favicon)), HasBooleanField(DefaultSearchManager::kSafeForAutoReplace, false),
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc index db5de36c..535cc754 100644 --- a/components/search_engines/template_url_service.cc +++ b/components/search_engines/template_url_service.cc
@@ -501,6 +501,22 @@ IsPrepopulatedOrDefaultProviderByPolicy(t_url); } +bool TemplateURLService::ShowInActivesList(const TemplateURL* t_url) const { + return t_url->is_active() == TemplateURLData::ActiveStatus::kTrue || + (t_url->created_by_policy() == + TemplateURLData::CreatedByPolicy::kSiteSearch && + t_url->keyword()[0] != u'@'); +} + +bool TemplateURLService::HiddenFromLists(const TemplateURL* t_url) const { + // Hide synthetic entries created by SiteSearchSettings policy, since they + // are only used for discoverability and the corresponding entry that doesn't + // start with "@" is already shown in the actives list. + return t_url->created_by_policy() == + TemplateURLData::CreatedByPolicy::kSiteSearch && + t_url->keyword()[0] == u'@'; +} + void TemplateURLService::AddMatchingKeywords(const std::u16string& prefix, bool supports_replacement_only, TemplateURLVector* matches) {
diff --git a/components/search_engines/template_url_service.h b/components/search_engines/template_url_service.h index d55a55b..fe95626 100644 --- a/components/search_engines/template_url_service.h +++ b/components/search_engines/template_url_service.h
@@ -156,6 +156,14 @@ // very long). bool ShowInDefaultList(const TemplateURL* template_url) const; + // Returns whether |template_url| should be shown in the list of active + // engines, including active search engines and search engines created by + // the SiteSearchSettings policy. + bool ShowInActivesList(const TemplateURL* template_url) const; + + // Returns whether |template_url| should be hidden from all lists of engines. + bool HiddenFromLists(const TemplateURL* template_url) const; + // Adds to |matches| all TemplateURLs whose keywords begin with |prefix|, // sorted shortest-keyword-first. If |supports_replacement_only| is true, only // TemplateURLs that support replacement are returned. This method must be
diff --git a/components/segmentation_platform/embedder/default_model/search_user_model.cc b/components/segmentation_platform/embedder/default_model/search_user_model.cc index 2b40db6..ef5c7028 100644 --- a/components/segmentation_platform/embedder/default_model/search_user_model.cc +++ b/components/segmentation_platform/embedder/default_model/search_user_model.cc
@@ -16,6 +16,7 @@ #include "components/segmentation_platform/public/features.h" #include "components/segmentation_platform/public/model_provider.h" #include "components/segmentation_platform/public/proto/model_metadata.pb.h" +#include "services/metrics/public/cpp/ukm_builders.h" namespace segmentation_platform { @@ -43,6 +44,18 @@ constexpr char kUkmInputEnabled[] = "ukm-input-enabled"; +#if BUILDFLAG(IS_IOS) +constexpr UkmEventHash kPageLoadHash = UkmEventHash::FromUnsafeValue( + ukm::builders::MainFrameNavigation::kEntryNameHash); +constexpr UkmMetricHash kNavMetricHash = UkmMetricHash::FromUnsafeValue( + ukm::builders::MainFrameNavigation::kDidCommitNameHash); +#else +constexpr UkmEventHash kPageLoadHash = + UkmEventHash::FromUnsafeValue(ukm::builders::PageLoad::kEntryNameHash); +constexpr UkmMetricHash kNavMetricHash = UkmMetricHash::FromUnsafeValue( + ukm::builders::PageLoad::kPaintTiming_NavigationToFirstPaintNameHash); +#endif + std::unique_ptr<DefaultModelProvider> GetSearchUserDefaultModel() { if (!base::GetFieldTrialParamByFeatureAsBool( features::kSegmentationPlatformSearchUser, kDefaultModelEnabledParam, @@ -88,12 +101,10 @@ features::kSegmentationPlatformSearchUser, kUkmInputEnabled, false)) { std::string query = "SELECT COUNT(id) FROM metrics WHERE metric_hash = '64BD7CCE5A95BF00'"; - const std::array<UkmMetricHash, 1> kNavigationMetric = { - UkmMetricHash::FromUnsafeValue(7259095400115977984ull)}; + const std::array<UkmMetricHash, 1> kNavigationMetric = {kNavMetricHash}; const std::array<MetadataWriter::SqlFeature::EventAndMetrics, 1> kPageLoadEvent{MetadataWriter::SqlFeature::EventAndMetrics{ - .event_hash = - UkmEventHash::FromUnsafeValue(12426032810838168341ull), + .event_hash = kPageLoadHash, .metrics = kNavigationMetric.data(), .metrics_size = kNavigationMetric.size()}};
diff --git a/components/segmentation_platform/internal/dummy_ukm_data_manager.cc b/components/segmentation_platform/internal/dummy_ukm_data_manager.cc index 9426c63..9afa256 100644 --- a/components/segmentation_platform/internal/dummy_ukm_data_manager.cc +++ b/components/segmentation_platform/internal/dummy_ukm_data_manager.cc
@@ -12,8 +12,9 @@ DummyUkmDataManager::~DummyUkmDataManager() = default; void DummyUkmDataManager::Initialize(const base::FilePath& database_path, - bool in_memory, - UkmObserver* ukm_observer) {} + bool in_memory) {} + +void DummyUkmDataManager::StartObservation(UkmObserver* ukm_observer) {} bool DummyUkmDataManager::IsUkmEngineEnabled() { return false;
diff --git a/components/segmentation_platform/internal/dummy_ukm_data_manager.h b/components/segmentation_platform/internal/dummy_ukm_data_manager.h index 99013e3..c19bb92 100644 --- a/components/segmentation_platform/internal/dummy_ukm_data_manager.h +++ b/components/segmentation_platform/internal/dummy_ukm_data_manager.h
@@ -20,9 +20,8 @@ DummyUkmDataManager& operator=(const DummyUkmDataManager&) = delete; // UkmDataManager implementation: - void Initialize(const base::FilePath& database_path, - bool in_memory, - UkmObserver* ukm_observer) override; + void Initialize(const base::FilePath& database_path, bool in_memory) override; + void StartObservation(UkmObserver* ukm_observer) override; bool IsUkmEngineEnabled() override; void StartObservingUkm(const UkmConfig& config) override; void PauseOrResumeObservation(bool pause) override;
diff --git a/components/segmentation_platform/internal/mock_ukm_data_manager.h b/components/segmentation_platform/internal/mock_ukm_data_manager.h index 9907a0e..0be105c 100644 --- a/components/segmentation_platform/internal/mock_ukm_data_manager.h +++ b/components/segmentation_platform/internal/mock_ukm_data_manager.h
@@ -19,9 +19,11 @@ MOCK_METHOD(void, Initialize, - (const base::FilePath& database_path, bool, UkmObserver*), + (const base::FilePath& database_path, bool), (override)); + MOCK_METHOD(void, StartObservation, (UkmObserver*), (override)); + MOCK_METHOD(bool, IsUkmEngineEnabled, (), (override)); MOCK_METHOD(void, StartObservingUkm, (const UkmConfig& config), (override));
diff --git a/components/segmentation_platform/internal/selection/segment_result_provider.cc b/components/segmentation_platform/internal/selection/segment_result_provider.cc index bc59ee5..4819f05 100644 --- a/components/segmentation_platform/internal/selection/segment_result_provider.cc +++ b/components/segmentation_platform/internal/selection/segment_result_provider.cc
@@ -238,8 +238,8 @@ return; } - if (metadata_utils::HasExpiredOrUnavailableResult(*db_segment_info, - clock_->Now())) { + if (force_refresh_results_ || metadata_utils::HasExpiredOrUnavailableResult( + *db_segment_info, clock_->Now())) { VLOG(1) << __func__ << ": segment=" << SegmentId_Name(request_state->options->segment_id) << " has expired or unavailable result.";
diff --git a/components/segmentation_platform/internal/ukm_data_manager.h b/components/segmentation_platform/internal/ukm_data_manager.h index 6551b01..75e781a 100644 --- a/components/segmentation_platform/internal/ukm_data_manager.h +++ b/components/segmentation_platform/internal/ukm_data_manager.h
@@ -35,8 +35,9 @@ // Initializes UKM database and the observer of all UKM events. virtual void Initialize(const base::FilePath& database_path, - bool in_memory, - UkmObserver* ukm_observer) = 0; + bool in_memory) = 0; + + virtual void StartObservation(UkmObserver* ukm_observer) = 0; // Returns true when UKM engine is usable. If false, then UKM based engine is // disabled and this class is a no-op. UkmObserver, UrlSignalHandler and
diff --git a/components/segmentation_platform/internal/ukm_data_manager_impl.cc b/components/segmentation_platform/internal/ukm_data_manager_impl.cc index 92dc534..57438d2 100644 --- a/components/segmentation_platform/internal/ukm_data_manager_impl.cc +++ b/components/segmentation_platform/internal/ukm_data_manager_impl.cc
@@ -43,26 +43,26 @@ void UkmDataManagerImpl::InitializeForTesting( std::unique_ptr<UkmDatabase> ukm_database, UkmObserver* ukm_observer) { - InitiailizeImpl(std::move(ukm_database), ukm_observer); + InitiailizeImpl(std::move(ukm_database)); + StartObservation(ukm_observer); } void UkmDataManagerImpl::Initialize(const base::FilePath& database_path, - bool in_memory, - UkmObserver* ukm_observer) { - InitiailizeImpl(std::make_unique<UkmDatabaseImpl>(database_path, in_memory), - ukm_observer); + bool in_memory) { + InitiailizeImpl(std::make_unique<UkmDatabaseImpl>(database_path, in_memory)); +} + +void UkmDataManagerImpl::StartObservation(UkmObserver* ukm_observer) { + ukm_observer_ = ukm_observer; + ukm_observer_->set_ukm_data_manager(this); } void UkmDataManagerImpl::InitiailizeImpl( - std::unique_ptr<UkmDatabase> ukm_database, - UkmObserver* ukm_observer) { + std::unique_ptr<UkmDatabase> ukm_database) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_check_); DCHECK(!ukm_database_); DCHECK(!ukm_observer_); - ukm_observer_ = ukm_observer; - ukm_observer_->set_ukm_data_manager(this); - ukm_database_ = std::move(ukm_database); // TODO(ssid): Move this call to constructor to make it clear any transaction // is posted after initialization. @@ -106,7 +106,10 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_check_); // TODO(b/290821132): Remove this check. if (!ukm_observer_) { + // On iOS the eg tests do not set this flag. +#if !BUILDFLAG(IS_IOS) CHECK_IS_TEST(); +#endif return; } ukm_observer_->PauseOrResumeObservation(pause);
diff --git a/components/segmentation_platform/internal/ukm_data_manager_impl.h b/components/segmentation_platform/internal/ukm_data_manager_impl.h index b85fdc3..d363d18 100644 --- a/components/segmentation_platform/internal/ukm_data_manager_impl.h +++ b/components/segmentation_platform/internal/ukm_data_manager_impl.h
@@ -31,9 +31,8 @@ UkmObserver* ukm_observer); // UkmDataManager implementation: - void Initialize(const base::FilePath& database_path, - bool in_memory, - UkmObserver* ukm_observer) override; + void Initialize(const base::FilePath& database_path, bool in_memory) override; + void StartObservation(UkmObserver* ukm_observer) override; bool IsUkmEngineEnabled() override; void StartObservingUkm(const UkmConfig& config) override; void PauseOrResumeObservation(bool pause) override; @@ -48,8 +47,7 @@ private: // Helper method for initializing this object. - void InitiailizeImpl(std::unique_ptr<UkmDatabase> ukm_database, - UkmObserver* ukm_observer); + void InitiailizeImpl(std::unique_ptr<UkmDatabase> ukm_database); void RunCleanupTask();
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc index 79e0efc..20e6c1d 100644 --- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc +++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
@@ -19,6 +19,7 @@ #include "components/signin/public/base/signin_client.h" #include "components/signin/public/base/signin_metrics.h" #include "components/signin/public/base/signin_pref_names.h" +#include "components/signin/public/base/signin_switches.h" #include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/webdata/token_web_data.h" #include "components/webdata/common/web_data_service_base.h" @@ -200,7 +201,7 @@ network::NetworkConnectionTracker* network_connection_tracker, scoped_refptr<TokenWebData> token_web_data, signin::AccountConsistencyMethod account_consistency, - bool revoke_all_tokens_on_load, + RevokeAllTokensOnLoad revoke_all_tokens_on_load, #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) std::unique_ptr<TokenBindingHelper> token_binding_helper, #endif // BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) @@ -375,6 +376,7 @@ } loading_primary_account_id_ = primary_account_id; + loading_is_syncing_ = is_syncing; web_data_service_request_ = token_web_data_->GetAllTokens(this); } @@ -432,6 +434,7 @@ #endif loading_primary_account_id_ = CoreAccountId(); + loading_is_syncing_ = false; FinishLoadingCredentials(); } @@ -467,7 +470,26 @@ load_account ? LoadTokenFromDBStatus::TOKEN_LOADED : LoadTokenFromDBStatus::TOKEN_REVOKED_SECONDARY_ACCOUNT; - if (load_account && revoke_all_tokens_on_load_) { + bool revoke_token = false; + switch (revoke_all_tokens_on_load_) { + case RevokeAllTokensOnLoad::kNo: + break; + case RevokeAllTokensOnLoad::kDeleteSiteDataOnExit: + if (base::FeatureList::IsEnabled(switches::kUnoDesktop)) { + // With Uno, tokens are not revoked when clearing cookies if the user + // is signed in non-syncing. + revoke_token = + loading_primary_account_id_.empty() || loading_is_syncing_; + } else { + revoke_token = true; + } + break; + case RevokeAllTokensOnLoad::kExplicitRevoke: + revoke_token = true; + break; + } + + if (load_account && revoke_token) { if (account_id == loading_primary_account_id_) { RevokeCredentialsOnServer(refresh_token); refresh_token = GaiaConstants::kInvalidRefreshToken; @@ -626,8 +648,9 @@ VLOG(1) << "MutablePO2TS::RevokeAllCredentials before tokens are loaded."; // If |RevokeAllCredentials| is called while credentials are being loaded, // then the tokens should be revoked on load. - revoke_all_tokens_on_load_ = true; + revoke_all_tokens_on_load_ = RevokeAllTokensOnLoad::kExplicitRevoke; loading_primary_account_id_ = CoreAccountId(); + loading_is_syncing_ = false; } // Make a temporary copy of the account ids.
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h index a9862da2..97eb97ff 100644 --- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h +++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h
@@ -30,6 +30,12 @@ class TokenBindingHelper; #endif // BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) +enum class RevokeAllTokensOnLoad { + kNo = 0, + kDeleteSiteDataOnExit = 1, + kExplicitRevoke = 2 +}; + class MutableProfileOAuth2TokenServiceDelegate : public ProfileOAuth2TokenServiceDelegate, public WebDataServiceConsumer, @@ -43,7 +49,7 @@ network::NetworkConnectionTracker* network_connection_tracker, scoped_refptr<TokenWebData> token_web_data, signin::AccountConsistencyMethod account_consistency, - bool revoke_all_tokens_on_load, + RevokeAllTokensOnLoad revoke_all_tokens_on_load, #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) std::unique_ptr<TokenBindingHelper> token_binding_helper, #endif // BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) @@ -147,6 +153,9 @@ FRIEND_TEST_ALL_PREFIXES(MutableProfileOAuth2TokenServiceDelegateTest, RevokeBoundToken); #endif // BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) + FRIEND_TEST_ALL_PREFIXES( + MutableProfileOAuth2TokenServiceDelegateWithUnoDesktopTest, + KeepPrimaryAccountTokenOnStartupWithClearOnExit); // WebDataServiceConsumer implementation: void OnWebDataServiceRequestDone( @@ -226,6 +235,10 @@ // credentials. This member is empty otherwise. CoreAccountId loading_primary_account_id_; + // Whether sync is enabled for the primary account of this service's profile + // during the loading of credentials. This member is false otherwise. + bool loading_is_syncing_ = false; + std::vector<std::unique_ptr<RevokeServerRefreshToken>> server_revokes_; // Used to verify that certain methods are called only on the thread on which @@ -241,7 +254,7 @@ // Revokes all the tokens after loading them. Secondary accounts will be // completely removed, and the primary account will be kept in authentication // error state. - bool revoke_all_tokens_on_load_; + RevokeAllTokensOnLoad revoke_all_tokens_on_load_ = RevokeAllTokensOnLoad::kNo; #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) // This is null if token binding is disabled.
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc index 654df64c..a994f1a 100644 --- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc +++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
@@ -16,6 +16,7 @@ #include "base/run_loop.h" #include "base/task/single_thread_task_runner.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/time/time.h" #include "components/os_crypt/sync/os_crypt_mocker.h" @@ -26,6 +27,7 @@ #include "components/signin/public/base/account_consistency_method.h" #include "components/signin/public/base/device_id_helper.h" #include "components/signin/public/base/signin_pref_names.h" +#include "components/signin/public/base/signin_switches.h" #include "components/signin/public/base/test_signin_client.h" #include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/webdata/token_web_data.h" @@ -68,7 +70,7 @@ tokens_loaded_count_(0), end_batch_changes_(0), auth_error_changed_count_(0), - revoke_all_tokens_on_load_(false) {} + revoke_all_tokens_on_load_(RevokeAllTokensOnLoad::kNo) {} void SetUp() override { OSCryptMocker::SetUp(); @@ -252,7 +254,7 @@ int tokens_loaded_count_; int end_batch_changes_; int auth_error_changed_count_; - bool revoke_all_tokens_on_load_; + RevokeAllTokensOnLoad revoke_all_tokens_on_load_; std::string source_for_refresh_token_available_; std::string source_for_refresh_token_revoked_; }; @@ -376,7 +378,8 @@ EXPECT_EQ(0, token_available_count_); EXPECT_EQ(2, token_revoked_count_); EXPECT_EQ(1, end_batch_changes_); - EXPECT_TRUE(oauth2_service_delegate_->revoke_all_tokens_on_load_); + EXPECT_NE(RevokeAllTokensOnLoad::kNo, + oauth2_service_delegate_->revoke_all_tokens_on_load_); EXPECT_TRUE(token_service_observer.revoke_all_credentials_called_); EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(account1)); EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(account2)); @@ -1100,7 +1103,7 @@ // updates the database, and is applied only once. TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, ClearTokensOnStartup) { client_->SetNetworkCallsDelayed(true); - revoke_all_tokens_on_load_ = true; + revoke_all_tokens_on_load_ = RevokeAllTokensOnLoad::kDeleteSiteDataOnExit; InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled); CoreAccountId primary_account = CoreAccountId::FromGaiaId("primaryaccount"); CoreAccountId secondary_account = @@ -1347,3 +1350,69 @@ EXPECT_EQ(0, access_token_failure_count_); } #endif // BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) + +class MutableProfileOAuth2TokenServiceDelegateWithUnoDesktopTest + : public MutableProfileOAuth2TokenServiceDelegateTest { + private: + base::test::ScopedFeatureList scoped_feature_list_{switches::kUnoDesktop}; +}; + +// Checks that, for a signed in non-syncing account in UNO with clear on exit, +// set_revoke_all_tokens_on_first_load() keeps the tokens for the primary and +// secondary accounts, updates the database, and is applied only once. +TEST_F(MutableProfileOAuth2TokenServiceDelegateWithUnoDesktopTest, + KeepPrimaryAccountTokenOnStartupWithClearOnExit) { + client_->SetNetworkCallsDelayed(true); + revoke_all_tokens_on_load_ = RevokeAllTokensOnLoad::kDeleteSiteDataOnExit; + InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice); + CoreAccountId primary_account = CoreAccountId::FromGaiaId("primary_account"); + char refresh_token_primary[] = "refresh_token_primary"; + CoreAccountId secondary_account = + CoreAccountId::FromGaiaId("secondary_account"); + char refresh_token_secondary[] = "refresh_token_secondary"; + + oauth2_service_delegate_->RevokeAllCredentials(); + ResetObserverCounts(); + AddAuthTokenManually("AccountId-" + primary_account.ToString(), + refresh_token_primary); + AddAuthTokenManually("AccountId-" + secondary_account.ToString(), + refresh_token_secondary); + oauth2_service_delegate_->LoadCredentials(primary_account, + /*is_syncing=*/false); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(1, tokens_loaded_count_); + EXPECT_EQ(2, token_available_count_); + EXPECT_EQ(0, token_revoked_count_); + EXPECT_EQ(1, end_batch_changes_); + EXPECT_TRUE( + oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account)); + EXPECT_TRUE( + oauth2_service_delegate_->RefreshTokenIsAvailable(secondary_account)); + EXPECT_STREQ( + refresh_token_primary, + oauth2_service_delegate_->GetRefreshToken(primary_account).c_str()); + EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), + oauth2_service_delegate_->GetAuthError(primary_account)); + + // No token is revoked on the server. + EXPECT_EQ(0u, oauth2_service_delegate_->server_revokes_.size()); + client_->SetNetworkCallsDelayed(false); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty()); + + // Check that the changes have been persisted in the database: tokens are not + // revoked again on the server. + client_->SetNetworkCallsDelayed(true); + oauth2_service_delegate_->LoadCredentials(primary_account, + /*is_syncing=*/false); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE( + oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account)); + EXPECT_TRUE( + oauth2_service_delegate_->RefreshTokenIsAvailable(secondary_account)); + EXPECT_STREQ( + refresh_token_primary, + oauth2_service_delegate_->GetRefreshToken(primary_account).c_str()); + EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty()); +}
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc b/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc index e2aecf8..5482ffc 100644 --- a/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc +++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc
@@ -94,9 +94,11 @@ network::NetworkConnectionTracker* network_connection_tracker) { // When signin cookies are cleared on exit and Dice is enabled, all tokens // should also be cleared. - bool revoke_all_tokens_on_load = + RevokeAllTokensOnLoad revoke_all_tokens_on_load = (account_consistency == signin::AccountConsistencyMethod::kDice) && - delete_signin_cookies_on_exit; + delete_signin_cookies_on_exit + ? RevokeAllTokensOnLoad::kDeleteSiteDataOnExit + : RevokeAllTokensOnLoad::kNo; #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) std::unique_ptr<TokenBindingHelper> token_binding_helper;
diff --git a/components/supervised_user/core/browser/supervised_user_pref_store.cc b/components/supervised_user/core/browser/supervised_user_pref_store.cc index 871aa49..ca9d20da 100644 --- a/components/supervised_user/core/browser/supervised_user_pref_store.cc +++ b/components/supervised_user/core/browser/supervised_user_pref_store.cc
@@ -143,14 +143,8 @@ prefs_->SetInteger(policy::policy_prefs::kForceYouTubeRestrict, safe_search_api::YOUTUBE_RESTRICT_MODERATE); #endif + prefs_->SetBoolean(policy::policy_prefs::kHideWebStoreIcon, false); - -// TODO(b/290004926): Modifying `prefs::kSigninAllowed` causes check failures on -// iOS. -#if !BUILDFLAG(IS_IOS) - prefs_->SetBoolean(prefs::kSigninAllowed, false); -#endif // !BUILDFLAG(IS_IOS) - prefs_->SetBoolean(feed::prefs::kEnableSnippets, supervised_user::IsKidFriendlyContentFeedAvailable());
diff --git a/components/sync/base/features.cc b/components/sync/base/features.cc index 72f0537..1fe6ef1 100644 --- a/components/sync/base/features.cc +++ b/components/sync/base/features.cc
@@ -147,16 +147,14 @@ "EnableBookmarkFoldersForAccountStorage", base::FEATURE_DISABLED_BY_DEFAULT); -#if !BUILDFLAG(IS_IOS) BASE_FEATURE(kReadingListEnableSyncTransportModeUponSignIn, "ReadingListEnableSyncTransportModeUponSignIn", - base::FEATURE_DISABLED_BY_DEFAULT); - -bool IsReadingListAccountStorageEnabled() { - return base::FeatureList::IsEnabled( - syncer::kReadingListEnableSyncTransportModeUponSignIn); -} -#endif // !BUILDFLAG(IS_IOS) +#if BUILDFLAG(IS_IOS) + base::FEATURE_ENABLED_BY_DEFAULT +#else + base::FEATURE_DISABLED_BY_DEFAULT +#endif // BUILDFLAG(IS_IOS) +); BASE_FEATURE(kSyncEnableWalletMetadataInTransportMode, "SyncEnableWalletMetadataInTransportMode",
diff --git a/components/sync/base/features.h b/components/sync/base/features.h index 1955600..1c09a0fc 100644 --- a/components/sync/base/features.h +++ b/components/sync/base/features.h
@@ -146,16 +146,7 @@ // Feature flag used for enabling sync (transport mode) for signed-in users that // haven't turned on full sync. -#if !BUILDFLAG(IS_IOS) BASE_DECLARE_FEATURE(kReadingListEnableSyncTransportModeUponSignIn); -// Returns whether reading list storage related UI can be enabled, by testing -// `kReadingListEnableSyncTransportModeUponSignIn`. -bool IsReadingListAccountStorageEnabled(); -#else -constexpr bool IsReadingListAccountStorageEnabled() { - return true; -} -#endif // !BUILDFLAG(IS_IOS) // Flags to allow AUTOFILL_WALLET_METADATA and AUTOFILL_WALLET_OFFER, // respectively, to run in transport mode.
diff --git a/components/sync/service/sync_prefs.cc b/components/sync/service/sync_prefs.cc index 47f31dc..e656971e 100644 --- a/components/sync/service/sync_prefs.cc +++ b/components/sync/service/sync_prefs.cc
@@ -620,7 +620,8 @@ kEnableBookmarkFoldersForAccountStorage); #endif case UserSelectableType::kReadingList: - return syncer::IsReadingListAccountStorageEnabled(); + return base::FeatureList::IsEnabled( + kReadingListEnableSyncTransportModeUponSignIn); case UserSelectableType::kPreferences: return base::FeatureList::IsEnabled(kReplaceSyncPromosWithSignInPromos) && base::FeatureList::IsEnabled(kEnablePreferencesAccountStorage);
diff --git a/components/sync/service/sync_prefs_unittest.cc b/components/sync/service/sync_prefs_unittest.cc index 531a851..3aa5d81 100644 --- a/components/sync/service/sync_prefs_unittest.cc +++ b/components/sync/service/sync_prefs_unittest.cc
@@ -301,9 +301,7 @@ base::test::ScopedFeatureList features; features.InitWithFeatures( /*enabled_features=*/{kEnableBookmarkFoldersForAccountStorage, -#if !BUILDFLAG(IS_IOS) kReadingListEnableSyncTransportModeUponSignIn, -#endif // !BUILDFLAG(IS_IOS) password_manager::features:: kEnablePasswordsAccountStorage, kSyncEnableContactInfoDataTypeInTransportMode, @@ -345,9 +343,7 @@ features.InitWithFeatures( /*enabled_features=*/{kEnableBookmarkFoldersForAccountStorage, kReplaceSyncPromosWithSignInPromos, -#if !BUILDFLAG(IS_IOS) kReadingListEnableSyncTransportModeUponSignIn, -#endif // !BUILDFLAG(IS_IOS) password_manager::features:: kEnablePasswordsAccountStorage, kSyncEnableContactInfoDataTypeInTransportMode, @@ -687,9 +683,7 @@ // in transport mode. feature_list_.InitWithFeatures( /*enabled_features=*/{kEnableBookmarkFoldersForAccountStorage, -#if !BUILDFLAG(IS_IOS) kReadingListEnableSyncTransportModeUponSignIn, -#endif // !BUILDFLAG(IS_IOS) password_manager::features:: kEnablePasswordsAccountStorage, kSyncEnableContactInfoDataTypeInTransportMode,
diff --git a/components/sync/service/sync_user_settings_impl_unittest.cc b/components/sync/service/sync_user_settings_impl_unittest.cc index 0e4a20e4..33f47aed 100644 --- a/components/sync/service/sync_user_settings_impl_unittest.cc +++ b/components/sync/service/sync_user_settings_impl_unittest.cc
@@ -156,9 +156,7 @@ feature_list.InitWithFeatures( /*enabled_features=*/{kEnableBookmarkFoldersForAccountStorage, kReplaceSyncPromosWithSignInPromos, -#if !BUILDFLAG(IS_IOS) kReadingListEnableSyncTransportModeUponSignIn, -#endif // !BUILDFLAG(IS_IOS) password_manager::features:: kEnablePasswordsAccountStorage, kSyncEnableContactInfoDataTypeInTransportMode,
diff --git a/components/system_cpu/BUILD.gn b/components/system_cpu/BUILD.gn new file mode 100644 index 0000000..51874376 --- /dev/null +++ b/components/system_cpu/BUILD.gn
@@ -0,0 +1,87 @@ +# Copyright 2023 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/features.gni") + +source_set("system_cpu") { + sources = [ + "cpu_probe.cc", + "cpu_probe.h", + "pressure_sample.h", + ] + + configs += [ "//build/config/compiler:wexit_time_destructors" ] + + deps = [ "//base" ] + + libs = [] + + if (is_linux || is_chromeos) { + sources += [ + "core_times.cc", + "core_times.h", + "cpu_probe_linux.cc", + "cpu_probe_linux.h", + "procfs_stat_cpu_parser.cc", + "procfs_stat_cpu_parser.h", + ] + } + + if (is_mac) { + sources += [ + "core_times.cc", + "core_times.h", + "cpu_probe_mac.cc", + "cpu_probe_mac.h", + "host_processor_info_scanner.cc", + "host_processor_info_scanner.h", + ] + } + + if (is_win) { + sources += [ + "cpu_probe_win.cc", + "cpu_probe_win.h", + ] + + libs += [ "pdh.lib" ] + } +} + +source_set("unit_tests") { + testonly = true + + sources = [ + "cpu_probe_unittest.cc", + "pressure_test_support.cc", + "pressure_test_support.h", + ] + + deps = [ + ":system_cpu", + "//base", + "//base/test:test_support", + "//testing/gmock", + "//testing/gtest", + ] + + if (is_linux || is_chromeos) { + sources += [ + "core_times_unittest.cc", + "cpu_probe_linux_unittest.cc", + "procfs_stat_cpu_parser_unittest.cc", + ] + } + + if (is_mac) { + sources += [ + "core_times_unittest.cc", + "cpu_probe_mac_unittest.cc", + ] + } + + if (is_win) { + sources += [ "cpu_probe_win_unittest.cc" ] + } +}
diff --git a/components/system_cpu/DIR_METADATA b/components/system_cpu/DIR_METADATA new file mode 100644 index 0000000..6b8ed80 --- /dev/null +++ b/components/system_cpu/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "Internals>Instrumentation" +}
diff --git a/components/system_cpu/OWNERS b/components/system_cpu/OWNERS new file mode 100644 index 0000000..b31e7eae --- /dev/null +++ b/components/system_cpu/OWNERS
@@ -0,0 +1,2 @@ +charlesmeng@google.com +joenotcharles@google.com
diff --git a/components/system_cpu/README.md b/components/system_cpu/README.md new file mode 100644 index 0000000..34e52472 --- /dev/null +++ b/components/system_cpu/README.md
@@ -0,0 +1,4 @@ +This directory contains classes for collecting CPU usage from the operating +system. `system_cpu::CpuProbe` is a base class that provides a common interface +across different platforms and acts as a dependency injection point for tests. +Currently supports Linux/ChromeOS, Mac, and Windows. \ No newline at end of file
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/core_times.cc b/components/system_cpu/core_times.cc similarity index 94% rename from chrome/browser/performance_manager/metrics/cpu_probe/core_times.cc rename to components/system_cpu/core_times.cc index 3efab55..6dc874ba 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/core_times.cc +++ b/components/system_cpu/core_times.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/core_times.h" +#include "components/system_cpu/core_times.h" #include "base/check_op.h" -namespace performance_manager::metrics { +namespace system_cpu { CoreTimes::CoreTimes(const std::initializer_list<uint64_t>& times) { CHECK_EQ(times.size(), 10u); @@ -138,4 +138,4 @@ return active_delta / total_delta; } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/core_times.h b/components/system_cpu/core_times.h similarity index 89% rename from chrome/browser/performance_manager/metrics/cpu_probe/core_times.h rename to components/system_cpu/core_times.h index 6c10497..87cf1f9 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/core_times.h +++ b/components/system_cpu/core_times.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CORE_TIMES_H_ -#define CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CORE_TIMES_H_ +#ifndef COMPONENTS_SYSTEM_CPU_CORE_TIMES_H_ +#define COMPONENTS_SYSTEM_CPU_CORE_TIMES_H_ #include <stdint.h> @@ -11,7 +11,7 @@ #include "base/gtest_prod_util.h" -namespace performance_manager::metrics { +namespace system_cpu { // CPU core utilization statistics. // @@ -84,6 +84,6 @@ uint64_t times_[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; }; -} // namespace performance_manager::metrics +} // namespace system_cpu -#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CORE_TIMES_H_ +#endif // COMPONENTS_SYSTEM_CPU_CORE_TIMES_H_
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/core_times_unittest.cc b/components/system_cpu/core_times_unittest.cc similarity index 95% rename from chrome/browser/performance_manager/metrics/cpu_probe/core_times_unittest.cc rename to components/system_cpu/core_times_unittest.cc index f37f656..aab5dea 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/core_times_unittest.cc +++ b/components/system_cpu/core_times_unittest.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/core_times.h" +#include "components/system_cpu/core_times.h" #include <vector> #include "testing/gtest/include/gtest/gtest.h" -namespace performance_manager::metrics { +namespace system_cpu { using CoreTimesTest = testing::Test; @@ -107,4 +107,4 @@ } } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.cc b/components/system_cpu/cpu_probe.cc similarity index 85% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.cc rename to components/system_cpu/cpu_probe.cc index f55cc48..7d6f1bc 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.cc +++ b/components/system_cpu/cpu_probe.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h" +#include "components/system_cpu/cpu_probe.h" #include <memory> #include <utility> @@ -13,14 +13,14 @@ #include "base/location.h" #include "build/build_config.h" #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux.h" +#include "components/system_cpu/cpu_probe_linux.h" #elif BUILDFLAG(IS_WIN) -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win.h" +#include "components/system_cpu/cpu_probe_win.h" #elif BUILDFLAG(IS_MAC) -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac.h" +#include "components/system_cpu/cpu_probe_mac.h" #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) -namespace performance_manager::metrics { +namespace system_cpu { // static std::unique_ptr<CpuProbe> CpuProbe::Create() { @@ -80,4 +80,4 @@ std::move(callback).Run(std::move(sample)); } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h b/components/system_cpu/cpu_probe.h similarity index 89% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h rename to components/system_cpu/cpu_probe.h index 88e6857..5e740454 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h +++ b/components/system_cpu/cpu_probe.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_H_ -#define CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_H_ +#ifndef COMPONENTS_SYSTEM_CPU_CPU_PROBE_H_ +#define COMPONENTS_SYSTEM_CPU_CPU_PROBE_H_ #include <memory> @@ -12,10 +12,10 @@ #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/thread_annotations.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h" +#include "components/system_cpu/pressure_sample.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace performance_manager::metrics { +namespace system_cpu { // Interface for retrieving the CPU load from the underlying OS on request. // @@ -95,6 +95,6 @@ bool got_probe_baseline_ GUARDED_BY_CONTEXT(sequence_checker_) = false; }; -} // namespace performance_manager::metrics +} // namespace system_cpu -#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_H_ +#endif // COMPONENTS_SYSTEM_CPU_CPU_PROBE_H_
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux.cc b/components/system_cpu/cpu_probe_linux.cc similarity index 90% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux.cc rename to components/system_cpu/cpu_probe_linux.cc index 35f1b3c..292c823 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux.cc +++ b/components/system_cpu/cpu_probe_linux.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux.h" +#include "components/system_cpu/cpu_probe_linux.h" #include <stdint.h> @@ -17,11 +17,11 @@ #include "base/task/sequenced_task_runner.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/core_times.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.h" +#include "components/system_cpu/core_times.h" +#include "components/system_cpu/pressure_sample.h" +#include "components/system_cpu/procfs_stat_cpu_parser.h" -namespace performance_manager::metrics { +namespace system_cpu { // Helper class that performs the actual I/O. It must run on a // SequencedTaskRunner that is properly configured for blocking I/O @@ -141,4 +141,4 @@ return weak_factory_.GetWeakPtr(); } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux.h b/components/system_cpu/cpu_probe_linux.h similarity index 76% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux.h rename to components/system_cpu/cpu_probe_linux.h index 6ffac699..4a40251 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux.h +++ b/components/system_cpu/cpu_probe_linux.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_LINUX_H_ -#define CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_LINUX_H_ +#ifndef COMPONENTS_SYSTEM_CPU_CPU_PROBE_LINUX_H_ +#define COMPONENTS_SYSTEM_CPU_CPU_PROBE_LINUX_H_ #include <memory> @@ -12,9 +12,9 @@ #include "base/memory/weak_ptr.h" #include "base/thread_annotations.h" #include "base/threading/sequence_bound.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h" +#include "components/system_cpu/cpu_probe.h" -namespace performance_manager::metrics { +namespace system_cpu { class CpuProbeLinux : public CpuProbe { public: @@ -48,6 +48,6 @@ GUARDED_BY_CONTEXT(sequence_checker_){this}; }; -} // namespace performance_manager::metrics +} // namespace system_cpu -#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_LINUX_H_ +#endif // COMPONENTS_SYSTEM_CPU_CPU_PROBE_LINUX_H_
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux_unittest.cc b/components/system_cpu/cpu_probe_linux_unittest.cc similarity index 95% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux_unittest.cc rename to components/system_cpu/cpu_probe_linux_unittest.cc index 4d6a737..fa1f1ec 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux_unittest.cc +++ b/components/system_cpu/cpu_probe_linux_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_linux.h" +#include "components/system_cpu/cpu_probe_linux.h" #include <memory> #include <string> @@ -14,14 +14,14 @@ #include "base/test/task_environment.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_test_support.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.h" +#include "components/system_cpu/cpu_probe.h" +#include "components/system_cpu/pressure_sample.h" +#include "components/system_cpu/pressure_test_support.h" +#include "components/system_cpu/procfs_stat_cpu_parser.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace performance_manager::metrics { +namespace system_cpu { class CpuProbeLinuxTest : public testing::Test { public: @@ -389,4 +389,4 @@ EXPECT_EQ(sample3->cpu_utilization, 0.25); } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac.cc b/components/system_cpu/cpu_probe_mac.cc similarity index 89% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac.cc rename to components/system_cpu/cpu_probe_mac.cc index 709eecf..6c7909d0 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac.cc +++ b/components/system_cpu/cpu_probe_mac.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac.h" +#include "components/system_cpu/cpu_probe_mac.h" #include <stdint.h> @@ -16,12 +16,12 @@ #include "base/task/sequenced_task_runner.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/core_times.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/host_processor_info_scanner.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h" +#include "components/system_cpu/core_times.h" +#include "components/system_cpu/host_processor_info_scanner.h" +#include "components/system_cpu/pressure_sample.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace performance_manager::metrics { +namespace system_cpu { // Helper class that performs the actual I/O. It must run on a // SequencedTaskRunner that is properly configured for blocking I/O @@ -132,4 +132,4 @@ return weak_factory_.GetWeakPtr(); } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac.h b/components/system_cpu/cpu_probe_mac.h similarity index 72% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac.h rename to components/system_cpu/cpu_probe_mac.h index 0f46b60..072f255 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac.h +++ b/components/system_cpu/cpu_probe_mac.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_MAC_H_ -#define CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_MAC_H_ +#ifndef COMPONENTS_SYSTEM_CPU_CPU_PROBE_MAC_H_ +#define COMPONENTS_SYSTEM_CPU_CPU_PROBE_MAC_H_ #include <memory> @@ -11,9 +11,9 @@ #include "base/memory/weak_ptr.h" #include "base/thread_annotations.h" #include "base/threading/sequence_bound.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h" +#include "components/system_cpu/cpu_probe.h" -namespace performance_manager::metrics { +namespace system_cpu { class CpuProbeMac : public CpuProbe { public: @@ -44,6 +44,6 @@ GUARDED_BY_CONTEXT(sequence_checker_){this}; }; -} // namespace performance_manager::metrics +} // namespace system_cpu -#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_MAC_H_ +#endif // COMPONENTS_SYSTEM_CPU_CPU_PROBE_MAC_H_
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac_unittest.cc b/components/system_cpu/cpu_probe_mac_unittest.cc similarity index 73% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac_unittest.cc rename to components/system_cpu/cpu_probe_mac_unittest.cc index 3e20597..29ebed0 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac_unittest.cc +++ b/components/system_cpu/cpu_probe_mac_unittest.cc
@@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_mac.h" +#include "components/system_cpu/cpu_probe_mac.h" #include <memory> #include "base/test/task_environment.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_test_support.h" +#include "components/system_cpu/cpu_probe.h" +#include "components/system_cpu/pressure_sample.h" +#include "components/system_cpu/pressure_test_support.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace performance_manager::metrics { +namespace system_cpu { class CpuProbeMacTest : public testing::Test { public: @@ -44,4 +44,4 @@ EXPECT_LE(sample->cpu_utilization, 1.0); } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_unittest.cc b/components/system_cpu/cpu_probe_unittest.cc similarity index 92% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_unittest.cc rename to components/system_cpu/cpu_probe_unittest.cc index b7aa0ca8..8ef86c1 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_unittest.cc +++ b/components/system_cpu/cpu_probe_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h" +#include "components/system_cpu/cpu_probe.h" #include <memory> #include <utility> @@ -18,13 +18,13 @@ #include "base/thread_annotations.h" #include "base/time/time.h" #include "base/timer/timer.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_test_support.h" +#include "components/system_cpu/cpu_probe.h" +#include "components/system_cpu/pressure_sample.h" +#include "components/system_cpu/pressure_test_support.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace performance_manager::metrics { +namespace system_cpu { class CpuProbeTest : public testing::Test { public: @@ -169,4 +169,4 @@ EXPECT_CHECK_DEATH(cpu_probe_->StartSampling()); } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win.cc b/components/system_cpu/cpu_probe_win.cc similarity index 95% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win.cc rename to components/system_cpu/cpu_probe_win.cc index f3c7667..29b8ccd3c 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win.cc +++ b/components/system_cpu/cpu_probe_win.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win.h" +#include "components/system_cpu/cpu_probe_win.h" #include <pdh.h> @@ -17,10 +17,10 @@ #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "base/win/scoped_pdh_query.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h" +#include "components/system_cpu/pressure_sample.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace performance_manager::metrics { +namespace system_cpu { namespace { @@ -166,4 +166,4 @@ return weak_factory_.GetWeakPtr(); } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win.h b/components/system_cpu/cpu_probe_win.h similarity index 72% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win.h rename to components/system_cpu/cpu_probe_win.h index 7b3ad78..a02d9a61 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win.h +++ b/components/system_cpu/cpu_probe_win.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_WIN_H_ -#define CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_WIN_H_ +#ifndef COMPONENTS_SYSTEM_CPU_CPU_PROBE_WIN_H_ +#define COMPONENTS_SYSTEM_CPU_CPU_PROBE_WIN_H_ #include <memory> @@ -11,9 +11,9 @@ #include "base/memory/weak_ptr.h" #include "base/thread_annotations.h" #include "base/threading/sequence_bound.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h" +#include "components/system_cpu/cpu_probe.h" -namespace performance_manager::metrics { +namespace system_cpu { class CpuProbeWin : public CpuProbe { public: @@ -44,6 +44,6 @@ GUARDED_BY_CONTEXT(sequence_checker_){this}; }; -} // namespace performance_manager::metrics +} // namespace system_cpu -#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_CPU_PROBE_WIN_H_ +#endif // COMPONENTS_SYSTEM_CPU_CPU_PROBE_WIN_H_
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win_unittest.cc b/components/system_cpu/cpu_probe_win_unittest.cc similarity index 77% rename from chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win_unittest.cc rename to components/system_cpu/cpu_probe_win_unittest.cc index 771496b4..3c4f020 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win_unittest.cc +++ b/components/system_cpu/cpu_probe_win_unittest.cc
@@ -2,19 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe_win.h" +#include "components/system_cpu/cpu_probe_win.h" #include <memory> #include "base/test/task_environment.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_test_support.h" +#include "components/system_cpu/cpu_probe.h" +#include "components/system_cpu/pressure_test_support.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace performance_manager::metrics { +namespace system_cpu { class CpuProbeWinTest : public testing::Test { public: @@ -43,4 +43,4 @@ EXPECT_LE(sample->cpu_utilization, 1.0); } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/host_processor_info_scanner.cc b/components/system_cpu/host_processor_info_scanner.cc similarity index 89% rename from chrome/browser/performance_manager/metrics/cpu_probe/host_processor_info_scanner.cc rename to components/system_cpu/host_processor_info_scanner.cc index 221fcdc..4d27c0f4 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/host_processor_info_scanner.cc +++ b/components/system_cpu/host_processor_info_scanner.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/host_processor_info_scanner.h" +#include "components/system_cpu/host_processor_info_scanner.h" #include <mach/mach.h> #include <mach/mach_host.h> @@ -12,9 +12,9 @@ #include "base/apple/scoped_mach_vm.h" #include "base/mac/mac_util.h" #include "base/system/sys_info.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/core_times.h" +#include "components/system_cpu/core_times.h" -namespace performance_manager::metrics { +namespace system_cpu { HostProcessorInfoScanner::HostProcessorInfoScanner() { core_times_.reserve(base::SysInfo::NumberOfProcessors()); @@ -70,4 +70,4 @@ return true; } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/host_processor_info_scanner.h b/components/system_cpu/host_processor_info_scanner.h similarity index 69% rename from chrome/browser/performance_manager/metrics/cpu_probe/host_processor_info_scanner.h rename to components/system_cpu/host_processor_info_scanner.h index fac409cb..cebf827 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/host_processor_info_scanner.h +++ b/components/system_cpu/host_processor_info_scanner.h
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_HOST_PROCESSOR_INFO_SCANNER_H_ -#define CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_HOST_PROCESSOR_INFO_SCANNER_H_ +#ifndef COMPONENTS_SYSTEM_CPU_HOST_PROCESSOR_INFO_SCANNER_H_ +#define COMPONENTS_SYSTEM_CPU_HOST_PROCESSOR_INFO_SCANNER_H_ #include <vector> #include "base/sequence_checker.h" #include "base/thread_annotations.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/core_times.h" +#include "components/system_cpu/core_times.h" -namespace performance_manager::metrics { +namespace system_cpu { // Parses CPU time usage stats from host_processor_info. // @@ -40,6 +40,6 @@ std::vector<CoreTimes> core_times_ GUARDED_BY_CONTEXT(sequence_checker_); }; -} // namespace performance_manager::metrics +} // namespace system_cpu -#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_HOST_PROCESSOR_INFO_SCANNER_H_ +#endif // COMPONENTS_SYSTEM_CPU_HOST_PROCESSOR_INFO_SCANNER_H_
diff --git a/components/system_cpu/pressure_sample.h b/components/system_cpu/pressure_sample.h new file mode 100644 index 0000000..7370e3e --- /dev/null +++ b/components/system_cpu/pressure_sample.h
@@ -0,0 +1,20 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SYSTEM_CPU_PRESSURE_SAMPLE_H_ +#define COMPONENTS_SYSTEM_CPU_PRESSURE_SAMPLE_H_ + +namespace system_cpu { + +// Represents availability of compute resources measured over a period of time. +struct PressureSample { + // Average utilization of all CPU cores. + // + // Values use a scale from 0.0 (no utilization) to 1.0 (100% utilization). + double cpu_utilization; +}; + +} // namespace system_cpu + +#endif // COMPONENTS_SYSTEM_CPU_PRESSURE_SAMPLE_H_
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/pressure_test_support.cc b/components/system_cpu/pressure_test_support.cc similarity index 91% rename from chrome/browser/performance_manager/metrics/cpu_probe/pressure_test_support.cc rename to components/system_cpu/pressure_test_support.cc index 79f1f0f..f3ce36ba 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/pressure_test_support.cc +++ b/components/system_cpu/pressure_test_support.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_test_support.h" +#include "components/system_cpu/pressure_test_support.h" #include <utility> @@ -13,7 +13,7 @@ #include "base/sequence_checker.h" #include "base/task/sequenced_task_runner.h" -namespace performance_manager::metrics { +namespace system_cpu { FakeCpuProbe::FakeCpuProbe() = default; @@ -69,4 +69,4 @@ return weak_factory_.GetWeakPtr(); } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/pressure_test_support.h b/components/system_cpu/pressure_test_support.h similarity index 83% rename from chrome/browser/performance_manager/metrics/cpu_probe/pressure_test_support.h rename to components/system_cpu/pressure_test_support.h index f451f0d..7cc5465 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/pressure_test_support.h +++ b/components/system_cpu/pressure_test_support.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_PRESSURE_TEST_SUPPORT_H_ -#define CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_PRESSURE_TEST_SUPPORT_H_ +#ifndef COMPONENTS_SYSTEM_CPU_PRESSURE_TEST_SUPPORT_H_ +#define COMPONENTS_SYSTEM_CPU_PRESSURE_TEST_SUPPORT_H_ #include <stdint.h> @@ -16,11 +16,11 @@ #include "base/synchronization/lock.h" #include "base/test/test_future.h" #include "base/thread_annotations.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/cpu_probe.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/pressure_sample.h" +#include "components/system_cpu/cpu_probe.h" +#include "components/system_cpu/pressure_sample.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace performance_manager::metrics { +namespace system_cpu { // Test double for platform specific CpuProbe that stores the PressureSample in // a TestFuture. @@ -88,6 +88,6 @@ base::WeakPtrFactory<StreamingCpuProbe> weak_factory_{this}; }; -} // namespace performance_manager::metrics +} // namespace system_cpu -#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_PRESSURE_TEST_SUPPORT_H_ +#endif // COMPONENTS_SYSTEM_CPU_PRESSURE_TEST_SUPPORT_H_
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.cc b/components/system_cpu/procfs_stat_cpu_parser.cc similarity index 96% rename from chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.cc rename to components/system_cpu/procfs_stat_cpu_parser.cc index 3bfe8eb..762d20c3 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.cc +++ b/components/system_cpu/procfs_stat_cpu_parser.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.h" +#include "components/system_cpu/procfs_stat_cpu_parser.h" #include <stdint.h> @@ -18,7 +18,7 @@ #include "base/strings/string_split.h" #include "base/system/sys_info.h" -namespace performance_manager::metrics { +namespace system_cpu { constexpr base::FilePath::CharType ProcfsStatCpuParser::kProcfsStatPath[]; @@ -145,4 +145,4 @@ core_times.set_guest_nice(parsed_numbers[9]); } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.h b/components/system_cpu/procfs_stat_cpu_parser.h similarity index 81% rename from chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.h rename to components/system_cpu/procfs_stat_cpu_parser.h index 8e33689..c4aa72f 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.h +++ b/components/system_cpu/procfs_stat_cpu_parser.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_PROCFS_STAT_CPU_PARSER_H_ -#define CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_PROCFS_STAT_CPU_PARSER_H_ +#ifndef COMPONENTS_SYSTEM_CPU_PROCFS_STAT_CPU_PARSER_H_ +#define COMPONENTS_SYSTEM_CPU_PROCFS_STAT_CPU_PARSER_H_ #include <stdint.h> @@ -13,9 +13,9 @@ #include "base/sequence_checker.h" #include "base/strings/string_piece.h" #include "base/thread_annotations.h" -#include "chrome/browser/performance_manager/metrics/cpu_probe/core_times.h" +#include "components/system_cpu/core_times.h" -namespace performance_manager::metrics { +namespace system_cpu { // Parses CPU time usage stats from procfs (/proc/stat). // @@ -63,6 +63,6 @@ std::vector<CoreTimes> core_times_ GUARDED_BY_CONTEXT(sequence_checker_); }; -} // namespace performance_manager::metrics +} // namespace system_cpu -#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_METRICS_CPU_PROBE_PROCFS_STAT_CPU_PARSER_H_ +#endif // COMPONENTS_SYSTEM_CPU_PROCFS_STAT_CPU_PARSER_H_
diff --git a/chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser_unittest.cc b/components/system_cpu/procfs_stat_cpu_parser_unittest.cc similarity index 98% rename from chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser_unittest.cc rename to components/system_cpu/procfs_stat_cpu_parser_unittest.cc index 293ad8c..81e036a 100644 --- a/chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser_unittest.cc +++ b/components/system_cpu/procfs_stat_cpu_parser_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/performance_manager/metrics/cpu_probe/procfs_stat_cpu_parser.h" +#include "components/system_cpu/procfs_stat_cpu_parser.h" #include <memory> #include <string> @@ -15,7 +15,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace performance_manager::metrics { +namespace system_cpu { class ProcfsStatCpuParserTest : public testing::Test { public: @@ -428,4 +428,4 @@ } } -} // namespace performance_manager::metrics +} // namespace system_cpu
diff --git a/components/viz/client/frame_evictor.cc b/components/viz/client/frame_evictor.cc index 406da89..7019f7e 100644 --- a/components/viz/client/frame_evictor.cc +++ b/components/viz/client/frame_evictor.cc
@@ -46,14 +46,7 @@ DCHECK(surface_ids.empty() || !current.is_valid() || base::Contains(surface_ids, current)); - // TODO(crbug.com/1416884): Once we've confirmed the memory impact, remove - // this feature and always add the current SurfaceId. Android was always only - // adding the current one before the feature was added. - bool add_current = base::FeatureList::IsEnabled(features::kEvictSubtree); -#if BUILDFLAG(IS_ANDROID) - add_current = true; -#endif - if (surface_ids.empty() && add_current && current.is_valid()) { + if (surface_ids.empty() && current.is_valid()) { surface_ids.push_back(current); }
diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc index d53693c..3595d390 100644 --- a/components/viz/common/features.cc +++ b/components/viz/common/features.cc
@@ -244,16 +244,6 @@ #endif ); -// On all platforms when attempting to evict a FrameTree, the active -// viz::Surface can be not included. This feature ensures that the we always add -// the active viz::Surface to the eviction list. -// -// Furthermore, by default on Android, when a client is being evicted, it only -// evicts itself. This differs from Destkop platforms which evict the entire -// FrameTree along with the topmost viz::Surface. When this feature is enabled, -// Android will begin also evicting the entire FrameTree. -BASE_FEATURE(kEvictSubtree, "EvictSubtree", base::FEATURE_ENABLED_BY_DEFAULT); - // If enabled, CompositorFrameSinkClient::OnBeginFrame is also treated as the // DidReceiveCompositorFrameAck. Both in providing the Ack for the previous // frame, and in returning resources. While enabled we attempt to not send
diff --git a/components/viz/common/features.h b/components/viz/common/features.h index c7784ee6..4df65170 100644 --- a/components/viz/common/features.h +++ b/components/viz/common/features.h
@@ -71,7 +71,6 @@ VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kOverrideThrottledFrameRateParams); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kRendererAllocatesImages); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kBufferQueueImageSetPurgeable); -VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kEvictSubtree); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kOnBeginFrameAcks); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kOnBeginFrameThrottleVideo); VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kSharedBitmapToSharedImage);
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index ba566ff..627c075 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -505,13 +505,10 @@ if (!HasSavedFrame()) return; - // This list could incorrectly be empty. This could occur when the - // RenderFrameHostImpl has been disconnected from the RenderViewHostImpl, - // preventing the FrameTree from being traversed. This could happen during - // navigation involving BFCache. This should not occur with - // features::kEvictSubtree. - DCHECK(!surface_ids.empty() || - !base::FeatureList::IsEnabled(features::kEvictSubtree)); + // Ensure the list is not empty, otherwise we are silently disconnecting our + // FrameTree. This prevents the eviction of viz::Surfaces, leading to GPU + // memory staying allocated. + DCHECK(!surface_ids.empty()); if (!surface_ids.empty()) { DCHECK(host_frame_sink_manager_); host_frame_sink_manager_->EvictSurfaces(surface_ids);
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc index 4f9a0e1d..89b2604 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -7692,9 +7692,6 @@ std::vector<base::test::FeatureRefAndParams> enabled_features = GetDefaultEnabledBackForwardCacheFeaturesForTesting( /*ignore_outstanding_network_request=*/false); - enabled_features.push_back( - {features::kNavigationUpdatesChildViewsVisibility, {{}}}); - enabled_features.push_back({features::kEvictSubtree, {{}}}); scoped_feature_list_.InitWithFeaturesAndParameters( enabled_features, GetDefaultDisabledBackForwardCacheFeaturesForTesting());
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc index ee575066..3663d62e 100644 --- a/content/browser/renderer_host/render_frame_host_manager.cc +++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -4583,9 +4583,7 @@ // not affect the visibility of the blink::WidgetBase. We should unify these // two visibility states to prevent them from drifting. old_view->Hide(); - if (base::FeatureList::IsEnabled( - features::kNavigationUpdatesChildViewsVisibility) && - old_render_frame_host->child_count()) { + if (old_render_frame_host->child_count()) { old_render_frame_host->SetVisibilityForChildViews(false); } } @@ -4800,9 +4798,7 @@ // finishes, we show it if the delegate is shown. if (!frame_tree_node_->frame_tree().IsHidden()) { new_view->Show(); - if (base::FeatureList::IsEnabled( - features::kNavigationUpdatesChildViewsVisibility) && - render_frame_host_->child_count()) { + if (render_frame_host_->child_count()) { render_frame_host_->SetVisibilityForChildViews(true); } }
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 401a00d..14cddd1 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -925,8 +925,7 @@ ? tree.NodesIncludingInnerTreeNodes() : tree.SubtreeNodes(root); CollectSurfaceIdsForEvictionForFrameTreeNodeRange(node_range, ids); - } else if (is_in_back_forward_cache_ && - base::FeatureList::IsEnabled(features::kEvictSubtree)) { + } else if (is_in_back_forward_cache_) { // `FrameTree::SubtreeAndInnerTreeNodes` starts with the children of `rfh` // so we need to add our current viz::SurfaceId to ensure it is evicted. if (render_widget_host_) {
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc index 0157be58..e8b88e9f 100644 --- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -574,8 +574,6 @@ std::vector<base::test::FeatureRefAndParams> enabled_features = GetDefaultEnabledBackForwardCacheFeaturesForTesting( /*ignore_outstanding_network_request=*/false); - // To evict the main frame's `viz::SurfaceId` while in BFCache. - enabled_features.push_back({features::kEvictSubtree, {{}}}); scoped_feature_list_.InitWithFeaturesAndParameters( enabled_features,
diff --git a/content/browser/resources/traces_internals/trace_report_list.html b/content/browser/resources/traces_internals/trace_report_list.html index f6436899..110cd08 100644 --- a/content/browser/resources/traces_internals/trace_report_list.html +++ b/content/browser/resources/traces_internals/trace_report_list.html
@@ -110,6 +110,12 @@ --iron-icon-width: 40px; --iron-icon-height: 40px; } + + .utility-bar { + display: flex; + justify-content: end; + margin-bottom: 8px; + } </style> <div class="traces-header"> <h1>Traces @@ -126,6 +132,13 @@ </template> <template is="dom-if" if="[[!isLoading]]"> + <div class="utility-bar"> + <cr-button class="floating-button" disabled$="[[hasTraces_(traces)]]" + on-click="onDeleteAllTracesClick_"> + <iron-icon icon="cr:delete" aria-hidden="true"></iron-icon> + Delete All Traces + </cr-button> + </div> <template is="dom-repeat" items="[[traces]]"> <trace-report trace="[[item]]" on-show-toast="showToastHandler_"> </trace-report>
diff --git a/content/browser/resources/traces_internals/trace_report_list.ts b/content/browser/resources/traces_internals/trace_report_list.ts index 86638f6..b077f43 100644 --- a/content/browser/resources/traces_internals/trace_report_list.ts +++ b/content/browser/resources/traces_internals/trace_report_list.ts
@@ -4,6 +4,8 @@ import './trace_report.js'; import 'chrome://resources/cr_elements/cr_toast/cr_toast.js'; +import 'chrome://resources/cr_elements/cr_button/cr_button.js'; +import 'chrome://resources/cr_elements/icons.html.js'; import 'chrome://resources/cr_elements/cr_hidden_style.css.js'; import 'chrome://resources/cr_elements/icons.html.js'; import 'chrome://resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js'; @@ -118,6 +120,23 @@ private hasTraces_(traces: ClientTraceReport[]): boolean { return traces.length > 0; } + + + private async onDeleteAllTracesClick_(): Promise<void> { + const {success} = await this.traceReportProxy_.handler.deleteAllTraces(); + if (!success) { + this.dispatchToast_('Failed to delete to delete all traces.'); + } + this.initializeList(); + } + + private dispatchToast_(message: string): void { + this.dispatchEvent(new CustomEvent('show-toast', { + bubbles: true, + composed: true, + detail: new Notification(NotificationTypeEnum.ERROR, message), + })); + } } declare global {
diff --git a/content/browser/webid/federated_auth_disconnect_request_unittest.cc b/content/browser/webid/federated_auth_disconnect_request_unittest.cc index c996c7c..fda43388f 100644 --- a/content/browser/webid/federated_auth_disconnect_request_unittest.cc +++ b/content/browser/webid/federated_auth_disconnect_request_unittest.cc
@@ -29,7 +29,7 @@ #include "url/gurl.h" #include "url/origin.h" -using ApiPermissionStatus = +using PermissionStatus = content::FederatedIdentityApiPermissionContextDelegate::PermissionStatus; using FetchStatus = content::IdpNetworkRequestManager::FetchStatus; using ParseStatus = content::IdpNetworkRequestManager::ParseStatus; @@ -78,6 +78,10 @@ /*disconnect_fetch_status=*/{ParseStatus::kSuccess, net::HTTP_OK}, kProviderUrl}; +url::Origin OriginFromString(const std::string& url_string) { + return url::Origin::Create(GURL(url_string)); +} + // Helper class for receiving the Disconnect method callback. class DisconnectRequestCallbackHelper { public: @@ -176,24 +180,8 @@ const Config config_; }; -class TestApiPermissionDelegate : public MockApiPermissionDelegate { - public: - ApiPermissionStatus GetApiPermissionStatus( - const url::Origin& origin) override { - return ApiPermissionStatus::GRANTED; - } -}; - class TestPermissionDelegate : public MockPermissionDelegate { public: - bool HasSharingPermission( - const url::Origin& relying_party_requester, - const url::Origin& relying_party_embedder, - const url::Origin& identity_provider, - const absl::optional<std::string>& account_id) override { - return true; - } - absl::optional<bool> GetIdpSigninStatus( const url::Origin& idp_origin) override { return true; @@ -214,7 +202,7 @@ RenderViewHostImplTestHarness::SetUp(); scoped_feature_list_.InitAndEnableFeature(features::kFedCmDisconnect); - api_permission_delegate_ = std::make_unique<TestApiPermissionDelegate>(); + api_permission_delegate_ = std::make_unique<MockApiPermissionDelegate>(); permission_delegate_ = std::make_unique<TestPermissionDelegate>(); static_cast<TestWebContents*>(web_contents()) @@ -236,6 +224,10 @@ if (!rfh) { rfh = static_cast<RenderFrameHost*>(main_test_rfh()); } + if (expected_disconnect_status != DisconnectStatus::kSuccess) { + EXPECT_CALL(*permission_delegate_, RevokeSharingPermission(_, _, _, _)) + .Times(0); + } metrics_ = std::make_unique<FedCmMetrics>( GURL(config.config_url), rfh->GetPageUkmSourceId(), @@ -342,12 +334,18 @@ network_manager_->has_fetched_disconnect_; } + bool DidFetchAllEndpoints() { + return network_manager_->has_fetched_well_known_ && + network_manager_->has_fetched_config_ && + network_manager_->has_fetched_disconnect_; + } + ukm::TestAutoSetUkmRecorder* ukm_recorder() { return ukm_recorder_.get(); } protected: base::test::ScopedFeatureList scoped_feature_list_; raw_ptr<TestIdpNetworkRequestManager> network_manager_; - std::unique_ptr<TestApiPermissionDelegate> api_permission_delegate_; + std::unique_ptr<MockApiPermissionDelegate> api_permission_delegate_; std::unique_ptr<TestPermissionDelegate> permission_delegate_; std::unique_ptr<FedCmMetrics> metrics_; std::unique_ptr<FederatedAuthDisconnectRequest> request_; @@ -357,10 +355,21 @@ TEST_F(FederatedAuthDisconnectRequestTest, Success) { Config config = kValidConfig; + EXPECT_CALL( + *permission_delegate_, + HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl), + OriginFromString(kProviderUrl), _)) + .WillOnce(Return(true)); + EXPECT_CALL(*permission_delegate_, + RevokeSharingPermission(OriginFromString(kRpUrl), + OriginFromString(kRpUrl), + OriginFromString(kProviderUrl), _)); + EXPECT_CALL(*api_permission_delegate_, + GetApiPermissionStatus(OriginFromString(kRpUrl))) + .WillOnce(Return(PermissionStatus::GRANTED)); + RunDisconnectTest(config, DisconnectStatus::kSuccess); - EXPECT_TRUE(network_manager_->has_fetched_well_known_); - EXPECT_TRUE(network_manager_->has_fetched_config_); - EXPECT_TRUE(network_manager_->has_fetched_disconnect_); + EXPECT_TRUE(DidFetchAllEndpoints()); ExpectDisconnectMetricsAndConsoleError(DisconnectStatusForMetrics::kSuccess, FedCmRequesterFrameType::kMainFrame, @@ -392,11 +401,21 @@ HasThirdPartyCookiesAccess(_, GURL(kProviderUrl), url::Origin::Create(GURL(kRpUrl)))) .WillOnce(Return(true)); + EXPECT_CALL(*api_permission_delegate_, + GetApiPermissionStatus(OriginFromString(kRpUrl))) + .WillOnce(Return(PermissionStatus::GRANTED)); + EXPECT_CALL( + *permission_delegate_, + HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl), + OriginFromString(kProviderUrl), _)) + .WillOnce(Return(false)); + EXPECT_CALL(*permission_delegate_, + RevokeSharingPermission(OriginFromString(kRpUrl), + OriginFromString(kRpUrl), + OriginFromString(kProviderUrl), _)); RunDisconnectTest(config, DisconnectStatus::kSuccess); - EXPECT_TRUE(network_manager_->has_fetched_well_known_); - EXPECT_TRUE(network_manager_->has_fetched_config_); - EXPECT_TRUE(network_manager_->has_fetched_disconnect_); + EXPECT_TRUE(DidFetchAllEndpoints()); ExpectDisconnectMetricsAndConsoleError(DisconnectStatusForMetrics::kSuccess, FedCmRequesterFrameType::kMainFrame, @@ -411,7 +430,21 @@ RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame()) ->AppendChild("same_site_iframe")); Config config = kValidConfig; + EXPECT_CALL(*api_permission_delegate_, + GetApiPermissionStatus(OriginFromString(kRpUrl))) + .WillOnce(Return(PermissionStatus::GRANTED)); + EXPECT_CALL(*permission_delegate_, + HasSharingPermission(OriginFromString(kSameSiteIframeUrl), + OriginFromString(kRpUrl), + OriginFromString(kProviderUrl), _)) + .WillOnce(Return(true)); + + EXPECT_CALL(*permission_delegate_, + RevokeSharingPermission(OriginFromString(kSameSiteIframeUrl), + OriginFromString(kRpUrl), + OriginFromString(kProviderUrl), _)); RunDisconnectTest(config, DisconnectStatus::kSuccess, same_site_iframe); + EXPECT_TRUE(DidFetchAllEndpoints()); ExpectDisconnectMetricsAndConsoleError( DisconnectStatusForMetrics::kSuccess, @@ -431,8 +464,22 @@ GURL(kCrossSiteIframeUrl), RenderFrameHostTester::For(web_contents()->GetPrimaryMainFrame()) ->AppendChild("cross_site_iframe")); + EXPECT_CALL(*api_permission_delegate_, + GetApiPermissionStatus(OriginFromString(kRpUrl))) + .WillOnce(Return(PermissionStatus::GRANTED)); + EXPECT_CALL(*permission_delegate_, + HasSharingPermission(OriginFromString(kCrossSiteIframeUrl), + OriginFromString(kRpUrl), + OriginFromString(kProviderUrl), _)) + .WillOnce(Return(true)); Config config = kValidConfig; + + EXPECT_CALL(*permission_delegate_, + RevokeSharingPermission(OriginFromString(kCrossSiteIframeUrl), + OriginFromString(kRpUrl), + OriginFromString(kProviderUrl), _)); RunDisconnectTest(config, DisconnectStatus::kSuccess, cross_site_iframe); + EXPECT_TRUE(DidFetchAllEndpoints()); ExpectDisconnectMetricsAndConsoleError( DisconnectStatusForMetrics::kSuccess, @@ -440,4 +487,79 @@ /*should_record_duration=*/true); } +TEST_F(FederatedAuthDisconnectRequestTest, NoAccountToDisconnect) { + Config config = kValidConfig; + EXPECT_CALL(*api_permission_delegate_, + GetApiPermissionStatus(OriginFromString(kRpUrl))) + .WillOnce(Return(PermissionStatus::GRANTED)); + EXPECT_CALL( + *permission_delegate_, + HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl), + OriginFromString(kProviderUrl), _)) + .WillOnce(Return(false)); + + RunDisconnectTest(config, DisconnectStatus::kError); + EXPECT_FALSE(DidFetchAnyEndpoint()); + + ExpectDisconnectMetricsAndConsoleError( + DisconnectStatusForMetrics::kNoAccountToDisconnect, + FedCmRequesterFrameType::kMainFrame, + /*should_record_duration=*/false); +} + +TEST_F(FederatedAuthDisconnectRequestTest, DisabledInSettings) { + Config config = kValidConfig; + EXPECT_CALL(*api_permission_delegate_, + GetApiPermissionStatus(OriginFromString(kRpUrl))) + .WillOnce(Return(PermissionStatus::BLOCKED_SETTINGS)); + + RunDisconnectTest(config, DisconnectStatus::kError); + EXPECT_FALSE(DidFetchAnyEndpoint()); + + ExpectDisconnectMetricsAndConsoleError( + DisconnectStatusForMetrics::kDisabledInSettings, + FedCmRequesterFrameType::kMainFrame, + /*should_record_duration=*/false); +} + +TEST_F(FederatedAuthDisconnectRequestTest, DisabledInFlags) { + Config config = kValidConfig; + EXPECT_CALL(*api_permission_delegate_, + GetApiPermissionStatus(OriginFromString(kRpUrl))) + .WillOnce(Return(PermissionStatus::BLOCKED_VARIATIONS)); + + RunDisconnectTest(config, DisconnectStatus::kError); + EXPECT_FALSE(DidFetchAnyEndpoint()); + + ExpectDisconnectMetricsAndConsoleError( + DisconnectStatusForMetrics::kDisabledInFlags, + FedCmRequesterFrameType::kMainFrame, + /*should_record_duration=*/false); +} + +// Tests that disconnect() succeeds even if FedCM is under embargo (e.g. +// cooldown). +TEST_F(FederatedAuthDisconnectRequestTest, SuccessDespiteEmbargo) { + Config config = kValidConfig; + EXPECT_CALL(*api_permission_delegate_, + GetApiPermissionStatus(OriginFromString(kRpUrl))) + .WillOnce(Return(PermissionStatus::BLOCKED_EMBARGO)); + EXPECT_CALL( + *permission_delegate_, + HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl), + OriginFromString(kProviderUrl), _)) + .WillOnce(Return(true)); + EXPECT_CALL(*permission_delegate_, + RevokeSharingPermission(OriginFromString(kRpUrl), + OriginFromString(kRpUrl), + OriginFromString(kProviderUrl), _)); + + RunDisconnectTest(config, DisconnectStatus::kSuccess); + EXPECT_TRUE(DidFetchAllEndpoints()); + + ExpectDisconnectMetricsAndConsoleError(DisconnectStatusForMetrics::kSuccess, + FedCmRequesterFrameType::kMainFrame, + /*should_record_duration=*/true); +} + } // namespace content
diff --git a/content/public/android/java/src/org/chromium/content/browser/webid/DigitalCredentialProvider.java b/content/public/android/java/src/org/chromium/content/browser/webid/DigitalCredentialProvider.java index a9b1e6c..548aee4 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webid/DigitalCredentialProvider.java +++ b/content/public/android/java/src/org/chromium/content/browser/webid/DigitalCredentialProvider.java
@@ -15,7 +15,7 @@ @JNINamespace("content") public class DigitalCredentialProvider { private static final String TAG = "DigitalCredentialProvider"; - private final long mDigitalCredentialProvider; + private long mDigitalCredentialProvider; private static IdentityCredentialsDelegate sCredentials = new IdentityCredentialsDelegateImpl(); private DigitalCredentialProvider(long dcProvider) { @@ -35,7 +35,9 @@ } @CalledByNative - private void destroy() {} + private void destroy() { + mDigitalCredentialProvider = 0; + } /** * Triggers a request to the Identity Credentials Manager in GMS. @@ -50,11 +52,16 @@ .get(window.getActivity().get(), origin, request) .then( data -> { - DigitalCredentialProviderJni.get() - .onReceive(mDigitalCredentialProvider, new String(data)); + if (mDigitalCredentialProvider != 0) { + DigitalCredentialProviderJni.get() + .onReceive(mDigitalCredentialProvider, new String(data)); + } }, e -> { - DigitalCredentialProviderJni.get().onError(mDigitalCredentialProvider); + if (mDigitalCredentialProvider != 0) { + DigitalCredentialProviderJni.get() + .onError(mDigitalCredentialProvider); + } }); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java index 60efb79..752a035a 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java
@@ -50,7 +50,8 @@ protected static final String NODE_ERROR = "Generated AccessibilityNodeInfo tree did not match expectations."; protected static final String EXPECTATIONS_NULL = - "Test expectations were null, perhaps the file is missing?"; + "Test expectations were null, perhaps the file is missing? Create an empty file for " + + "both the -external and -assist-data tests."; protected static final String RESULTS_NULL = "Test results were null, did you add the tracker to WebContentsAccessibilityImpl?"; protected static final String MISSING_FILE_ERROR =
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AssistViewStructureTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AssistViewStructureTest.java index a9adb1e50..b22a286d 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AssistViewStructureTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AssistViewStructureTest.java
@@ -35,7 +35,6 @@ /** Tests for the implementation of onProvideVirtualStructure in WebContentsAccessibility. */ @RunWith(BaseJUnit4ClassRunner.class) -// TODO(mschillaci): Migrate all these tests to the WebContentsAccessibilityTreeTest suite. public class AssistViewStructureTest { @Rule public TestRule mProcessor = new Features.InstrumentationProcessor();
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java index 5f4d3ead..18908e0 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java
@@ -10,7 +10,6 @@ import android.annotation.SuppressLint; import android.os.Build.VERSION_CODES; -import android.os.Environment; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.test.filters.SmallTest; @@ -29,8 +28,6 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.DeviceRestriction; -import java.io.File; - /** Tests for WebContentsAccessibilityImpl integration with accessibility services. */ @RunWith(ContentJUnit4ClassRunner.class) @SuppressLint("VisibleForTests") @@ -51,11 +48,10 @@ /** * Perform a single test which will: - * 1. Open the given HTML file - * 2. Generate the full AccessibilityNodeInfo tree - * 3. Read expectations file and compare with results - * 4. Generate an AssistData structure for the page - * 5. Read AssistData expectations file and compare with results + * 1. Open the given HTML file + * 2. Generate the full AccessibilityNodeInfo tree + * 3. Generate the full AssistData tree + * 4. Read expectations file and compare both trees with results * * @param inputFile HTML test input file * @param expectationFile TXT expectations file @@ -65,47 +61,76 @@ // Build page from given file and enable testing framework. mActivityTestRule.setupTestFromFile(expectationFilePath + inputFile); - // Create an extra string to print to logs along with potential error for rebase tool. - String errorStringPrefix = + // Create extra strings to print to logs along with potential error(s) for rebase tool. + String accessibilityNodeInfoErrorPrefix = String.format( "\n\nTesting: %s%s\nExpected output: %s%s", - expectationFilePath, inputFile, expectationFilePath, expectationFile); + expectationFilePath, + inputFile, + expectationFilePath, + expectationFile + DEFAULT_FILE_SUFFIX); + String assistDataErrorPrefix = + String.format( + "\n\nTesting: %s%s\nExpected output: %s%s", + expectationFilePath, + inputFile, + expectationFilePath, + expectationFile + ASSIST_DATA_FILE_SUFFIX); - // Generate full AccessibilityNodeInfo tree and verify results. - assertResults( - expectationFilePath + expectationFile, - generateAccessibilityNodeInfoTree(), - errorStringPrefix); + // Generate full AccessibilityNodeInfo and AssistData trees + String accessibilityNodeInfoTree = generateAccessibilityNodeInfoTree(); + String assistDataTree = generateViewStructureTree(); + Assert.assertNotNull(RESULTS_NULL, accessibilityNodeInfoTree); + Assert.assertNotNull(RESULTS_NULL, assistDataTree); - // TODO(mschillaci): remove this and add to verifyInputFile when upgrade is complete. - String assistDataFileName = - inputFile.substring(0, inputFile.length() - 5) + ASSIST_DATA_FILE_SUFFIX; - String directory = - Environment.getExternalStorageDirectory().getPath() - + "/chromium_tests_root/" - + expectationFilePath; - File expectedFile = new File(directory, "/" + assistDataFileName); - if (expectedFile.exists()) { - errorStringPrefix = - String.format( - "\n\nTesting: %s%s\nExpected output: %s%s", - expectationFilePath, - inputFile, - expectationFilePath, - assistDataFileName); - // Generate full AssistData tree and verify results. - assertResults( - expectationFilePath + "/" + assistDataFileName, - generateViewStructureTree(), - errorStringPrefix); + // Attempt to read expectation files (will throw an error if files do not exist). + String accessibilityNodeInfoTreeExpectedResults = + mActivityTestRule + .readExpectationFile( + expectationFilePath + expectationFile + DEFAULT_FILE_SUFFIX) + .trim(); + String assistDataTreeExpectedResults = + mActivityTestRule + .readExpectationFile( + expectationFilePath + expectationFile + ASSIST_DATA_FILE_SUFFIX) + .trim(); + + // We want to test both trees so that the rebase tree only needs to be run once for newly + // added tests, so we will first check equivalency without using Assert and create an error + // message that can include results for both tree tests. + String outputError = ""; + if (!accessibilityNodeInfoTree.equals(accessibilityNodeInfoTreeExpectedResults)) { + outputError += + NODE_ERROR + + accessibilityNodeInfoErrorPrefix + + "\n\nExpected\n--------\n" + + accessibilityNodeInfoTreeExpectedResults + + "\n\nActual\n------\n" + + accessibilityNodeInfoTree + + "\n<-- End-of-file -->\n\n\n"; } + if (!assistDataTree.equals(assistDataTreeExpectedResults)) { + outputError += + NODE_ERROR + + assistDataErrorPrefix + + "\n\nExpected\n--------\n" + + assistDataTreeExpectedResults + + "\n\nActual\n------\n" + + assistDataTree + + "\n<-- End-of-file -->\n\n\n"; + } + + // Assert expectations and print error if needed. + Assert.assertEquals( + outputError, accessibilityNodeInfoTreeExpectedResults, accessibilityNodeInfoTree); + Assert.assertEquals(outputError, assistDataTreeExpectedResults, assistDataTree); } // Helper methods to pass-through to the performTest method so each individual test does // not need to include its own filepath. private void performAccnameTest(String input) { // Remove the '.html' from the input file, and append the standard suffix. - performAccnameTest(input, input.substring(0, input.length() - 5) + DEFAULT_FILE_SUFFIX); + performAccnameTest(input, input.substring(0, input.length() - 5)); } private void performAccnameTest(String inputFile, String expectationFile) { @@ -114,7 +139,7 @@ private void performAriaTest(String input) { // Remove the '.html' from the input file, and append the standard suffix. - performAriaTest(input, input.substring(0, input.length() - 5) + DEFAULT_FILE_SUFFIX); + performAriaTest(input, input.substring(0, input.length() - 5)); } private void performAriaTest(String inputFile, String expectationFile) { @@ -123,7 +148,7 @@ private void performCssTest(String input) { // Remove the '.html' from the input file, and append the standard suffix. - performCssTest(input, input.substring(0, input.length() - 5) + DEFAULT_FILE_SUFFIX); + performCssTest(input, input.substring(0, input.length() - 5)); } private void performCssTest(String inputFile, String expectationFile) { @@ -132,7 +157,7 @@ private void performHtmlTest(String input) { // Remove the '.html' from the input file, and append the standard suffix. - performHtmlTest(input, input.substring(0, input.length() - 5) + DEFAULT_FILE_SUFFIX); + performHtmlTest(input, input.substring(0, input.length() - 5)); } private void performHtmlTest(String inputFile, String expectationFile) { @@ -140,29 +165,6 @@ } /** - * Helper method to compare test outputs with expected results. Reads content of expectations - * file, asserts non-null, then compares with results. - * - * @param expectationFile File of the expectations for the test (including path) - * @param actualResults Actual results generated by the accessibility code - */ - private void assertResults(String expectationFile, String actualResults, String errorPrefix) { - String expectedResults = mActivityTestRule.readExpectationFile(expectationFile).trim(); - - Assert.assertNotNull(RESULTS_NULL, actualResults); - Assert.assertEquals( - NODE_ERROR - + errorPrefix - + "\n\nExpected\n--------\n" - + expectedResults - + "\n\nActual\n------\n" - + actualResults - + "\n<-- End-of-file -->\n\n\n", - expectedResults, - actualResults); - } - - /** * Generate the full AccessibilityNodeInfo tree as a String of text. * * @return String The AccessibilityNodeInfo tree in text form
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 6e1d0aaa..1e184733 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -588,12 +588,6 @@ #endif ); -// When enabled, RenderFrameHostManager::CommitPending will also update the -// visibility of all child views, not just that of the main frame. -BASE_FEATURE(kNavigationUpdatesChildViewsVisibility, - "NavigationUpdatesChildViewsVisibility", - base::FEATURE_ENABLED_BY_DEFAULT); - // If the network service is enabled, runs it in process. BASE_FEATURE(kNetworkServiceInProcess, "NetworkServiceInProcess2",
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index eeaf030c..d5bb6ce 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -149,7 +149,6 @@ CONTENT_EXPORT extern const base::FeatureParam<MBIMode> kMBIModeParam; CONTENT_EXPORT BASE_DECLARE_FEATURE(kMojoVideoCapture); CONTENT_EXPORT BASE_DECLARE_FEATURE(kNavigationNetworkResponseQueue); -CONTENT_EXPORT BASE_DECLARE_FEATURE(kNavigationUpdatesChildViewsVisibility); CONTENT_EXPORT BASE_DECLARE_FEATURE(kNetworkQualityEstimatorWebHoldback); CONTENT_EXPORT BASE_DECLARE_FEATURE(kNetworkServiceInProcess); CONTENT_EXPORT BASE_DECLARE_FEATURE(kNotificationContentImage);
diff --git a/content/public/common/content_switch_dependent_feature_overrides.cc b/content/public/common/content_switch_dependent_feature_overrides.cc index d305a83c..fcd1f6a 100644 --- a/content/public/common/content_switch_dependent_feature_overrides.cc +++ b/content/public/common/content_switch_dependent_feature_overrides.cc
@@ -99,9 +99,6 @@ std::cref(net::features::kThirdPartyStoragePartitioning), base::FeatureList::OVERRIDE_ENABLE_FEATURE}, {switches::kEnableExperimentalWebPlatformFeatures, - std::cref(blink::features::kStorageAccessAPI), - base::FeatureList::OVERRIDE_ENABLE_FEATURE}, - {switches::kEnableExperimentalWebPlatformFeatures, std::cref(blink::features::kStorageAccessAPIForOriginExtension), base::FeatureList::OVERRIDE_ENABLE_FEATURE}, {switches::kEnableExperimentalWebPlatformFeatures,
diff --git a/dbus/message.cc b/dbus/message.cc index a1dced2..41a8b216 100644 --- a/dbus/message.cc +++ b/dbus/message.cc
@@ -590,47 +590,58 @@ container_is_open_ = false; } -void MessageWriter::AppendArrayOfBytes(const uint8_t* values, size_t length) { +void MessageWriter::AppendArrayOfBytes(base::span<const uint8_t> values) { DCHECK(!container_is_open_); MessageWriter array_writer(message_); OpenArray("y", &array_writer); + // dbus_message_iter_append_fixed_array takes a pointer to a pointer to the + // data. + const uint8_t* ptr = values.data(); const bool success = dbus_message_iter_append_fixed_array( - &(array_writer.raw_message_iter_), DBUS_TYPE_BYTE, &values, - static_cast<int>(length)); + &(array_writer.raw_message_iter_), DBUS_TYPE_BYTE, &ptr, + base::checked_cast<int>(values.size())); CHECK(success) << "Unable to allocate memory"; CloseContainer(&array_writer); } -void MessageWriter::AppendArrayOfInt32s(const int32_t* values, size_t length) { +void MessageWriter::AppendArrayOfInt32s(base::span<const int32_t> values) { DCHECK(!container_is_open_); MessageWriter array_writer(message_); OpenArray("i", &array_writer); + // dbus_message_iter_append_fixed_array takes a pointer to a pointer to the + // data. + const int32_t* ptr = values.data(); const bool success = dbus_message_iter_append_fixed_array( - &(array_writer.raw_message_iter_), DBUS_TYPE_INT32, &values, - static_cast<int>(length)); + &(array_writer.raw_message_iter_), DBUS_TYPE_INT32, &ptr, + base::checked_cast<int>(values.size())); CHECK(success) << "Unable to allocate memory"; CloseContainer(&array_writer); } -void MessageWriter::AppendArrayOfUint32s(const uint32_t* values, - size_t length) { +void MessageWriter::AppendArrayOfUint32s(base::span<const uint32_t> values) { DCHECK(!container_is_open_); MessageWriter array_writer(message_); OpenArray("u", &array_writer); + // dbus_message_iter_append_fixed_array takes a pointer to a pointer to the + // data. + const uint32_t* ptr = values.data(); const bool success = dbus_message_iter_append_fixed_array( - &(array_writer.raw_message_iter_), DBUS_TYPE_UINT32, &values, - static_cast<int>(length)); + &(array_writer.raw_message_iter_), DBUS_TYPE_UINT32, &ptr, + base::checked_cast<int>(values.size())); CHECK(success) << "Unable to allocate memory"; CloseContainer(&array_writer); } -void MessageWriter::AppendArrayOfDoubles(const double* values, size_t length) { +void MessageWriter::AppendArrayOfDoubles(base::span<const double> values) { DCHECK(!container_is_open_); MessageWriter array_writer(message_); OpenArray("d", &array_writer); + // dbus_message_iter_append_fixed_array takes a pointer to a pointer to the + // data. + const double* ptr = values.data(); const bool success = dbus_message_iter_append_fixed_array( - &(array_writer.raw_message_iter_), DBUS_TYPE_DOUBLE, &values, - static_cast<int>(length)); + &(array_writer.raw_message_iter_), DBUS_TYPE_DOUBLE, &ptr, + base::checked_cast<int>(values.size())); CHECK(success) << "Unable to allocate memory"; CloseContainer(&array_writer); } @@ -664,8 +675,7 @@ LOG(ERROR) << "Unable to serialize supplied protocol buffer"; return false; } - AppendArrayOfBytes(reinterpret_cast<const uint8_t*>(serialized_proto.data()), - serialized_proto.size()); + AppendArrayOfBytes(base::as_byte_span(serialized_proto)); return true; }
diff --git a/dbus/message.h b/dbus/message.h index 4c81963..bbec529 100644 --- a/dbus/message.h +++ b/dbus/message.h
@@ -13,6 +13,7 @@ #include <string> #include <vector> +#include "base/containers/span.h" #include "base/files/scoped_file.h" #include "base/memory/raw_ptr.h" #include "dbus/dbus_export.h" @@ -319,16 +320,16 @@ // Appends the array of bytes. Arrays of bytes are often used for // exchanging binary blobs hence it's worth having a specialized // function. - void AppendArrayOfBytes(const uint8_t* values, size_t length); + void AppendArrayOfBytes(base::span<const uint8_t> values); // Appends array of int32_ts. - void AppendArrayOfInt32s(const int32_t* values, size_t length); + void AppendArrayOfInt32s(base::span<const int32_t> values); // Appends array of uint32_ts. - void AppendArrayOfUint32s(const uint32_t* values, size_t length); + void AppendArrayOfUint32s(base::span<const uint32_t> values); // Appends the array of doubles. Used for audio mixer matrix doubles. - void AppendArrayOfDoubles(const double* values, size_t length); + void AppendArrayOfDoubles(base::span<const double> values); // Appends the array of strings. Arrays of strings are often used for // exchanging lists of names hence it's worth having a specialized
diff --git a/dbus/message_unittest.cc b/dbus/message_unittest.cc index 2f2dc33..2a77050 100644 --- a/dbus/message_unittest.cc +++ b/dbus/message_unittest.cc
@@ -226,7 +226,7 @@ bytes.push_back(1); bytes.push_back(2); bytes.push_back(3); - writer.AppendArrayOfBytes(bytes.data(), bytes.size()); + writer.AppendArrayOfBytes(bytes); MessageReader reader(message.get()); const uint8_t* output_bytes = nullptr; @@ -247,7 +247,7 @@ int32s.push_back(1); int32s.push_back(2); int32s.push_back(3); - writer.AppendArrayOfInt32s(int32s.data(), int32s.size()); + writer.AppendArrayOfInt32s(int32s); MessageReader reader(message.get()); const int32_t* output_int32s = nullptr; @@ -268,7 +268,7 @@ uint32s.push_back(1); uint32s.push_back(2); uint32s.push_back(3); - writer.AppendArrayOfUint32s(uint32s.data(), uint32s.size()); + writer.AppendArrayOfUint32s(uint32s); MessageReader reader(message.get()); const uint32_t* output_uint32s = nullptr; @@ -289,7 +289,7 @@ doubles.push_back(0.2); doubles.push_back(0.5); doubles.push_back(1); - writer.AppendArrayOfDoubles(doubles.data(), doubles.size()); + writer.AppendArrayOfDoubles(doubles); MessageReader reader(message.get()); const double* output_doubles = nullptr; @@ -307,7 +307,7 @@ std::unique_ptr<Response> message(Response::CreateEmpty()); MessageWriter writer(message.get()); std::vector<uint8_t> bytes; - writer.AppendArrayOfBytes(bytes.data(), bytes.size()); + writer.AppendArrayOfBytes(bytes); MessageReader reader(message.get()); const uint8_t* output_bytes = nullptr;
diff --git a/dbus/property.cc b/dbus/property.cc index 06354733..c58bed5 100644 --- a/dbus/property.cc +++ b/dbus/property.cc
@@ -548,7 +548,7 @@ MessageWriter* writer) { MessageWriter variant_writer(nullptr); writer->OpenVariant("ay", &variant_writer); - variant_writer.AppendArrayOfBytes(set_value_.data(), set_value_.size()); + variant_writer.AppendArrayOfBytes(set_value_); writer->CloseContainer(&variant_writer); } @@ -640,8 +640,7 @@ for (const auto& pair : set_value_) { dbus::MessageWriter struct_writer(nullptr); array_writer.OpenStruct(&struct_writer); - struct_writer.AppendArrayOfBytes(std::get<0>(pair).data(), - std::get<0>(pair).size()); + struct_writer.AppendArrayOfBytes(std::get<0>(pair)); struct_writer.AppendUint16(std::get<1>(pair)); array_writer.CloseContainer(&struct_writer); } @@ -710,8 +709,7 @@ MessageWriter value_varient_writer(nullptr); entry_writer.OpenVariant("ay", &value_varient_writer); - value_varient_writer.AppendArrayOfBytes(pair.second.data(), - pair.second.size()); + value_varient_writer.AppendArrayOfBytes(pair.second); entry_writer.CloseContainer(&value_varient_writer); dict_writer.CloseContainer(&entry_writer); @@ -782,8 +780,7 @@ MessageWriter value_varient_writer(nullptr); entry_writer.OpenVariant("ay", &value_varient_writer); - value_varient_writer.AppendArrayOfBytes(pair.second.data(), - pair.second.size()); + value_varient_writer.AppendArrayOfBytes(pair.second); entry_writer.CloseContainer(&value_varient_writer); dict_writer.CloseContainer(&entry_writer);
diff --git a/dbus/property_unittest.cc b/dbus/property_unittest.cc index 3461686..164b1553 100644 --- a/dbus/property_unittest.cc +++ b/dbus/property_unittest.cc
@@ -379,7 +379,7 @@ for (uint16_t i = 0; i < 5; ++i) { variant_array_writer.OpenStruct(&struct_entry_writer); ip_bytes[4] = 0x30 + i; - struct_entry_writer.AppendArrayOfBytes(ip_bytes, std::size(ip_bytes)); + struct_entry_writer.AppendArrayOfBytes(ip_bytes); struct_entry_writer.AppendUint16(i); variant_array_writer.CloseContainer(&struct_entry_writer); } @@ -442,7 +442,7 @@ MessageWriter value_varient_writer(nullptr); entry_writer.OpenVariant("ay", &value_varient_writer); - value_varient_writer.AppendArrayOfBytes(values[i].data(), values[i].size()); + value_varient_writer.AppendArrayOfBytes(values[i]); entry_writer.CloseContainer(&value_varient_writer); dict_writer.CloseContainer(&entry_writer); @@ -476,7 +476,7 @@ dict_writer.OpenDictEntry(&entry_writer); entry_writer.AppendString(keys[i]); - entry_writer.AppendArrayOfBytes(values[i].data(), values[i].size()); + entry_writer.AppendArrayOfBytes(values[i]); dict_writer.CloseContainer(&entry_writer); } @@ -530,7 +530,7 @@ MessageWriter value_varient_writer(nullptr); entry_writer.OpenVariant("ay", &value_varient_writer); - value_varient_writer.AppendArrayOfBytes(values[i].data(), values[i].size()); + value_varient_writer.AppendArrayOfBytes(values[i]); entry_writer.CloseContainer(&value_varient_writer); dict_writer.CloseContainer(&entry_writer); @@ -564,7 +564,7 @@ dict_writer.OpenDictEntry(&entry_writer); entry_writer.AppendUint16(keys[i]); - entry_writer.AppendArrayOfBytes(values[i].data(), values[i].size()); + entry_writer.AppendArrayOfBytes(values[i]); dict_writer.CloseContainer(&entry_writer); }
diff --git a/dbus/test_service.cc b/dbus/test_service.cc index 2aef609..5e26344 100644 --- a/dbus/test_service.cc +++ b/dbus/test_service.cc
@@ -394,7 +394,7 @@ writer.OpenVariant("ay", &variant_writer); const uint8_t bytes[] = {0x54, 0x65, 0x73, 0x74}; - variant_writer.AppendArrayOfBytes(bytes, sizeof(bytes)); + variant_writer.AppendArrayOfBytes(bytes); writer.CloseContainer(&variant_writer); std::move(response_sender).Run(std::move(response)); @@ -596,7 +596,7 @@ dict_entry_writer.AppendString("Bytes"); dict_entry_writer.OpenVariant("ay", &variant_writer); const uint8_t bytes[] = {0x54, 0x65, 0x73, 0x74}; - variant_writer.AppendArrayOfBytes(bytes, sizeof(bytes)); + variant_writer.AppendArrayOfBytes(bytes); dict_entry_writer.CloseContainer(&variant_writer); array_writer.CloseContainer(&dict_entry_writer);
diff --git a/device/bluetooth/dbus/bluetooth_advertisement_monitor_service_provider_impl.cc b/device/bluetooth/dbus/bluetooth_advertisement_monitor_service_provider_impl.cc index f46600a..8422414 100644 --- a/device/bluetooth/dbus/bluetooth_advertisement_monitor_service_provider_impl.cc +++ b/device/bluetooth/dbus/bluetooth_advertisement_monitor_service_provider_impl.cc
@@ -237,7 +237,8 @@ struct_writer.AppendByte(start_pos); struct_writer.AppendByte(ad_data_type); - struct_writer.AppendArrayOfBytes(content_of_pattern, pattern_length); + struct_writer.AppendArrayOfBytes( + base::make_span(content_of_pattern, pattern_length)); pattern_array_writer->CloseContainer(&struct_writer); }
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc index eb035af..b6d3c54 100644 --- a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc +++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
@@ -133,7 +133,7 @@ bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface, bluetooth_gatt_characteristic::kWriteValue); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(value.data(), value.size()); + writer.AppendArrayOfBytes(value); // Append option dict base::Value::Dict dict; @@ -168,7 +168,7 @@ bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface, bluetooth_gatt_characteristic::kPrepareWriteValue); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(value.data(), value.size()); + writer.AppendArrayOfBytes(value); dbus::AppendValueData(&writer, base::Value::Dict());
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.cc index 0051f8b..0153149 100644 --- a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.cc +++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.cc
@@ -158,7 +158,7 @@ array_writer.OpenDictEntry(&dict_entry_writer); dict_entry_writer.AppendString(bluetooth_gatt_characteristic::kValueProperty); dict_entry_writer.OpenVariant("ay", &variant_writer); - variant_writer.AppendArrayOfBytes(value.data(), value.size()); + variant_writer.AppendArrayOfBytes(value); dict_entry_writer.CloseContainer(&variant_writer); array_writer.CloseContainer(&dict_entry_writer); writer.CloseContainer(&array_writer); @@ -512,7 +512,7 @@ std::unique_ptr<dbus::Response> response = dbus::Response::FromMethodCall(method_call); dbus::MessageWriter writer(response.get()); - writer.AppendArrayOfBytes(value.data(), value.size()); + writer.AppendArrayOfBytes(value); std::move(response_sender).Run(std::move(response)); }
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc index 6af0997..d79c34a 100644 --- a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc +++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
@@ -135,7 +135,7 @@ bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface, bluetooth_gatt_descriptor::kWriteValue); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(value.data(), value.size()); + writer.AppendArrayOfBytes(value); // Append empty option dict dbus::AppendValueData(&writer, base::Value::Dict());
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.cc index f0e2fc6..cc2f149 100644 --- a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.cc +++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.cc
@@ -123,7 +123,7 @@ array_writer.OpenDictEntry(&dict_entry_writer); dict_entry_writer.AppendString(bluetooth_gatt_descriptor::kValueProperty); dict_entry_writer.OpenVariant("ay", &variant_writer); - variant_writer.AppendArrayOfBytes(value.data(), value.size()); + variant_writer.AppendArrayOfBytes(value); dict_entry_writer.CloseContainer(&variant_writer); array_writer.CloseContainer(&dict_entry_writer); writer.CloseContainer(&array_writer); @@ -359,7 +359,7 @@ std::unique_ptr<dbus::Response> response = dbus::Response::FromMethodCall(method_call); dbus::MessageWriter writer(response.get()); - writer.AppendArrayOfBytes(value.data(), value.size()); + writer.AppendArrayOfBytes(value); std::move(response_sender).Run(std::move(response)); }
diff --git a/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc index bb72736..fa6f58ad 100644 --- a/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc +++ b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc
@@ -269,7 +269,7 @@ dbus::MessageWriter variant_writer(NULL); writer.OpenVariant("ay", &variant_writer); - variant_writer.AppendArrayOfBytes(value.data(), value.size()); + variant_writer.AppendArrayOfBytes(value); writer.CloseContainer(&variant_writer); std::move(response_sender).Run(std::move(response)); @@ -361,17 +361,17 @@ void AppendManufacturerDataVariant(dbus::MessageWriter* writer) { DCHECK(manufacturer_data_); - dbus::MessageWriter array_writer(NULL); + dbus::MessageWriter array_writer(nullptr); writer->OpenArray("{qv}", &array_writer); for (const auto& m : *manufacturer_data_) { - dbus::MessageWriter entry_writer(NULL); + dbus::MessageWriter entry_writer(nullptr); array_writer.OpenDictEntry(&entry_writer); entry_writer.AppendUint16(m.first); - dbus::MessageWriter variant_writer(NULL); + dbus::MessageWriter variant_writer(nullptr); entry_writer.OpenVariant("ay", &variant_writer); - variant_writer.AppendArrayOfBytes(m.second.data(), m.second.size()); + variant_writer.AppendArrayOfBytes(m.second); entry_writer.CloseContainer(&variant_writer); array_writer.CloseContainer(&entry_writer); @@ -381,17 +381,17 @@ void AppendServiceDataVariant(dbus::MessageWriter* writer) { DCHECK(service_data_); - dbus::MessageWriter array_writer(NULL); + dbus::MessageWriter array_writer(nullptr); writer->OpenArray("{sv}", &array_writer); for (const auto& m : *service_data_) { - dbus::MessageWriter entry_writer(NULL); + dbus::MessageWriter entry_writer(nullptr); array_writer.OpenDictEntry(&entry_writer); entry_writer.AppendString(m.first); - dbus::MessageWriter variant_writer(NULL); + dbus::MessageWriter variant_writer(nullptr); entry_writer.OpenVariant("ay", &variant_writer); - variant_writer.AppendArrayOfBytes(m.second.data(), m.second.size()); + variant_writer.AppendArrayOfBytes(m.second); entry_writer.CloseContainer(&variant_writer); array_writer.CloseContainer(&entry_writer); @@ -411,7 +411,7 @@ entry_writer.AppendByte(m.first); dbus::MessageWriter variant_writer(nullptr); entry_writer.OpenVariant("ay", &variant_writer); - variant_writer.AppendArrayOfBytes(m.second.data(), m.second.size()); + variant_writer.AppendArrayOfBytes(m.second); entry_writer.CloseContainer(&variant_writer); array_writer.CloseContainer(&entry_writer);
diff --git a/device/bluetooth/floss/floss_adapter_client_unittest.cc b/device/bluetooth/floss/floss_adapter_client_unittest.cc index 9a046b5..2e4c20c 100644 --- a/device/bluetooth/floss/floss_adapter_client_unittest.cc +++ b/device/bluetooth/floss/floss_adapter_client_unittest.cc
@@ -1084,8 +1084,7 @@ dbus::MessageWriter writer(response.get()); dbus::MessageWriter array_writer(nullptr); writer.OpenArray("ay", &array_writer); - array_writer.AppendArrayOfBytes(kFakeUuidByteArray, - sizeof(kFakeUuidByteArray)); + array_writer.AppendArrayOfBytes(kFakeUuidByteArray); writer.CloseContainer(&array_writer); std::move(*cb).Run(response.get(), /*err=*/nullptr); });
diff --git a/device/bluetooth/floss/floss_dbus_client.cc b/device/bluetooth/floss/floss_dbus_client.cc index 9a7e2a0..21cbc32a 100644 --- a/device/bluetooth/floss/floss_dbus_client.cc +++ b/device/bluetooth/floss/floss_dbus_client.cc
@@ -479,7 +479,7 @@ template <> void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer, const std::vector<uint8_t>& data) { - writer->AppendArrayOfBytes(data.data(), data.size()); + writer->AppendArrayOfBytes(data); } template <>
diff --git a/device/bluetooth/floss/floss_lescan_client_unittest.cc b/device/bluetooth/floss/floss_lescan_client_unittest.cc index f858f5b..60796f4 100644 --- a/device/bluetooth/floss/floss_lescan_client_unittest.cc +++ b/device/bluetooth/floss/floss_lescan_client_unittest.cc
@@ -151,7 +151,7 @@ method_call.SetSender(kTestSender); method_call.SetSerial(kTestSerial); dbus::MessageWriter writer(&method_call); - writer.AppendArrayOfBytes(kTestUuidByteArray, sizeof(kTestUuidByteArray)); + writer.AppendArrayOfBytes(kTestUuidByteArray); writer.AppendByte(kTestScannerId); writer.AppendUint32(static_cast<uint32_t>(kTestStatus)); @@ -347,8 +347,7 @@ // Create a fake response with UUID return value. auto response = ::dbus::Response::CreateEmpty(); dbus::MessageWriter writer(response.get()); - writer.AppendArrayOfBytes(kTestUuidByteArray, - sizeof(kTestUuidByteArray)); + writer.AppendArrayOfBytes(kTestUuidByteArray); std::move(*cb).Run(response.get(), /*err=*/nullptr); }); client_->RegisterScanner(
diff --git a/device/fido/win/authenticator.cc b/device/fido/win/authenticator.cc index 5365930..8dc0d671 100644 --- a/device/fido/win/authenticator.cc +++ b/device/fido/win/authenticator.cc
@@ -64,9 +64,8 @@ return allow_list.empty() || base::ranges::any_of(allow_list, [](const auto& credential) { return credential.transports.empty() || - credential.transports == - base::flat_set<FidoTransportProtocol>{ - FidoTransportProtocol::kInternal}; + base::Contains(credential.transports, + FidoTransportProtocol::kInternal); }); } @@ -283,8 +282,8 @@ const CtapGetAssertionOptions& request_options, GetPlatformCredentialInfoForRequestCallback callback) { // Handle the special case where a request has an allow list, all the - // credential descriptors have a transport, and none of those are "internal" - // only. These credentials cannot possibly be Windows Hello. + // credential descriptors have a transport, and none of have the "internal" + // transport. These credentials cannot possibly be Windows Hello. if (!MayHaveWindowsHelloCredentials(request.allow_list)) { std::move(callback).Run( /*credentials=*/{},
diff --git a/device/fido/win/authenticator_unittest.cc b/device/fido/win/authenticator_unittest.cc index 5f81ecc..b0fcbe97 100644 --- a/device/fido/win/authenticator_unittest.cc +++ b/device/fido/win/authenticator_unittest.cc
@@ -228,10 +228,9 @@ FidoRequestHandlerBase::RecognizedCredential::kNoRecognizedCredential); } -// Tests that for non empty allow-list requests without an only internal -// transport credential, the authenticator returns an empty credential list and -// reports no credential availability, even if silent discovery is not -// supported. +// Tests that for non empty allow-list requests without an internal transport +// credential, the authenticator returns an empty credential list and reports no +// credential availability, even if silent discovery is not supported. TEST_F(WinAuthenticatorTest, GetCredentialInformationForRequest_NonEmptyAllowList_NoInternal) { fake_webauthn_api_->set_supports_silent_discovery(false); @@ -241,6 +240,34 @@ PublicKeyCredentialDescriptor credential(CredentialType::kPublicKey, kCredentialId2); + credential.transports = {FidoTransportProtocol::kUsbHumanInterfaceDevice, + FidoTransportProtocol::kHybrid}; + request.allow_list.emplace_back(std::move(credential)); + + GetCredentialCallbackReceiver callback; + authenticator_->GetPlatformCredentialInfoForRequest( + std::move(request), CtapGetAssertionOptions(), callback.callback()); + callback.WaitForCallback(); + + EXPECT_EQ(std::get<0>(*callback.result()), + std::vector<DiscoverableCredentialMetadata>{}); + EXPECT_EQ( + std::get<1>(*callback.result()), + FidoRequestHandlerBase::RecognizedCredential::kNoRecognizedCredential); +} + +// Tests that for non empty allow-list requests with an internal transport +// credential, the authenticator returns an empty credential list reports +// unknown credential availability when silent discovery is not supported. +TEST_F(WinAuthenticatorTest, + GetCredentialInformationForRequest_NonEmptyAllowList_Internal) { + fake_webauthn_api_->set_supports_silent_discovery(false); + PublicKeyCredentialRpEntity rp(kRpId); + PublicKeyCredentialUserEntity user(kUserId, kUserName, kUserDisplayName); + CtapGetAssertionRequest request(kRpId, /*client_data_json=*/""); + + PublicKeyCredentialDescriptor credential(CredentialType::kPublicKey, + kCredentialId2); credential.transports = {FidoTransportProtocol::kInternal, FidoTransportProtocol::kHybrid}; request.allow_list.emplace_back(std::move(credential)); @@ -252,9 +279,8 @@ EXPECT_EQ(std::get<0>(*callback.result()), std::vector<DiscoverableCredentialMetadata>{}); - EXPECT_EQ( - std::get<1>(*callback.result()), - FidoRequestHandlerBase::RecognizedCredential::kNoRecognizedCredential); + EXPECT_EQ(std::get<1>(*callback.result()), + FidoRequestHandlerBase::RecognizedCredential::kUnknown); } TEST_F(WinAuthenticatorTest, EnumeratePlatformCredentials_NotSupported) {
diff --git a/docs/security/shepherd.md b/docs/security/shepherd.md index 2ba021a..5d399ba1 100644 --- a/docs/security/shepherd.md +++ b/docs/security/shepherd.md
@@ -474,6 +474,12 @@ Permissions Kill Switch, then follow [the instructions](https://docs.google.com/document/d/17JeYt3c1GgghYoxy4NKJnlxrteAX8F4x-MAzTeXqP4U) +### Vulnerabilities in Chromium's dependencies + +If you are handling a bug in one of Chromium's dependencies, see +[go/howto-investigate-autovm-chromium-bugs](https://goto.google.com/howto-investigate-autovm-chromium-bugs) +(Google-only, sorry) for some hints. + ### Wrapping Up The Fixed Issue 1. Check with the developer that the issue can be closed as Fixed to allow
diff --git a/docs/speed/perf_lab_platforms.md b/docs/speed/perf_lab_platforms.md index 43f12e7..21bf601b8 100644 --- a/docs/speed/perf_lab_platforms.md +++ b/docs/speed/perf_lab_platforms.md
@@ -45,6 +45,7 @@ * [win-10-perf](https://ci.chromium.org/p/chrome/builders/ci/win-10-perf): Windows Intel HD 630 towers, Core i7-7700 3.6 GHz, 16GB RAM, Intel Kaby Lake HD Graphics 630. * [win-10_amd_laptop-perf](https://ci.chromium.org/p/chrome/builders/ci/win-10_amd_laptop-perf): Windows 10 Laptop with AMD chipset.. * [win-10_laptop_low_end-perf](https://ci.chromium.org/p/chrome/builders/ci/win-10_laptop_low_end-perf): Low end windows 10 HP laptops. HD Graphics 5500, x86-64-i3-5005U, SSD, 4GB RAM.. + * [win-11-perf](https://ci.chromium.org/p/chrome/builders/ci/win-11-perf): Windows Dell PowerEdge R350. ## Pinpoint-Only Platforms @@ -75,6 +76,7 @@ * win-10-perf-pgo: Windows Intel HD 630 towers, Core i7-7700 3.6 GHz, 16GB RAM, Intel Kaby Lake HD Graphics 630. * win-10_amd_laptop-perf-pgo: Windows 10 Laptop with AMD chipset.. * win-10_laptop_low_end-perf-pgo: Low end windows 10 HP laptops. HD Graphics 5500, x86-64-i3-5005U, SSD, 4GB RAM.. + * win-11-perf-pgo: Windows Dell PowerEdge R350. ## FYI Platforms
diff --git a/docs/website b/docs/website index 504421a..b848d51 160000 --- a/docs/website +++ b/docs/website
@@ -1 +1 @@ -Subproject commit 504421a2e612c9042411ae65e24d7a7682dfdbe2 +Subproject commit b848d511837d6ccd44c6f7bef1576c0842d7e0ac
diff --git a/extensions/browser/api/networking_private/networking_private_linux.cc b/extensions/browser/api/networking_private/networking_private_linux.cc index 8e146deb..bcb9fc02 100644 --- a/extensions/browser/api/networking_private/networking_private_linux.cc +++ b/extensions/browser/api/networking_private/networking_private_linux.cc
@@ -419,8 +419,7 @@ dbus::MessageWriter variant_writer(&method_call); wifi_dict_writer.OpenVariant("ay", &variant_writer); - variant_writer.AppendArrayOfBytes( - reinterpret_cast<const uint8_t*>(ssid.c_str()), ssid.size()); + variant_writer.AppendArrayOfBytes(base::as_byte_span(ssid)); // Close all the arrays and dicts. wifi_dict_writer.CloseContainer(&variant_writer);
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 521a672..b1690a88 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -28237,7 +28237,7 @@ name: "Windows deterministic" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:Windows deterministic" - dimensions: "cores:8" + dimensions: "cores:32" dimensions: "cpu:x86-64" dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.ci"
diff --git a/infra/config/subprojects/chromium/ci/chromium.win.star b/infra/config/subprojects/chromium/ci/chromium.win.star index bbd3147f..9b431d97 100644 --- a/infra/config/subprojects/chromium/ci/chromium.win.star +++ b/infra/config/subprojects/chromium/ci/chromium.win.star
@@ -315,6 +315,7 @@ ], ), builderless = False, + cores = 32, console_view_entry = consoles.console_view_entry( category = "misc", short_name = "det",
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index bb54dfde..cbbf6b4 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -1070,8 +1070,8 @@ [self scheduleCrashReportUpload]; // ClearSessionCookies() is not synchronous. - if (cookie_util::ShouldClearSessionCookies()) { - ChromeBrowserState* browserState = self.appState.mainBrowserState; + ChromeBrowserState* browserState = self.appState.mainBrowserState; + if (cookie_util::ShouldClearSessionCookies(browserState->GetPrefs())) { cookie_util::ClearSessionCookies( browserState->GetOriginalChromeBrowserState()); Browser* otrBrowser =
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index de94b71..55590df 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -915,6 +915,9 @@ <message name="IDS_IOS_CONTACTS_USAGE_DESCRIPTION" desc="Specifies the reason for accessing the user's contacts while the app is in use [Length: unlimited] [iOS only]."> This will be used to show you possible invitees to your event. </message> + <message name="IDS_IOS_CONTENT_CONTEXT_ADDTABTONEWTABGROUP" desc="The iOS context menu item for adding a tab to a new tab group. Title case. [iOS only]"> + Add Tab to New Group + </message> <message name="IDS_IOS_CONTENT_CONTEXT_ADDTOBOOKMARKS" desc="The iOS context menu item for adding the url of a tab to the bookmarks. [iOS only]"> Add to Bookmarks </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CONTENT_CONTEXT_ADDTABTONEWTABGROUP.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CONTENT_CONTEXT_ADDTABTONEWTABGROUP.png.sha1 new file mode 100644 index 0000000..c1524391b --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CONTENT_CONTEXT_ADDTABTONEWTABGROUP.png.sha1
@@ -0,0 +1 @@ +a358c2bdfd874a826a8a8a746728e52247271b45 \ No newline at end of file
diff --git a/ios/chrome/browser/browsing_data/model/browsing_data_remover.h b/ios/chrome/browser/browsing_data/model/browsing_data_remover.h index 0812d2e..dd91f10 100644 --- a/ios/chrome/browser/browsing_data/model/browsing_data_remover.h +++ b/ios/chrome/browser/browsing_data/model/browsing_data_remover.h
@@ -34,6 +34,13 @@ BrowsingDataRemoveMask remove_mask, base::OnceClosure callback) = 0; + // A version of `Remove` that removes browsing data between a given + // `start_time` and `end_time` instead of a pre-specified `TimePeriod`. + virtual void RemoveInRange(base::Time start_time, + base::Time end_time, + BrowsingDataRemoveMask mask, + base::OnceClosure callback) = 0; + // Adds/removes `observer` from the list of observers notified when data is // removed by BrowsingDataRemover. void AddObserver(BrowsingDataRemoverObserver* observer);
diff --git a/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl.h b/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl.h index b49c4702..6b864c3 100644 --- a/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl.h +++ b/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl.h
@@ -45,6 +45,10 @@ void Remove(browsing_data::TimePeriod time_period, BrowsingDataRemoveMask remove_mask, base::OnceClosure callback) override; + void RemoveInRange(base::Time start_time, + base::Time end_time, + BrowsingDataRemoveMask mask, + base::OnceClosure callback) override; private: // Represents a single removal task. Contains all parameters to execute it.
diff --git a/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl.mm b/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl.mm index 30a2a23..79e46938 100644 --- a/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl.mm +++ b/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl.mm
@@ -248,6 +248,42 @@ } } +void BrowsingDataRemoverImpl::RemoveInRange(base::Time start_time, + base::Time end_time, + BrowsingDataRemoveMask mask, + base::OnceClosure callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(browser_state_); + + // Should always remove something. + DCHECK(mask != BrowsingDataRemoveMask::REMOVE_NOTHING); + + // In incognito, only data removal for all time is currently supported. + DCHECK(!browser_state_->IsOffTheRecord()); + + // Partial clearing of downloads, bookmarks or reading lists is not supported. + DCHECK(!( + IsRemoveDataMaskSet(mask, BrowsingDataRemoveMask::REMOVE_DOWNLOADS) || + IsRemoveDataMaskSet(mask, BrowsingDataRemoveMask::REMOVE_BOOKMARKS) || + IsRemoveDataMaskSet(mask, BrowsingDataRemoveMask::REMOVE_READING_LIST))); + + // Removing visited links requires clearing the cookies. + DCHECK( + IsRemoveDataMaskSet(mask, BrowsingDataRemoveMask::REMOVE_COOKIES) || + !IsRemoveDataMaskSet(mask, BrowsingDataRemoveMask::REMOVE_VISITED_LINKS)); + + // browsing_data::RecordDeletionForPeriod(time_period); + removal_queue_.emplace(start_time, end_time, mask, std::move(callback)); + + // If this is the only scheduled task, execute it immediately. Otherwise, + // it will be automatically executed when all tasks scheduled before it + // finish. + if (removal_queue_.size() == 1) { + SetRemoving(true); + RunNextTask(); + } +} + void BrowsingDataRemoverImpl::RunNextTask() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!removal_queue_.empty());
diff --git a/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl_unittest.mm b/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl_unittest.mm index be3813f..a46c461e 100644 --- a/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl_unittest.mm +++ b/ios/chrome/browser/browsing_data/model/browsing_data_remover_impl_unittest.mm
@@ -209,3 +209,70 @@ return remaining_calls == 0; })); } + +// Tests that BrowsingDataRemoverImpl::RemoveInRange() invokes the observers. +TEST_F(BrowsingDataRemoverImplTest, InvokesObservers_RemoveInRange) { + TestBrowsingDataRemoverObserver observer; + ASSERT_TRUE(observer.last_remove_mask() != kRemoveMask); + + base::ScopedObservation<BrowsingDataRemover, BrowsingDataRemoverObserver> + scoped_observer(&observer); + scoped_observer.Observe(&browsing_data_remover_); + + base::Time delete_start_time = base::Time::Now() - base::Hours(1); + base::Time delete_end_time = base::Time::Now(); + browsing_data_remover_.RemoveInRange(delete_start_time, delete_end_time, + kRemoveMask, base::DoNothing()); + + TestBrowsingDataRemoverObserver* observer_ptr = &observer; + EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^{ + // Spin the RunLoop as WaitUntilConditionOrTimeout doesn't. + base::RunLoop().RunUntilIdle(); + return observer_ptr->last_remove_mask() == kRemoveMask; + })); +} + +// Tests that BrowsingDataRemoverImpl::RemoveInRange() can be called multiple +// times. +TEST_F(BrowsingDataRemoverImplTest, SerializeRemovals_RemoveInRange) { + __block int remaining_calls = 2; + base::Time delete_start_time = base::Time::Now() - base::Hours(1); + base::Time delete_end_time = base::Time::Now(); + browsing_data_remover_.RemoveInRange(delete_start_time, delete_end_time, + kRemoveMask, base::BindOnce(^{ + --remaining_calls; + })); + + browsing_data_remover_.RemoveInRange(delete_start_time, delete_end_time, + kRemoveMask, base::BindOnce(^{ + --remaining_calls; + })); + + EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^{ + // Spin the RunLoop as WaitUntilConditionOrTimeout doesn't. + base::RunLoop().RunUntilIdle(); + return remaining_calls == 0; + })); +} + +// Tests that BrowsingDataRemoverImpl::RemoveInRange() can finish performing its +// operation even if the BrowserState is destroyed. +TEST_F(BrowsingDataRemoverImplTest, + PerformAfterBrowserStateDestruction_RemoveInRange) { + __block int remaining_calls = 1; + base::Time delete_start_time = base::Time::Now() - base::Hours(1); + base::Time delete_end_time = base::Time::Now(); + browsing_data_remover_.RemoveInRange(delete_start_time, delete_end_time, + kRemoveMask, base::BindOnce(^{ + --remaining_calls; + })); + + // Simulate destruction of BrowserState. + browsing_data_remover_.Shutdown(); + + EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^{ + // Spin the RunLoop as WaitUntilConditionOrTimeout doesn't. + base::RunLoop().RunUntilIdle(); + return remaining_calls == 0; + })); +}
diff --git a/ios/chrome/browser/browsing_data/model/fake_browsing_data_remover.h b/ios/chrome/browser/browsing_data/model/fake_browsing_data_remover.h index d98bde2..d17cccd4 100644 --- a/ios/chrome/browser/browsing_data/model/fake_browsing_data_remover.h +++ b/ios/chrome/browser/browsing_data/model/fake_browsing_data_remover.h
@@ -17,6 +17,10 @@ void Remove(browsing_data::TimePeriod time_period, BrowsingDataRemoveMask remove_mask, base::OnceClosure callback) override; + void RemoveInRange(base::Time start_time, + base::Time end_time, + BrowsingDataRemoveMask remove_mask, + base::OnceClosure callback) override; BrowsingDataRemoveMask GetLastUsedRemovalMask(); void SetFailedForTesting();
diff --git a/ios/chrome/browser/browsing_data/model/fake_browsing_data_remover.mm b/ios/chrome/browser/browsing_data/model/fake_browsing_data_remover.mm index 322da0e3..8abc09ab 100644 --- a/ios/chrome/browser/browsing_data/model/fake_browsing_data_remover.mm +++ b/ios/chrome/browser/browsing_data/model/fake_browsing_data_remover.mm
@@ -19,6 +19,11 @@ } } +void FakeBrowsingDataRemover::RemoveInRange(base::Time start_time, + base::Time end_time, + BrowsingDataRemoveMask remove_mask, + base::OnceClosure callback) {} + BrowsingDataRemoveMask FakeBrowsingDataRemover::GetLastUsedRemovalMask() { return last_remove_mask_; }
diff --git a/ios/chrome/browser/enterprise/model/idle/idle_service_factory.mm b/ios/chrome/browser/enterprise/model/idle/idle_service_factory.mm index e4fbae8..f249516a 100644 --- a/ios/chrome/browser/enterprise/model/idle/idle_service_factory.mm +++ b/ios/chrome/browser/enterprise/model/idle/idle_service_factory.mm
@@ -41,6 +41,8 @@ registry->RegisterListPref(enterprise_idle::prefs::kIdleTimeoutActions); registry->RegisterTimePref(enterprise_idle::prefs::kLastIdleTimestamp, base::Time()); + registry->RegisterBooleanPref( + enterprise_idle::prefs::kIdleTimeoutPolicyAppliesToUserOnly, false); } } // namespace enterprise_idle
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn index 7583030..7d011a2 100644 --- a/ios/chrome/browser/flags/BUILD.gn +++ b/ios/chrome/browser/flags/BUILD.gn
@@ -38,6 +38,7 @@ "//components/payments/core", "//components/policy:generated", "//components/policy/core/common:common_constants", + "//components/reading_list/features:flags", "//components/safe_browsing/core/common", "//components/search_provider_logos", "//components/security_state/core",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 94d3189..7e588f2 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -52,6 +52,7 @@ #import "components/policy/core/common/features.h" #import "components/policy/core/common/policy_loader_ios_constants.h" #import "components/policy/policy_constants.h" +#import "components/reading_list/features/reading_list_switches.h" #import "components/safe_browsing/core/common/features.h" #import "components/segmentation_platform/public/constants.h" #import "components/segmentation_platform/public/features.h" @@ -1310,6 +1311,11 @@ flags_ui::kOsIos, FEATURE_VALUE_TYPE(password_manager::features:: kIOSPasswordSettingsBulkUploadLocalPasswords)}, + {"enable-reading-list-sign-in-promo", + flag_descriptions::kEnableReadingListSignInPromoName, + flag_descriptions::kEnableReadingListSignInPromoDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE(syncer::kReadingListEnableSyncTransportModeUponSignIn)}, {"omnibox-grouping-framework-zps", flag_descriptions::kOmniboxGroupingFrameworkForZPSName, flag_descriptions::kOmniboxGroupingFrameworkForZPSDescription, @@ -1608,6 +1614,9 @@ {"revamp-page-info-ios", flag_descriptions::kRevampPageInfoIosName, flag_descriptions::kRevampPageInfoIosDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kRevampPageInfoIos)}, + {"ios-external-action-urls", flag_descriptions::kIOSExternalActionURLsName, + flag_descriptions::kIOSExternalActionURLsDescription, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(kIOSExternalActionURLs)}, }; bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 06f37a5..c35fd0f 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -513,6 +513,10 @@ extern const char kIOSEditMenuHideSearchWebDescription[] = "Hides the Search Web entry in edit menu."; +extern const char kIOSExternalActionURLsName[] = "iOS external action URLs"; +extern const char kIOSExternalActionURLsDescription[] = + "When enabled, the browser will support handling external action URLs."; + const char kIOSIncognitoDownloadsWarningName[] = "Enable Incognito downloads warning on iOS"; const char kIOSIncognitoDownloadsWarningDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index 0562422..214b80f 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -441,6 +441,10 @@ extern const char kIOSEditMenuHideSearchWebName[]; extern const char kIOSEditMenuHideSearchWebDescription[]; +// Title and description for the flag to enable handling external action URLs. +extern const char kIOSExternalActionURLsName[]; +extern const char kIOSExternalActionURLsDescription[]; + // Title and description for the flag to enable Incognito downloads education. extern const char kIOSIncognitoDownloadsWarningName[]; extern const char kIOSIncognitoDownloadsWarningDescription[];
diff --git a/ios/chrome/browser/reading_list/model/BUILD.gn b/ios/chrome/browser/reading_list/model/BUILD.gn index e709368..03084387 100644 --- a/ios/chrome/browser/reading_list/model/BUILD.gn +++ b/ios/chrome/browser/reading_list/model/BUILD.gn
@@ -41,6 +41,7 @@ "//components/pref_registry", "//components/prefs", "//components/reading_list/core", + "//components/reading_list/features:flags", "//components/reading_list/ios", "//components/sync", "//components/ukm/ios:ukm_url_recorder",
diff --git a/ios/chrome/browser/reading_list/model/reading_list_browser_agent.mm b/ios/chrome/browser/reading_list/model/reading_list_browser_agent.mm index a68e553..9055a84 100644 --- a/ios/chrome/browser/reading_list/model/reading_list_browser_agent.mm +++ b/ios/chrome/browser/reading_list/model/reading_list_browser_agent.mm
@@ -11,8 +11,8 @@ #import "base/metrics/user_metrics.h" #import "base/strings/sys_string_conversions.h" #import "components/reading_list/core/reading_list_model.h" +#import "components/reading_list/features/reading_list_switches.h" #import "components/signin/public/identity_manager/identity_manager.h" -#import "components/sync/base/features.h" #import "components/ukm/ios/ukm_url_recorder.h" #import "ios/chrome/browser/reading_list/model/reading_list_constants.h" #import "ios/chrome/browser/reading_list/model/reading_list_model_factory.h" @@ -64,8 +64,10 @@ base::i18n::MessageFormatter::FormatWithNamedArgs( pattern, "count", (int)urls.count, "email", account_info.email); snackbar_text = base::SysUTF16ToNSString(utf16Text); - static_assert(syncer::IsReadingListAccountStorageEnabled()); - snackbar_action = CreateUndoActionWithReadingListURLs(urls); + snackbar_action = + reading_list::switches::IsReadingListAccountStorageUIEnabled() + ? CreateUndoActionWithReadingListURLs(urls) + : nil; } else { snackbar_text = l10n_util::GetNSString(IDS_IOS_READING_LIST_SNACKBAR_MESSAGE);
diff --git a/ios/chrome/browser/segmentation_platform/model/BUILD.gn b/ios/chrome/browser/segmentation_platform/model/BUILD.gn index f1ad814..7e507c3 100644 --- a/ios/chrome/browser/segmentation_platform/model/BUILD.gn +++ b/ios/chrome/browser/segmentation_platform/model/BUILD.gn
@@ -14,6 +14,7 @@ "segmentation_platform_service_factory.mm", ] deps = [ + ":ukm_client", "//base", "//components/keyed_service/core", "//components/keyed_service/ios", @@ -28,6 +29,7 @@ "//components/segmentation_platform/public", "//components/segmentation_platform/public/proto", "//components/sync_device_info", + "//components/ukm", "//components/variations", "//ios/chrome/browser/history/model", "//ios/chrome/browser/metrics/model:accessor", @@ -45,20 +47,46 @@ frameworks = [ "Foundation.framework" ] } +source_set("ukm_client") { + sources = [ + "ukm_database_client.h", + "ukm_database_client.mm", + ] + deps = [ + "//base", + "//components/metrics_services_manager", + "//components/segmentation_platform/internal", + "//components/ukm", + "//ios/chrome/browser/shared/model/application_context", + "//ios/chrome/browser/shared/model/browser_state:browser_state", + "//ios/chrome/browser/shared/model/paths", + "//services/metrics/public/cpp:ukm_builders", + ] +} + source_set("unit_tests") { testonly = true sources = [ "otr_web_state_observer_unittest.mm", "segmentation_platform_service_factory_unittest.mm", + "ukm_data_manager_test_utils.h", + "ukm_data_manager_test_utils.mm", ] deps = [ ":model", + ":ukm_client", "//base/test:test_support", + "//components/history/core/browser", "//components/optimization_guide/core", "//components/optimization_guide/core:features", + "//components/segmentation_platform/embedder", + "//components/segmentation_platform/internal", + "//components/segmentation_platform/internal:test_support", "//components/segmentation_platform/internal/proto", "//components/segmentation_platform/public", "//components/segmentation_platform/public/proto", + "//components/ukm:test_support", + "//ios/chrome/browser/history/model", "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/browser/test:test_support", "//ios/chrome/browser/shared/model/browser_state:test_support", @@ -67,6 +95,7 @@ "//ios/chrome/test:test_support", "//ios/web/public/test", "//ios/web/public/test/fakes", + "//services/metrics/public/cpp:ukm_builders", "//testing/gtest", ] }
diff --git a/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory.mm b/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory.mm index ca30fed..ca82210 100644 --- a/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory.mm +++ b/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory.mm
@@ -30,6 +30,7 @@ #import "ios/chrome/browser/optimization_guide/model/optimization_guide_service_factory.h" #import "ios/chrome/browser/segmentation_platform/model/otr_web_state_observer.h" #import "ios/chrome/browser/segmentation_platform/model/segmentation_platform_config.h" +#import "ios/chrome/browser/segmentation_platform/model/ukm_database_client.h" #import "ios/chrome/browser/shared/model/application_context/application_context.h" #import "ios/chrome/browser/shared/model/browser_state/browser_state_otr_helper.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" @@ -50,11 +51,6 @@ const char kSegmentationTabRankDispatcherUserDataKey[] = "segmentation_tab_rank_dispatcher_data"; -UkmDataManager* GetUkmDataManager() { - static base::NoDestructor<DummyUkmDataManager> instance; - return instance.get(); -} - std::unique_ptr<processing::InputDelegateHolder> SetUpInputDelegates( std::vector<std::unique_ptr<Config>>& configs, sync_sessions::SessionSyncService* session_sync_service, @@ -141,7 +137,9 @@ params->db_provider = protodb_provider; params->clock = base::DefaultClock::GetInstance(); - params->ukm_data_manager = GetUkmDataManager(); + params->ukm_data_manager = + UkmDatabaseClientHolder::GetClientInstance(chrome_browser_state) + .GetUkmDataManager(); params->profile_prefs = chrome_browser_state->GetPrefs(); params->configs = GetSegmentationPlatformConfig();
diff --git a/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm b/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm index 0edfc1f..6b6a147 100644 --- a/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm +++ b/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm
@@ -6,9 +6,14 @@ #import "base/functional/bind.h" #import "base/memory/scoped_refptr.h" +#import "base/test/scoped_command_line.h" #import "base/test/scoped_feature_list.h" #import "base/test/task_environment.h" #import "components/optimization_guide/core/optimization_guide_features.h" +#import "components/prefs/pref_change_registrar.h" +#import "components/prefs/pref_service.h" +#import "components/segmentation_platform/internal/constants.h" +#import "components/segmentation_platform/internal/database/client_result_prefs.h" #import "components/segmentation_platform/public/constants.h" #import "components/segmentation_platform/public/features.h" #import "components/segmentation_platform/public/prediction_options.h" @@ -16,6 +21,8 @@ #import "components/segmentation_platform/public/segment_selection_result.h" #import "components/segmentation_platform/public/segmentation_platform_service.h" #import "components/segmentation_platform/public/service_proxy.h" +#import "components/ukm/test_ukm_recorder.h" +#import "ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.h" #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" #import "ios/web/public/test/web_task_environment.h" #import "testing/gtest/include/gtest/gtest.h" @@ -42,71 +49,181 @@ } // namespace class SegmentationPlatformServiceFactoryTest : public PlatformTest { public: - SegmentationPlatformServiceFactoryTest() { + SegmentationPlatformServiceFactoryTest() + : test_utils_(std::make_unique<UkmDataManagerTestUtils>(&ukm_recorder_)) { // TODO(b/293500507): Create a base class for testing default models. scoped_feature_list_.InitWithFeaturesAndParameters( {{optimization_guide::features::kOptimizationTargetPrediction, {}}, {features::kSegmentationPlatformFeature, {}}, + {features::kSegmentationPlatformUkmEngine, {}}, + {features::kContextualPageActionShareModel, + {{"ukm-input-enabled", "true"}}}, {features::kSegmentationPlatformIosModuleRanker, {{kDefaultModelEnabledParam, "true"}}}}, {}); + scoped_command_line_.GetProcessCommandLine()->AppendSwitch( + kSegmentationPlatformRefreshResultsSwitch); + scoped_command_line_.GetProcessCommandLine()->AppendSwitch( + kSegmentationPlatformDisableModelExecutionDelaySwitch); } ~SegmentationPlatformServiceFactoryTest() override = default; - void OnGetClassificationResult(base::RepeatingClosure closure, - const ClassificationResult& result) { - ASSERT_EQ(result.status, PredictionStatus::kSucceeded); - EXPECT_FALSE(result.ordered_labels.empty()); - EXPECT_EQ(5u, result.ordered_labels.size()); - EXPECT_EQ("MostVisitedTiles", result.ordered_labels[0]); - EXPECT_EQ("Shortcuts", result.ordered_labels[1]); - EXPECT_EQ("SafetyCheck", result.ordered_labels[2]); - EXPECT_EQ("TabResumption", result.ordered_labels[3]); - EXPECT_EQ("ParcelTracking", result.ordered_labels[4]); - - std::move(closure).Run(); - } - void SetUp() override { PlatformTest::SetUp(); - TestChromeBrowserState::Builder builder; - builder.AddTestingFactory( - SegmentationPlatformServiceFactory::GetInstance(), - SegmentationPlatformServiceFactory::GetDefaultFactory()); - browser_state_ = builder.Build(); - - service = SegmentationPlatformServiceFactory::GetForBrowserState( - browser_state_.get()); + test_utils_->PreProfileInit({}); + profile_ = std::make_unique<ProfileData>(test_utils_.get(), ""); WaitForServiceInit(); ChromeBrowserState* otr_browser_state = - browser_state_->CreateOffTheRecordBrowserStateWithTestingFactories( - {std::make_pair( - SegmentationPlatformServiceFactory::GetInstance(), - SegmentationPlatformServiceFactory::GetDefaultFactory())}); + profile_->browser_state + ->CreateOffTheRecordBrowserStateWithTestingFactories( + {std::make_pair( + SegmentationPlatformServiceFactory::GetInstance(), + SegmentationPlatformServiceFactory::GetDefaultFactory())}); ASSERT_FALSE(SegmentationPlatformServiceFactory::GetForBrowserState( otr_browser_state)); } + void TearDown() override { + web_task_env_.RunUntilIdle(); + profile_.reset(); + test_utils_.reset(); + } + + void InitServiceAndCacheResults(const std::string& segmentation_key) { + WaitForServiceInit(); + WaitForClientResultPrefUpdate(segmentation_key); + const std::string output = profile_->browser_state->GetPrefs()->GetString( + kSegmentationClientResultPrefs); + + // TODO(b/297091996): Remove this when leak is fixed. + web_task_env_.RunUntilIdle(); + + profile_.reset(); + + // Creating profile and initialising segmentation service again with prefs + // from the last session. + profile_ = std::make_unique<ProfileData>(test_utils_.get(), output); + // Copying the prefs from last session. + WaitForServiceInit(); + // TODO(b/297091996): Remove this when leak is fixed. + web_task_env_.RunUntilIdle(); + } + + bool HasClientResultPref(const std::string& segmentation_key) { + PrefService* pref_service_ = profile_->browser_state->GetPrefs(); + std::unique_ptr<ClientResultPrefs> result_prefs_ = + std::make_unique<ClientResultPrefs>(pref_service_); + return result_prefs_->ReadClientResultFromPrefs(segmentation_key) != + nullptr; + } + + void OnClientResultPrefUpdated(const std::string& segmentation_key) { + if (!wait_for_pref_callback_.is_null() && + HasClientResultPref(segmentation_key)) { + std::move(wait_for_pref_callback_).Run(); + } + } + + void WaitForClientResultPrefUpdate(const std::string& segmentation_key) { + if (HasClientResultPref(segmentation_key)) { + return; + } + + base::RunLoop wait_for_pref; + wait_for_pref_callback_ = wait_for_pref.QuitClosure(); + pref_registrar_.Init(profile_->browser_state->GetPrefs()); + pref_registrar_.Add( + kSegmentationClientResultPrefs, + base::BindRepeating( + &SegmentationPlatformServiceFactoryTest::OnClientResultPrefUpdated, + base::Unretained(this), segmentation_key)); + wait_for_pref.Run(); + + pref_registrar_.RemoveAll(); + } + protected: + struct ProfileData { + explicit ProfileData(UkmDataManagerTestUtils* test_utils, + const std::string& result_pref) + : test_utils(test_utils) { + TestChromeBrowserState::Builder builder; + builder.AddTestingFactory( + SegmentationPlatformServiceFactory::GetInstance(), + SegmentationPlatformServiceFactory::GetDefaultFactory()); + browser_state = builder.Build(); + + browser_state->GetPrefs()->SetString(kSegmentationClientResultPrefs, + result_pref); + test_utils->SetupForProfile(browser_state.get()); + service = SegmentationPlatformServiceFactory::GetForBrowserState( + browser_state.get()); + } + + ~ProfileData() { test_utils->WillDestroyProfile(browser_state.get()); } + + ProfileData(ProfileData&) = delete; + + const raw_ptr<UkmDataManagerTestUtils> test_utils; + std::unique_ptr<TestChromeBrowserState> browser_state; + raw_ptr<SegmentationPlatformService> service; + }; + void WaitForServiceInit() { + if (profile_->service->IsPlatformInitialized()) { + return; + } base::RunLoop wait_for_init; WaitServiceInitializedObserver wait_observer(wait_for_init.QuitClosure()); - service->GetServiceProxy()->AddObserver(&wait_observer); + profile_->service->GetServiceProxy()->AddObserver(&wait_observer); wait_for_init.Run(); - while (!service->IsPlatformInitialized()) { + while (!profile_->service->IsPlatformInitialized()) { base::RunLoop().RunUntilIdle(); } - service->GetServiceProxy()->RemoveObserver(&wait_observer); + profile_->service->GetServiceProxy()->RemoveObserver(&wait_observer); + } + + void ExpectGetClassificationResult( + const std::string& segmentation_key, + const PredictionOptions& prediction_options, + scoped_refptr<InputContext> input_context, + PredictionStatus expected_status, + absl::optional<std::vector<std::string>> expected_labels) { + base::RunLoop loop; + profile_->service->GetClassificationResult( + segmentation_key, prediction_options, input_context, + base::BindOnce( + &SegmentationPlatformServiceFactoryTest::OnGetClassificationResult, + base::Unretained(this), loop.QuitClosure(), expected_status, + expected_labels)); + loop.Run(); + } + + void OnGetClassificationResult( + base::RepeatingClosure closure, + PredictionStatus expected_status, + absl::optional<std::vector<std::string>> expected_labels, + const ClassificationResult& actual_result) { + EXPECT_EQ(actual_result.status, expected_status); + if (expected_labels.has_value()) { + EXPECT_EQ(actual_result.ordered_labels, expected_labels.value()); + } + std::move(closure).Run(); } base::test::ScopedFeatureList scoped_feature_list_; web::WebTaskEnvironment web_task_env_; - SegmentationPlatformService* service; - std::unique_ptr<TestChromeBrowserState> browser_state_; + base::test::ScopedCommandLine scoped_command_line_; + ukm::TestUkmRecorder ukm_recorder_; + PrefChangeRegistrar pref_registrar_; + base::OnceClosure wait_for_pref_callback_; + + std::unique_ptr<UkmDataManagerTestUtils> test_utils_; + std::unique_ptr<ProfileData> profile_; }; TEST_F(SegmentationPlatformServiceFactoryTest, Test) { @@ -114,6 +231,18 @@ // fixed. } +TEST_F(SegmentationPlatformServiceFactoryTest, TestSearchUserModel) { + InitServiceAndCacheResults(kSearchUserKey); + + PredictionOptions prediction_options; + + ExpectGetClassificationResult( + kSearchUserKey, prediction_options, nullptr, + /*expected_status=*/PredictionStatus::kSucceeded, + /*expected_labels=*/ + std::vector<std::string>(1, kSearchUserModelLabelNone)); +} + TEST_F(SegmentationPlatformServiceFactoryTest, TestIosModuleRankerModel) { segmentation_platform::PredictionOptions prediction_options; prediction_options.on_demand_execution = true; @@ -146,14 +275,11 @@ segmentation_platform::processing::ProcessedValue::FromFloat( parcel_tracking_freshness_impression_count)); - base::RunLoop loop; - service->GetClassificationResult( + ExpectGetClassificationResult( segmentation_platform::kIosModuleRankerKey, prediction_options, - input_context, - base::BindOnce( - &SegmentationPlatformServiceFactoryTest::OnGetClassificationResult, - base::Unretained(this), loop.QuitClosure())); - loop.Run(); + input_context, PredictionStatus::kSucceeded, + std::vector<std::string>{"MostVisitedTiles", "Shortcuts", "SafetyCheck", + "TabResumption", "ParcelTracking"}); } } // namespace segmentation_platform
diff --git a/ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.h b/ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.h new file mode 100644 index 0000000..b55ad96 --- /dev/null +++ b/ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.h
@@ -0,0 +1,96 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_SEGMENTATION_PLATFORM_MODEL_UKM_DATA_MANAGER_TEST_UTILS_H_ +#define IOS_CHROME_BROWSER_SEGMENTATION_PLATFORM_MODEL_UKM_DATA_MANAGER_TEST_UTILS_H_ + +#include <string> + +#include "base/memory/weak_ptr.h" +#include "components/segmentation_platform/internal/execution/mock_model_provider.h" +#include "components/segmentation_platform/public/proto/model_metadata.pb.h" +#include "components/segmentation_platform/public/proto/segmentation_platform.pb.h" +#include "components/ukm/test_ukm_recorder.h" +#include "ios/chrome/browser/segmentation_platform/model/ukm_database_client.h" + +class GURL; + +namespace history { +class HistoryService; +} + +namespace segmentation_platform { + +// Utility used for testing UKM based engine. +class UkmDataManagerTestUtils { + public: + // `owned_db_client` is used for unittests that require multiple clients in + // the same process. + explicit UkmDataManagerTestUtils(ukm::TestUkmRecorder* ukm_recorder, + bool owned_db_client = true); + ~UkmDataManagerTestUtils(); + + UkmDataManagerTestUtils(const UkmDataManagerTestUtils&) = delete; + UkmDataManagerTestUtils& operator=(const UkmDataManagerTestUtils&) = delete; + + // Must be called before the first profile initialization, sets up default + // model overrides for the given `default_overrides` + void PreProfileInit( + const std::map<proto::SegmentId, proto::SegmentationModelMetadata>& + default_overrides); + + // Sets up the UKM testing for the `profile`. Can be called multiple times in + // the same process for different profiles, but WillDestroyProfile() must be + // called before setting up the next profile. + void SetupForProfile(ChromeBrowserState* profile); + + // Must be called before destroying `profile`. + void WillDestroyProfile(ChromeBrowserState* profile); + + // The UKM observers are registered after platform initialization. Wait for it + // to register observers, so that the UKM signals written by tests will be + // recorded in database. + void WaitForUkmObserverRegistration(); + + // Creates a sample page load UKM based model metadata, with a simple SQL + // feature with `query`. + proto::SegmentationModelMetadata GetSamplePageLoadMetadata( + const std::string& query); + + // Records a page load and 2 valid UKM metrics associated with it. May record + // other UKM metrics that are unrelated to the metadata provided by + // GetSamplePageLoadMetadata(). + void RecordPageLoadUkm(const GURL& url, base::Time history_timestamp); + + // Returns whether the `url` is part of the UKM database. + bool IsUrlInDatabase(const GURL& url); + + // Returns the model provider override for the `segment_id`. + MockDefaultModelProvider* GetDefaultOverride(proto::SegmentId segment_id); + + // History service is needed for validating test URLs written to database. + void set_history_service(history::HistoryService* history_service) { + history_service_ = history_service; + } + + UkmDatabaseClient* ukm_database_client() { + return ukm_database_client_.get(); + } + + private: + const raw_ptr<ukm::TestUkmRecorder> ukm_recorder_; + int source_id_counter_ = 1; + raw_ptr<history::HistoryService> history_service_; + raw_ptr<UkmDatabaseClient> ukm_database_client_; + + std::unique_ptr<UkmDatabaseClient> owned_db_client_; + + std::map<proto::SegmentId, MockDefaultModelProvider*> default_overrides_; + + base::WeakPtrFactory<UkmDataManagerTestUtils> weak_factory_{this}; +}; + +} // namespace segmentation_platform + +#endif // IOS_CHROME_BROWSER_SEGMENTATION_PLATFORM_MODEL_UKM_DATA_MANAGER_TEST_UTILS_H_
diff --git a/ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.mm b/ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.mm new file mode 100644 index 0000000..458b15a --- /dev/null +++ b/ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.mm
@@ -0,0 +1,192 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.h" + +#import "base/run_loop.h" +#import "components/history/core/browser/history_service.h" +#import "components/keyed_service/core/service_access_type.h" +#import "components/segmentation_platform/embedder/model_provider_factory_impl.h" +#import "components/segmentation_platform/internal/database/ukm_database.h" +#import "components/segmentation_platform/internal/execution/mock_model_provider.h" +#import "components/segmentation_platform/internal/metadata/metadata_writer.h" +#import "components/segmentation_platform/internal/segmentation_platform_service_impl.h" +#import "components/segmentation_platform/internal/signals/ukm_observer.h" +#import "components/segmentation_platform/internal/ukm_data_manager.h" +#import "components/segmentation_platform/public/proto/segmentation_platform.pb.h" +#import "ios/chrome/browser/history/model/history_service_factory.h" +#import "ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory.h" +#import "ios/chrome/browser/segmentation_platform/model/ukm_database_client.h" +#import "services/metrics/public/cpp/ukm_builders.h" +#import "testing/gtest/include/gtest/gtest.h" +#import "url/gurl.h" + +namespace segmentation_platform { + +namespace { + +using ::segmentation_platform::proto::SegmentId; +using ::testing::Return; +using ::ukm::builders::PageLoad; + +// Returns a sample UKM entry. +ukm::mojom::UkmEntryPtr GetSamplePageLoadEntry(ukm::SourceId source_id) { + ukm::mojom::UkmEntryPtr entry = ukm::mojom::UkmEntry::New(); + entry->source_id = source_id; + entry->event_hash = PageLoad::kEntryNameHash; + entry->metrics[PageLoad::kCpuTimeNameHash] = 10; + entry->metrics[PageLoad::kIsNewBookmarkNameHash] = 20; + entry->metrics[PageLoad::kIsNTPCustomLinkNameHash] = 30; + return entry; +} + +// Runs the given query and returns the result as float value. See +// RunReadonlyQueries() for more info. +absl::optional<float> RunQueryAndGetResult( + UkmDatabase* database, + UkmDatabase::CustomSqlQuery&& query) { + absl::optional<float> output; + UkmDatabase::QueryList queries; + queries.emplace(0, std::move(query)); + base::RunLoop wait_for_query; + database->RunReadonlyQueries( + std::move(queries), + base::BindOnce( + [](base::OnceClosure quit, absl::optional<float>* output, + bool success, processing::IndexedTensors tensor) { + if (success) { + EXPECT_EQ(1u, tensor.size()); + EXPECT_EQ(1u, tensor.at(0).size()); + *output = tensor.at(0)[0].float_val; + } + std::move(quit).Run(); + }, + wait_for_query.QuitClosure(), &output)); + wait_for_query.Run(); + return output; +} + +} // namespace + +UkmDataManagerTestUtils::UkmDataManagerTestUtils( + ukm::TestUkmRecorder* ukm_recorder, + bool owned_db_client) + : ukm_recorder_(ukm_recorder) { + if (owned_db_client) { + owned_db_client_ = std::make_unique<UkmDatabaseClient>(); + ukm_database_client_ = owned_db_client_.get(); + } else { + ukm_database_client_ = &UkmDatabaseClientHolder::GetClientInstance(nullptr); + } +} +UkmDataManagerTestUtils::~UkmDataManagerTestUtils() { +#if !BUILDFLAG(IS_ANDROID) + // The client should be torn down after profile is destroyed. On Android + // browser tests the profile is never destroyed, so do not tear down the + // client. + ukm_database_client_->TearDownForTesting(); +#endif + ukm_database_client_ = nullptr; +} + +void UkmDataManagerTestUtils::PreProfileInit( + const std::map<SegmentId, proto::SegmentationModelMetadata>& + default_overrides) { + // Set test recorder before UkmObserver is created. + ukm_database_client_->set_ukm_recorder_for_testing(ukm_recorder_); + + for (const auto& segment : default_overrides) { + auto provider = std::make_unique<MockDefaultModelProvider>(segment.first, + segment.second); + + default_overrides_[segment.first] = provider.get(); + // Default model must be overridden before the platform is created: + TestDefaultModelOverride::GetInstance().SetModelForTesting( + segment.first, std::move(provider)); + } + + if (owned_db_client_) { + owned_db_client_->PreProfileInit(/*in_memory_database=*/true); + } +} + +void UkmDataManagerTestUtils::SetupForProfile(ChromeBrowserState* profile) { + UkmDatabaseClientHolder::SetUkmClientForTesting(profile, + ukm_database_client_.get()); + CHECK_EQ(ukm_database_client_.get(), + &UkmDatabaseClientHolder::GetClientInstance(profile)); + history_service_ = ios::HistoryServiceFactory::GetForBrowserState( + profile, ServiceAccessType::EXPLICIT_ACCESS); + // Create the platform to kick off initialization. + segmentation_platform::SegmentationPlatformServiceFactory::GetForBrowserState( + profile); +} + +void UkmDataManagerTestUtils::WillDestroyProfile(ChromeBrowserState* profile) { + UkmDatabaseClientHolder::SetUkmClientForTesting(profile, nullptr); +} + +void UkmDataManagerTestUtils::WaitForUkmObserverRegistration() { + UkmObserver* observer = ukm_database_client_->ukm_observer_for_testing(); + while (!observer->is_started_for_testing()) { + base::RunLoop().RunUntilIdle(); + } +} + +proto::SegmentationModelMetadata +UkmDataManagerTestUtils::GetSamplePageLoadMetadata(const std::string& query) { + proto::SegmentationModelMetadata metadata; + MetadataWriter writer(&metadata); + writer.AddOutputConfigForBinaryClassifier( + /*threshold=*/0.5f, + /*positive_label=*/"Show", + /*negative_label=*/"NotShow"); + metadata.set_time_unit(proto::TimeUnit::DAY); + metadata.set_bucket_duration(42u); + + auto* feature = metadata.add_input_features(); + auto* sql_feature = feature->mutable_sql_feature(); + sql_feature->set_sql(query); + + auto* ukm_event = sql_feature->mutable_signal_filter()->add_ukm_events(); + ukm_event->set_event_hash(PageLoad::kEntryNameHash); + ukm_event->add_metric_hash_filter(PageLoad::kCpuTimeNameHash); + ukm_event->add_metric_hash_filter(PageLoad::kIsNewBookmarkNameHash); + return metadata; +} + +void UkmDataManagerTestUtils::RecordPageLoadUkm(const GURL& url, + base::Time history_timestamp) { + UkmObserver* observer = ukm_database_client_->ukm_observer_for_testing(); + // Ensure that the observer is started before recording metrics. + ASSERT_TRUE(observer->is_started_for_testing()); + // Ensure that OTR profiles are not started in the test. + ASSERT_FALSE(observer->is_paused_for_testing()); + + ukm_recorder_->AddEntry(GetSamplePageLoadEntry(source_id_counter_)); + ukm_recorder_->UpdateSourceURL(source_id_counter_, url); + source_id_counter_++; + + // Without a history service the recorded URLs will not be written to + // database. + ASSERT_TRUE(history_service_); + history_service_->AddPage(url, history_timestamp, + history::VisitSource::SOURCE_BROWSED); +} + +bool UkmDataManagerTestUtils::IsUrlInDatabase(const GURL& url) { + UkmDatabase::CustomSqlQuery query("SELECT 1 FROM urls WHERE url=?", + {processing::ProcessedValue(url.spec())}); + absl::optional<float> result = RunQueryAndGetResult( + ukm_database_client_->GetUkmDataManager()->GetUkmDatabase(), + std::move(query)); + return !!result; +} + +MockDefaultModelProvider* UkmDataManagerTestUtils::GetDefaultOverride( + proto::SegmentId segment_id) { + return default_overrides_[segment_id]; +} + +} // namespace segmentation_platform
diff --git a/ios/chrome/browser/segmentation_platform/model/ukm_database_client.h b/ios/chrome/browser/segmentation_platform/model/ukm_database_client.h new file mode 100644 index 0000000..d3bd06bf --- /dev/null +++ b/ios/chrome/browser/segmentation_platform/model/ukm_database_client.h
@@ -0,0 +1,103 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_SEGMENTATION_PLATFORM_MODEL_UKM_DATABASE_CLIENT_H_ +#define IOS_CHROME_BROWSER_SEGMENTATION_PLATFORM_MODEL_UKM_DATABASE_CLIENT_H_ + +#import "base/check.h" +#import "base/memory/raw_ptr.h" +#import "base/no_destructor.h" +#import "base/synchronization/lock.h" +#import "base/thread_annotations.h" +#import "components/segmentation_platform/internal/signals/ukm_observer.h" +#import "components/segmentation_platform/internal/ukm_data_manager.h" +#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" + +namespace ukm { +class UkmRecorderImpl; +} + +namespace segmentation_platform { +class UkmDataManager; +class UkmObserver; + +// Provides UKM functionality to the segmentation platform service(s). +class UkmDatabaseClient { + public: + UkmDatabaseClient(); + ~UkmDatabaseClient(); + + UkmDatabaseClient(const UkmDatabaseClient&) = delete; + UkmDatabaseClient& operator=(const UkmDatabaseClient&) = delete; + + // Must be called before any profiles (segmentation services) are created. + // `in_memory_database` is used in tests only to create in memory databases to + // make tests faster. + void PreProfileInit(bool in_memory_database); + + void StartObservation(); + + // Must be called after profiles are destroyed, but before metrics service is + // destroyed. + void PostMessageLoopRun(); + + // UkmDataManager will be valid for the lifetime of all the profiles. It is + // created before profiles are created at startup. It is safe to use this + // pointer till ProfileManagerDestroying() is called. + segmentation_platform::UkmDataManager* GetUkmDataManager(); + + // UKM observer will use the test recorder to observe metrics. + void set_ukm_recorder_for_testing(ukm::UkmRecorderImpl* ukm_recorder) { + DCHECK(!ukm_observer_); + ukm_recorder_for_testing_ = ukm_recorder; + } + + UkmObserver* ukm_observer_for_testing() { return ukm_observer_.get(); } + + void TearDownForTesting(); + + private: + raw_ptr<ukm::UkmRecorderImpl> ukm_recorder_for_testing_; + std::unique_ptr<UkmObserver> ukm_observer_; + std::unique_ptr<UkmDataManager> ukm_data_manager_; +}; + +// Class to own the UkmDatabaseClient. Supports overriding instances in tests. +class UkmDatabaseClientHolder { + public: + // Always returns the main client instance, unless a client was set for + // testing. Can be called with nullptr to get the main instance when `profile` + // is not created. + static UkmDatabaseClient& GetClientInstance(ChromeBrowserState* profile); + + // Sets or removes the instance used by `profile` for testing. Thread safe, + // and GetClientInstance() will return the new client based on the profile. + // Note that if GetClientInstance() is called with nullptr, the main instance + // will still be returned. + static void SetUkmClientForTesting(ChromeBrowserState* profile, + UkmDatabaseClient* client); + + UkmDatabaseClientHolder(const UkmDatabaseClientHolder&) = delete; + UkmDatabaseClientHolder& operator=(const UkmDatabaseClientHolder&) = delete; + + private: + friend base::NoDestructor<UkmDatabaseClientHolder>; + + static UkmDatabaseClientHolder& GetInstance(); + UkmDatabaseClientHolder(); + ~UkmDatabaseClientHolder(); + + void SetUkmClientForTestingInternal(ChromeBrowserState* profile, + UkmDatabaseClient* client); + + base::Lock lock_; + std::map<raw_ptr<ChromeBrowserState>, raw_ptr<UkmDatabaseClient>> + clients_for_testing_ GUARDED_BY(lock_); + + std::unique_ptr<UkmDatabaseClient> main_client_; +}; + +} // namespace segmentation_platform + +#endif // IOS_CHROME_BROWSER_SEGMENTATION_PLATFORM_MODEL_UKM_DATABASE_CLIENT_H_
diff --git a/ios/chrome/browser/segmentation_platform/model/ukm_database_client.mm b/ios/chrome/browser/segmentation_platform/model/ukm_database_client.mm new file mode 100644 index 0000000..59da46f5 --- /dev/null +++ b/ios/chrome/browser/segmentation_platform/model/ukm_database_client.mm
@@ -0,0 +1,131 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/segmentation_platform/model/ukm_database_client.h" + +#import <utility> + +#import "base/check_is_test.h" +#import "base/feature_list.h" +#import "base/no_destructor.h" +#import "base/path_service.h" +#import "components/metrics_services_manager/metrics_services_manager.h" +#import "components/segmentation_platform/internal/dummy_ukm_data_manager.h" +#import "components/segmentation_platform/internal/signals/ukm_observer.h" +#import "components/segmentation_platform/internal/ukm_data_manager_impl.h" +#import "components/segmentation_platform/public/features.h" +#import "components/segmentation_platform/public/local_state_helper.h" +#import "components/ukm/ukm_service.h" +#import "ios/chrome/browser/shared/model/application_context/application_context.h" +#import "ios/chrome/browser/shared/model/paths/paths.h" + +namespace segmentation_platform { + +UkmDatabaseClient::UkmDatabaseClient() { + if (base::FeatureList::IsEnabled( + segmentation_platform::features::kSegmentationPlatformUkmEngine)) { + ukm_data_manager_ = std::make_unique<UkmDataManagerImpl>(); + } else { + ukm_data_manager_ = std::make_unique<DummyUkmDataManager>(); + } +} + +UkmDatabaseClient::~UkmDatabaseClient() = default; + +UkmDataManager* UkmDatabaseClient::GetUkmDataManager() { + CHECK(ukm_data_manager_); + return ukm_data_manager_.get(); +} + +void UkmDatabaseClient::PreProfileInit(bool in_memory_database) { + segmentation_platform::LocalStateHelper::GetInstance().Initialize( + GetApplicationContext()->GetLocalState()); + + // Path service is setup at early startup. + base::FilePath local_data_dir; + bool result = base::PathService::Get(ios::DIR_USER_DATA, &local_data_dir); + DCHECK(result); + ukm_data_manager_->Initialize( + local_data_dir.Append(FILE_PATH_LITERAL("segmentation_platform/ukm_db")), + in_memory_database); +} + +void UkmDatabaseClient::TearDownForTesting() { + ukm_data_manager_.reset(); + ukm_observer_.reset(); + ukm_recorder_for_testing_ = nullptr; +} + +void UkmDatabaseClient::StartObservation() { + CHECK(!ukm_observer_); + if (ukm_recorder_for_testing_) { + CHECK_IS_TEST(); + ukm_observer_ = std::make_unique<UkmObserver>(ukm_recorder_for_testing_); + } else { + ukm_observer_ = std::make_unique<UkmObserver>( + GetApplicationContext()->GetMetricsServicesManager()->GetUkmService()); + } + ukm_data_manager_->StartObservation(ukm_observer_.get()); +} + +void UkmDatabaseClient::PostMessageLoopRun() { + // UkmService is destroyed in ApplicationContextImpl::StartTearDown(), which + // happens after all the extra main parts get PostMainMessageLoopRun(). So, it + // is safe to stop the observer here. The profiles can still be active and + // UkmDataManager needs to be available. This does not tear down the + // UkmDataManager, but only stops observing UKM. + if (ukm_observer_) { + // Some of the content browser implementations do not invoke + // PreProfileInit(). + ukm_observer_->StopObserving(); + ukm_observer_ = nullptr; + } +} + +// static +UkmDatabaseClientHolder& UkmDatabaseClientHolder::GetInstance() { + static base::NoDestructor<UkmDatabaseClientHolder> instance; + return *instance; +} + +// static +UkmDatabaseClient& UkmDatabaseClientHolder::GetClientInstance( + ChromeBrowserState* profile) { + UkmDatabaseClientHolder& instance = GetInstance(); + base::AutoLock l(instance.lock_); + if (!instance.clients_for_testing_.empty()) { + CHECK_IS_TEST(); + CHECK(profile); + CHECK(instance.clients_for_testing_.count(profile)); + return *instance.clients_for_testing_[profile]; + } + return *instance.main_client_; +} + +// static +void UkmDatabaseClientHolder::SetUkmClientForTesting( + ChromeBrowserState* profile, + UkmDatabaseClient* client) { + UkmDatabaseClientHolder& instance = GetInstance(); + instance.SetUkmClientForTestingInternal(profile, client); +} + +UkmDatabaseClientHolder::UkmDatabaseClientHolder() + : main_client_(std::make_unique<UkmDatabaseClient>()) {} + +UkmDatabaseClientHolder::~UkmDatabaseClientHolder() = default; + +void UkmDatabaseClientHolder::SetUkmClientForTestingInternal( + ChromeBrowserState* profile, + UkmDatabaseClient* client) { + base::AutoLock l(lock_); + CHECK(profile); + if (client) { + clients_for_testing_[profile] = client; + } else { + clients_for_testing_.erase(profile); + } +} + +} // namespace segmentation_platform
diff --git a/ios/chrome/browser/settings/model/sync/utils/BUILD.gn b/ios/chrome/browser/settings/model/sync/utils/BUILD.gn index 91aaa2d..23a842a 100644 --- a/ios/chrome/browser/settings/model/sync/utils/BUILD.gn +++ b/ios/chrome/browser/settings/model/sync/utils/BUILD.gn
@@ -83,9 +83,11 @@ "//components/bookmarks/common", "//components/browser_sync:switches", "//components/sync/base", + "//ios/chrome/browser/shared/ui/table_view:constants", "//ios/chrome/browser/signin/model:fake_system_identity", "//ios/chrome/browser/ui/authentication:eg_test_support+eg2", "//ios/chrome/browser/ui/bookmarks:eg_test_support+eg2", + "//ios/chrome/browser/ui/reading_list:eg_test_support+eg2", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/chrome/test/earl_grey:switches", "//ios/testing/earl_grey:eg_test_support+eg2",
diff --git a/ios/chrome/browser/settings/model/sync/utils/sync_fake_server_egtest.mm b/ios/chrome/browser/settings/model/sync/utils/sync_fake_server_egtest.mm index 4230489b..88174247 100644 --- a/ios/chrome/browser/settings/model/sync/utils/sync_fake_server_egtest.mm +++ b/ios/chrome/browser/settings/model/sync/utils/sync_fake_server_egtest.mm
@@ -10,10 +10,13 @@ #import "components/browser_sync/browser_sync_switches.h" #import "components/sync/base/command_line_switches.h" #import "components/sync/base/features.h" +#import "ios/chrome/browser/shared/ui/table_view/table_view_navigation_controller_constants.h" #import "ios/chrome/browser/signin/model/fake_system_identity.h" #import "ios/chrome/browser/ui/authentication/signin_earl_grey.h" #import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_earl_grey.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_app_interface.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_egtest_utils.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/test_switches.h" @@ -58,11 +61,14 @@ void ClearRelevantData() { [BookmarkEarlGrey clearBookmarks]; + GREYAssertNil([ReadingListAppInterface clearEntries], + @"Unable to clear Reading List entries"); [ChromeEarlGrey clearFakeSyncServerData]; WaitForEntitiesOnFakeServer(0, syncer::AUTOFILL_PROFILE); WaitForEntitiesOnFakeServer(0, syncer::BOOKMARKS); WaitForEntitiesOnFakeServer(0, syncer::HISTORY); + WaitForEntitiesOnFakeServer(0, syncer::READING_LIST); } } // namespace @@ -495,13 +501,24 @@ NSString* const kBookmarkUrl = @"https://www.goo.com/"; NSString* const kBookmarkTitle = @"Goo"; + + NSString* const kReadingListUrl = @"https://www.rl.com/"; + NSString* const kReadingListTitle = @"RL"; + // Create some data and wait for it to arrive on the server. [BookmarkEarlGrey addBookmarkWithTitle:kBookmarkTitle URL:kBookmarkUrl inStorage:bookmarks::StorageType::kLocalOrSyncable]; + GREYAssertNil([ReadingListAppInterface + addEntryWithURL:[NSURL URLWithString:kReadingListUrl] + title:kReadingListTitle + read:YES], + @"Unable to add Reading List item"); + WaitForEntitiesOnFakeServer(1, syncer::BOOKMARKS); - // TODO(crbug.com/1486420): Also add a password and a reading list entry. + WaitForEntitiesOnFakeServer(1, syncer::READING_LIST); + // TODO(crbug.com/1486420): Also add a password. // Restart Chrome with UNO phase 2 enabled. [self relaunchWithIdentity:fakeIdentity @@ -541,6 +558,22 @@ name:kBookmarkTitle inStorage:bookmarks::StorageType::kAccount]; + // The reading list item should still exist, and *not* have a crossed-cloud + // icon (no crossed-cloud icon means that it's in the account store). + reading_list_test_utils::OpenReadingList(); + [[EarlGrey + selectElementWithMatcher:reading_list_test_utils::VisibleReadingListItem( + kReadingListTitle)] + assertWithMatcher:grey_notNil()]; + [[EarlGrey + selectElementWithMatcher:reading_list_test_utils::VisibleLocalItemIcon( + kReadingListTitle)] + assertWithMatcher:grey_nil()]; + // Close the Reading List. + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + kTableViewNavigationDismissButtonId)] + performAction:grey_tap()]; + // The sync machinery should still be functional: Add an account bookmarks // and ensure it arrives on the server. [BookmarkEarlGrey addBookmarkWithTitle:@"Second bookmark"
diff --git a/ios/chrome/browser/shared/model/prefs/BUILD.gn b/ios/chrome/browser/shared/model/prefs/BUILD.gn index 6a46886..fdd3c6bf3 100644 --- a/ios/chrome/browser/shared/model/prefs/BUILD.gn +++ b/ios/chrome/browser/shared/model/prefs/BUILD.gn
@@ -116,6 +116,7 @@ "//ios/chrome/browser/voice/model:prefs", "//ios/chrome/browser/web/model", "//ios/chrome/browser/web/model/font_size", + "//ios/components/cookie_util:constants", "//ios/web/common:features", "//ui/base", ]
diff --git a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm index fef75e5..04cc6a2 100644 --- a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm +++ b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm
@@ -101,6 +101,7 @@ #import "ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h" #import "ios/chrome/browser/voice/model/voice_search_prefs_registration.h" #import "ios/chrome/browser/web/model/font_size/font_size_tab_helper.h" +#import "ios/components/cookie_util/cookie_constants.h" #import "ios/web/common/features.h" #import "ui/base/l10n/l10n_util.h" @@ -214,6 +215,23 @@ [defaults removeObjectForKey:key]; } +// Helper function migrating the preference `pref_name` of type "int" from +// `defaults` to `pref_service` and to transform the "int" into "base::Time". +void MigrateIntegerToTimePreferenceFromUserDefaults(std::string_view pref_name, + PrefService* pref_service, + NSUserDefaults* defaults) { + NSString* key = @(pref_name.data()); + NSNumber* value = + base::apple::ObjCCast<NSNumber>([defaults objectForKey:key]); + if (!value) { + return; + } + + pref_service->SetTime(pref_name.data(), + base::Time::FromTimeT([value intValue])); + [defaults removeObjectForKey:key]; +} + // Helper function migrating the preference `pref_name` of type "NSDate" from // `defaults` to `pref_service`. void MigrateNSDatePreferenceFromUserDefaults(std::string_view pref_name, @@ -679,6 +697,8 @@ registry->RegisterIntegerPref(prefs::kNotificationsPromoTimesDismissed, 0); registry->RegisterBooleanPref(prefs::kInsecureFormWarningsEnabled, true); + + registry->RegisterTimePref(kLastCookieDeletionDate, base::Time()); } // This method should be periodically pruned of year+ old migrations. @@ -861,6 +881,10 @@ // Added 12/2023. prefs->ClearPref(kSigninLastAccounts); prefs->ClearPref(kSigninLastAccountsMigrated); + + // Added 12/2023. + MigrateIntegerToTimePreferenceFromUserDefaults(kLastCookieDeletionDate, prefs, + defaults); } void MigrateObsoleteUserDefault() {
diff --git a/ios/chrome/browser/sync/model/BUILD.gn b/ios/chrome/browser/sync/model/BUILD.gn index 864ef6b..efec455 100644 --- a/ios/chrome/browser/sync/model/BUILD.gn +++ b/ios/chrome/browser/sync/model/BUILD.gn
@@ -10,8 +10,6 @@ "enterprise_utils.h", "ios_chrome_sync_client.h", "ios_chrome_sync_client.mm", - "ios_chrome_synced_tab_delegate.h", - "ios_chrome_synced_tab_delegate.mm", "ios_user_event_service_factory.cc", "ios_user_event_service_factory.h", "send_tab_to_self_sync_service_factory.h", @@ -87,15 +85,13 @@ "//ios/chrome/browser/signin/model", "//ios/chrome/browser/supervised_user/model:sync_settings_factory", "//ios/chrome/browser/sync/model/glue", - "//ios/chrome/browser/sync/model/sessions", "//ios/chrome/browser/tabs/model", + "//ios/chrome/browser/tabs/model:synced_tabs", "//ios/chrome/browser/trusted_vault/model", "//ios/chrome/browser/webdata_services/model", "//ios/chrome/common", "//ios/components/webui:url_constants", "//ios/web", - "//ios/web/common:features", - "//ios/web/public/session", "//net", "//ui/base", "//url", @@ -106,7 +102,6 @@ "//ios/chrome/browser/reading_list/model", "//ios/chrome/browser/signin/model", "//ios/chrome/browser/sync/model/glue", - "//ios/chrome/browser/sync/model/sessions", ] } @@ -169,7 +164,6 @@ source_set("unit_tests") { testonly = true sources = [ - "ios_chrome_synced_tab_delegate_unittest.mm", "session_sync_service_factory_unittest.cc", "sync_service_factory_unittest.cc", ]
diff --git a/ios/chrome/browser/sync/model/session_sync_service_factory.mm b/ios/chrome/browser/sync/model/session_sync_service_factory.mm index 89cfcd3a..6692e3e 100644 --- a/ios/chrome/browser/sync/model/session_sync_service_factory.mm +++ b/ios/chrome/browser/sync/model/session_sync_service_factory.mm
@@ -29,7 +29,7 @@ #import "ios/chrome/browser/sync/model/device_info_sync_service_factory.h" #import "ios/chrome/browser/sync/model/glue/sync_start_util.h" #import "ios/chrome/browser/sync/model/model_type_store_service_factory.h" -#import "ios/chrome/browser/sync/model/sessions/ios_chrome_local_session_event_router.h" +#import "ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.h" #import "ios/chrome/browser/tabs/model/ios_synced_window_delegate_getter.h" #import "ios/chrome/common/channel_info.h" #import "ios/components/webui/web_ui_url_constants.h"
diff --git a/ios/chrome/browser/sync/model/sessions/BUILD.gn b/ios/chrome/browser/sync/model/sessions/BUILD.gn deleted file mode 100644 index 59ec44eb..0000000 --- a/ios/chrome/browser/sync/model/sessions/BUILD.gn +++ /dev/null
@@ -1,24 +0,0 @@ -# Copyright 2016 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("sessions") { - sources = [ - "ios_chrome_local_session_event_router.h", - "ios_chrome_local_session_event_router.mm", - ] - deps = [ - "//base", - "//components/history/core/browser", - "//components/keyed_service/core", - "//components/sync", - "//components/sync_sessions", - "//ios/chrome/browser/history/model", - "//ios/chrome/browser/shared/model/browser", - "//ios/chrome/browser/shared/model/browser_state", - "//ios/chrome/browser/shared/model/web_state_list", - "//ios/chrome/browser/sync/model/glue", - "//ios/chrome/browser/tabs/model", - "//ios/web", - ] -}
diff --git a/ios/chrome/browser/tabs/model/BUILD.gn b/ios/chrome/browser/tabs/model/BUILD.gn index ddad322..61a450ff 100644 --- a/ios/chrome/browser/tabs/model/BUILD.gn +++ b/ios/chrome/browser/tabs/model/BUILD.gn
@@ -38,6 +38,7 @@ ] deps = [ ":model", + ":synced_tabs", "//base", "//components/autofill/ios/form_util", "//components/breadcrumbs/core:status", @@ -140,9 +141,41 @@ ] } +source_set("synced_tabs") { + sources = [ + "ios_chrome_local_session_event_router.h", + "ios_chrome_local_session_event_router.mm", + "ios_chrome_synced_tab_delegate.h", + "ios_chrome_synced_tab_delegate.mm", + ] + deps = [ + ":model", + "//base", + "//components/history/core/browser", + "//components/keyed_service/core", + "//components/sessions", + "//components/sessions:session_id", + "//components/sync/base:features", + "//components/sync/model", + "//components/sync_sessions", + "//ios/chrome/browser/complex_tasks/model", + "//ios/chrome/browser/history/model", + "//ios/chrome/browser/sessions", + "//ios/chrome/browser/shared/model/browser", + "//ios/chrome/browser/shared/model/web_state_list", + "//ios/chrome/browser/sync/model/glue", + "//ios/web/common:features", + "//ios/web/public", + "//ios/web/public:web_state_observer", + "//ios/web/public/navigation", + "//ios/web/public/session", + ] +} + source_set("unit_tests") { testonly = true sources = [ + "ios_chrome_synced_tab_delegate_unittest.mm", "tab_helper_delegate_installer_unittest.mm", "tab_sync_util_unittest.mm", "tab_title_util_unittest.mm", @@ -150,6 +183,7 @@ ] deps = [ ":model", + ":synced_tabs", ":tab_sync_util", ":tabs_internal", "//base",
diff --git a/ios/chrome/browser/tabs/model/DEPS b/ios/chrome/browser/tabs/model/DEPS index 8d7be08..c8abb5ea 100644 --- a/ios/chrome/browser/tabs/model/DEPS +++ b/ios/chrome/browser/tabs/model/DEPS
@@ -1,11 +1,13 @@ include_rules = [ - "+ios/chrome/browser/sessions", - "+ios/chrome/browser/sync/model", - "+ios/chrome/browser/synced_sessions/model", - "+ios/chrome/browser/snapshots/model", + "+ios/chrome/browser/complex_tasks/model", "+ios/chrome/browser/download/model/download_manager_tab_helper.h", + "+ios/chrome/browser/history/model", "+ios/chrome/browser/main/model/browser_util.h", "+ios/chrome/browser/ntp/model/new_tab_page_util.h", + "+ios/chrome/browser/sessions", + "+ios/chrome/browser/snapshots/model", + "+ios/chrome/browser/sync/model", + "+ios/chrome/browser/synced_sessions/model", ] specific_include_rules = {
diff --git a/ios/chrome/browser/sync/model/sessions/ios_chrome_local_session_event_router.h b/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.h similarity index 92% rename from ios/chrome/browser/sync/model/sessions/ios_chrome_local_session_event_router.h rename to ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.h index 356d1016..155c524 100644 --- a/ios/chrome/browser/sync/model/sessions/ios_chrome_local_session_event_router.h +++ b/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_SYNC_MODEL_SESSIONS_IOS_CHROME_LOCAL_SESSION_EVENT_ROUTER_H_ -#define IOS_CHROME_BROWSER_SYNC_MODEL_SESSIONS_IOS_CHROME_LOCAL_SESSION_EVENT_ROUTER_H_ +#ifndef IOS_CHROME_BROWSER_TABS_MODEL_IOS_CHROME_LOCAL_SESSION_EVENT_ROUTER_H_ +#define IOS_CHROME_BROWSER_TABS_MODEL_IOS_CHROME_LOCAL_SESSION_EVENT_ROUTER_H_ #include <stddef.h> @@ -103,4 +103,4 @@ int batch_in_progress_ = 0; }; -#endif // IOS_CHROME_BROWSER_SYNC_MODEL_SESSIONS_IOS_CHROME_LOCAL_SESSION_EVENT_ROUTER_H_ +#endif // IOS_CHROME_BROWSER_TABS_MODEL_IOS_CHROME_LOCAL_SESSION_EVENT_ROUTER_H_
diff --git a/ios/chrome/browser/sync/model/sessions/ios_chrome_local_session_event_router.mm b/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.mm similarity index 97% rename from ios/chrome/browser/sync/model/sessions/ios_chrome_local_session_event_router.mm rename to ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.mm index dcf8f91..aacec6d48 100644 --- a/ios/chrome/browser/sync/model/sessions/ios_chrome_local_session_event_router.mm +++ b/ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/sync/model/sessions/ios_chrome_local_session_event_router.h" +#import "ios/chrome/browser/tabs/model/ios_chrome_local_session_event_router.h" #import <stddef.h> @@ -18,7 +18,7 @@ #import "ios/chrome/browser/shared/model/browser/browser_list.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" #import "ios/chrome/browser/sync/model/glue/sync_start_util.h" -#import "ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate.h" +#import "ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h" #import "ios/chrome/browser/tabs/model/tab_parenting_global_observer.h" namespace {
diff --git a/ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate.h b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h similarity index 93% rename from ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate.h rename to ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h index 03fa5bc..dc20395 100644 --- a/ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate.h +++ b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_SYNC_MODEL_IOS_CHROME_SYNCED_TAB_DELEGATE_H_ -#define IOS_CHROME_BROWSER_SYNC_MODEL_IOS_CHROME_SYNCED_TAB_DELEGATE_H_ +#ifndef IOS_CHROME_BROWSER_TABS_MODEL_IOS_CHROME_SYNCED_TAB_DELEGATE_H_ +#define IOS_CHROME_BROWSER_TABS_MODEL_IOS_CHROME_SYNCED_TAB_DELEGATE_H_ #include <memory> #include <string> @@ -70,4 +70,4 @@ WEB_STATE_USER_DATA_KEY_DECL(); }; -#endif // IOS_CHROME_BROWSER_SYNC_MODEL_IOS_CHROME_SYNCED_TAB_DELEGATE_H_ +#endif // IOS_CHROME_BROWSER_TABS_MODEL_IOS_CHROME_SYNCED_TAB_DELEGATE_H_
diff --git a/ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate.mm b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.mm similarity index 99% rename from ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate.mm rename to ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.mm index 3f60f760..365730f 100644 --- a/ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate.mm +++ b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate.h" +#import "ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h" #import "base/check.h" #import "components/sessions/ios/ios_serialized_navigation_builder.h"
diff --git a/ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate_unittest.mm b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate_unittest.mm similarity index 94% rename from ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate_unittest.mm rename to ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate_unittest.mm index f4dd443..d137779f 100644 --- a/ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate_unittest.mm +++ b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate_unittest.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate.h" +#import "ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h" #import <memory>
diff --git a/ios/chrome/browser/tabs/model/synced_window_delegate_browser_agent.mm b/ios/chrome/browser/tabs/model/synced_window_delegate_browser_agent.mm index a879331e..43a6bf1 100644 --- a/ios/chrome/browser/tabs/model/synced_window_delegate_browser_agent.mm +++ b/ios/chrome/browser/tabs/model/synced_window_delegate_browser_agent.mm
@@ -8,7 +8,7 @@ #import "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" -#import "ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate.h" +#import "ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h" #import "ios/web/public/navigation/navigation_manager.h" BROWSER_USER_DATA_KEY_IMPL(SyncedWindowDelegateBrowserAgent)
diff --git a/ios/chrome/browser/tabs/model/tab_helper_util.mm b/ios/chrome/browser/tabs/model/tab_helper_util.mm index abd3b7c..87b9952 100644 --- a/ios/chrome/browser/tabs/model/tab_helper_util.mm +++ b/ios/chrome/browser/tabs/model/tab_helper_util.mm
@@ -83,7 +83,7 @@ #import "ios/chrome/browser/ssl/model/captive_portal_tab_helper.h" #import "ios/chrome/browser/supervised_user/model/supervised_user_error_container.h" #import "ios/chrome/browser/supervised_user/model/supervised_user_url_filter_tab_helper.h" -#import "ios/chrome/browser/sync/model/ios_chrome_synced_tab_delegate.h" +#import "ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h" #import "ios/chrome/browser/translate/model/chrome_ios_translate_client.h" #import "ios/chrome/browser/voice/model/voice_search_navigations_tab_helper.h" #import "ios/chrome/browser/web/model/annotations/annotations_tab_helper.h"
diff --git a/ios/chrome/browser/ui/account_picker/account_picker_confirmation/BUILD.gn b/ios/chrome/browser/ui/account_picker/account_picker_confirmation/BUILD.gn index 124630a7..439de98 100644 --- a/ios/chrome/browser/ui/account_picker/account_picker_confirmation/BUILD.gn +++ b/ios/chrome/browser/ui/account_picker/account_picker_confirmation/BUILD.gn
@@ -4,8 +4,6 @@ source_set("account_picker_confirmation") { sources = [ - "account_picker_confirmation_screen_constants.h", - "account_picker_confirmation_screen_constants.mm", "account_picker_confirmation_screen_consumer.h", "account_picker_confirmation_screen_coordinator.h", "account_picker_confirmation_screen_coordinator.mm", @@ -16,6 +14,7 @@ "account_picker_confirmation_screen_view_controller.mm", ] deps = [ + ":constants", "//base", "//components/signin/public/base", "//components/signin/public/identity_manager", @@ -42,3 +41,10 @@ "//ui/base", ] } + +source_set("constants") { + sources = [ + "account_picker_confirmation_screen_constants.h", + "account_picker_confirmation_screen_constants.mm", + ] +}
diff --git a/ios/chrome/browser/ui/download/BUILD.gn b/ios/chrome/browser/ui/download/BUILD.gn index eb2aed0..eb32fca 100644 --- a/ios/chrome/browser/ui/download/BUILD.gn +++ b/ios/chrome/browser/ui/download/BUILD.gn
@@ -6,8 +6,6 @@ sources = [ "ar_quick_look_coordinator.h", "ar_quick_look_coordinator.mm", - "download_manager_animation_constants.h", - "download_manager_animation_constants.mm", "download_manager_consumer.h", "download_manager_coordinator.h", "download_manager_coordinator.mm", @@ -34,6 +32,7 @@ "vcard_coordinator.mm", ] deps = [ + ":constants", ":features", "resources:background_compact", "resources:background_regular", @@ -84,6 +83,13 @@ ] } +source_set("constants") { + sources = [ + "download_manager_constants.h", + "download_manager_constants.mm", + ] +} + source_set("unit_tests") { testonly = true sources = [
diff --git a/ios/chrome/browser/ui/download/download_manager_animation_constants.h b/ios/chrome/browser/ui/download/download_manager_animation_constants.h deleted file mode 100644 index 22eee08..0000000 --- a/ios/chrome/browser/ui/download/download_manager_animation_constants.h +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_DOWNLOAD_DOWNLOAD_MANAGER_ANIMATION_CONSTANTS_H_ -#define IOS_CHROME_BROWSER_UI_DOWNLOAD_DOWNLOAD_MANAGER_ANIMATION_CONSTANTS_H_ - -#import <Foundation/Foundation.h> - -// Duration for all animations used in Download Manager. -extern const NSTimeInterval kDownloadManagerAnimationDuration; - -#endif // IOS_CHROME_BROWSER_UI_DOWNLOAD_DOWNLOAD_MANAGER_ANIMATION_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/download/download_manager_animation_constants.mm b/ios/chrome/browser/ui/download/download_manager_animation_constants.mm deleted file mode 100644 index c9d035f..0000000 --- a/ios/chrome/browser/ui/download/download_manager_animation_constants.mm +++ /dev/null
@@ -1,7 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/download/download_manager_animation_constants.h" - -const NSTimeInterval kDownloadManagerAnimationDuration = 0.2;
diff --git a/ios/chrome/browser/ui/download/download_manager_constants.h b/ios/chrome/browser/ui/download/download_manager_constants.h new file mode 100644 index 0000000..15c9ce3 --- /dev/null +++ b/ios/chrome/browser/ui/download/download_manager_constants.h
@@ -0,0 +1,18 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_DOWNLOAD_DOWNLOAD_MANAGER_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_UI_DOWNLOAD_DOWNLOAD_MANAGER_CONSTANTS_H_ + +#import <Foundation/Foundation.h> + +extern NSString* const kDownloadManagerDownloadToFilesAccessibilityIdentifier; +extern NSString* const kDownloadManagerDownloadToDriveAccessibilityIdentifier; +extern NSString* const kDownloadManagerOpenInAccessibilityIdentifier; +extern NSString* const kDownloadManagerTryAgainAccessibilityIdentifier; + +// Duration for all animations used in Download Manager. +extern const NSTimeInterval kDownloadManagerAnimationDuration; + +#endif // IOS_CHROME_BROWSER_UI_DOWNLOAD_DOWNLOAD_MANAGER_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/download/download_manager_constants.mm b/ios/chrome/browser/ui/download/download_manager_constants.mm new file mode 100644 index 0000000..143b8ac --- /dev/null +++ b/ios/chrome/browser/ui/download/download_manager_constants.mm
@@ -0,0 +1,16 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/download/download_manager_constants.h" + +NSString* const kDownloadManagerDownloadToFilesAccessibilityIdentifier = + @"kDownloadManagerDownloadToFilesAccessibilityIdentifier"; +NSString* const kDownloadManagerDownloadToDriveAccessibilityIdentifier = + @"kDownloadManagerDownloadToDriveAccessibilityIdentifier"; +NSString* const kDownloadManagerOpenInAccessibilityIdentifier = + @"kDownloadManagerOpenInAccessibilityIdentifier"; +NSString* const kDownloadManagerTryAgainAccessibilityIdentifier = + @"kDownloadManagerTryAgainAccessibilityIdentifier"; + +const NSTimeInterval kDownloadManagerAnimationDuration = 0.2;
diff --git a/ios/chrome/browser/ui/download/download_manager_view_controller.mm b/ios/chrome/browser/ui/download/download_manager_view_controller.mm index 9652e61ae..d648d3da 100644 --- a/ios/chrome/browser/ui/download/download_manager_view_controller.mm +++ b/ios/chrome/browser/ui/download/download_manager_view_controller.mm
@@ -10,6 +10,7 @@ #import "ios/chrome/browser/shared/ui/symbols/symbols.h" #import "ios/chrome/browser/shared/ui/util/layout_guide_names.h" #import "ios/chrome/browser/shared/ui/util/util_swift.h" +#import "ios/chrome/browser/ui/download/download_manager_constants.h" #import "ios/chrome/browser/ui/download/download_manager_view_controller_delegate.h" #import "ios/chrome/browser/ui/download/features.h" #import "ios/chrome/browser/ui/download/radial_progress_view.h" @@ -443,6 +444,8 @@ setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis: UILayoutConstraintAxisHorizontal]; + _downloadToFilesButton.accessibilityIdentifier = + kDownloadManagerDownloadToFilesAccessibilityIdentifier; } return _downloadToFilesButton; @@ -469,6 +472,8 @@ setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis: UILayoutConstraintAxisHorizontal]; + _downloadToDriveButton.accessibilityIdentifier = + kDownloadManagerDownloadToDriveAccessibilityIdentifier; } return _downloadToDriveButton; @@ -520,6 +525,8 @@ setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis: UILayoutConstraintAxisHorizontal]; + _openInButton.accessibilityIdentifier = + kDownloadManagerOpenInAccessibilityIdentifier; } return _openInButton; @@ -543,6 +550,8 @@ setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis: UILayoutConstraintAxisHorizontal]; + _tryAgainButton.accessibilityIdentifier = + kDownloadManagerTryAgainAccessibilityIdentifier; } return _tryAgainButton;
diff --git a/ios/chrome/browser/ui/download/legacy_download_manager_view_controller.mm b/ios/chrome/browser/ui/download/legacy_download_manager_view_controller.mm index 5ffc9c7..88f467d 100644 --- a/ios/chrome/browser/ui/download/legacy_download_manager_view_controller.mm +++ b/ios/chrome/browser/ui/download/legacy_download_manager_view_controller.mm
@@ -13,7 +13,7 @@ #import "ios/chrome/browser/shared/ui/symbols/symbols.h" #import "ios/chrome/browser/shared/ui/util/layout_guide_names.h" #import "ios/chrome/browser/shared/ui/util/util_swift.h" -#import "ios/chrome/browser/ui/download/download_manager_animation_constants.h" +#import "ios/chrome/browser/ui/download/download_manager_constants.h" #import "ios/chrome/browser/ui/download/download_manager_state_view.h" #import "ios/chrome/browser/ui/download/download_manager_view_controller_delegate.h" #import "ios/chrome/browser/ui/download/features.h" @@ -797,23 +797,29 @@ // Updates title and hidden state for action button depending on `state`. - (void)updateActionButton { NSString* title = nil; + NSString* accessibilityIdentifier = nil; switch (_state) { case kDownloadManagerStateNotStarted: title = l10n_util::GetNSString(IDS_IOS_DOWNLOAD_MANAGER_DOWNLOAD); + accessibilityIdentifier = + kDownloadManagerDownloadToFilesAccessibilityIdentifier; break; case kDownloadManagerStateInProgress: break; case kDownloadManagerStateSucceeded: title = l10n_util::GetNSString(IDS_IOS_OPEN_IN); + accessibilityIdentifier = kDownloadManagerOpenInAccessibilityIdentifier; break; case kDownloadManagerStateFailed: title = l10n_util::GetNSString(IDS_IOS_DOWNLOAD_MANAGER_TRY_AGAIN); + accessibilityIdentifier = kDownloadManagerTryAgainAccessibilityIdentifier; break; case kDownloadManagerStateFailedNotResumable: break; } [self.actionButton setTitle:title forState:UIControlStateNormal]; + [self.actionButton setAccessibilityIdentifier:accessibilityIdentifier]; self.actionButton.hidden = (_state == kDownloadManagerStateInProgress || _state == kDownloadManagerStateFailedNotResumable);
diff --git a/ios/chrome/browser/ui/first_run/omnibox_position/omnibox_position_choice_view_controller.mm b/ios/chrome/browser/ui/first_run/omnibox_position/omnibox_position_choice_view_controller.mm index c35d060..9b5b448 100644 --- a/ios/chrome/browser/ui/first_run/omnibox_position/omnibox_position_choice_view_controller.mm +++ b/ios/chrome/browser/ui/first_run/omnibox_position/omnibox_position_choice_view_controller.mm
@@ -61,6 +61,7 @@ self.hideHeaderOnTallContent = YES; self.headerImageType = PromoStyleImageType::kImageWithShadow; + self.headerViewForceStyleLight = YES; #if BUILDFLAG(IOS_USE_BRANDED_SYMBOLS) UIImage* logo = MakeSymbolMulticolor( CustomSymbolWithPointSize(kMulticolorChromeballSymbol, kLogoSize));
diff --git a/ios/chrome/browser/ui/menu/action_factory.h b/ios/chrome/browser/ui/menu/action_factory.h index 86c9348..6170f45 100644 --- a/ios/chrome/browser/ui/menu/action_factory.h +++ b/ios/chrome/browser/ui/menu/action_factory.h
@@ -126,6 +126,9 @@ - (ProceduralBlock)recordMobileWebContextMenuOpenTabActionWithBlock: (ProceduralBlock)block; +// Creates a UIAction instance for adding a tab in a new tab group. +- (UIAction*)actionToAddTabToNewGroupWithBlock:(ProceduralBlock)block; + @end #endif // IOS_CHROME_BROWSER_UI_MENU_ACTION_FACTORY_H_
diff --git a/ios/chrome/browser/ui/menu/action_factory.mm b/ios/chrome/browser/ui/menu/action_factory.mm index 161786c..3c92a8e 100644 --- a/ios/chrome/browser/ui/menu/action_factory.mm +++ b/ios/chrome/browser/ui/menu/action_factory.mm
@@ -4,6 +4,7 @@ #import "ios/chrome/browser/ui/menu/action_factory.h" +#import "base/check.h" #import "base/metrics/histogram_functions.h" #import "base/metrics/user_metrics.h" #import "ios/chrome/browser/net/model/crurl.h" @@ -338,6 +339,21 @@ }; } +- (UIAction*)actionToAddTabToNewGroupWithBlock:(ProceduralBlock)block { + CHECK(base::FeatureList::IsEnabled(kTabGroupsInGrid)) + << "You should not be able to create a tab group context menu action " + "outside the Tab Groups experiment."; + UIImage* image = DefaultSymbolWithPointSize(kNewTabGroupActionSymbol, + kSymbolActionPointSize); + UIAction* action = + [self actionWithTitle:l10n_util::GetNSString( + IDS_IOS_CONTENT_CONTEXT_ADDTABTONEWTABGROUP) + image:image + type:MenuActionType::AddTabToNewGroup + block:block]; + return action; +} + #pragma mark - Private // Creates a UIAction instance for closing a tab with a provided `title`.
diff --git a/ios/chrome/browser/ui/menu/menu_action_type.h b/ios/chrome/browser/ui/menu/menu_action_type.h index 2c2bdcdf..976f4eb 100644 --- a/ios/chrome/browser/ui/menu/menu_action_type.h +++ b/ios/chrome/browser/ui/menu/menu_action_type.h
@@ -54,7 +54,8 @@ LensCameraSearch = 41, SaveImageToGooglePhotos = 42, CloseAllOtherTabs = 43, - kMaxValue = CloseAllOtherTabs + AddTabToNewGroup = 44, + kMaxValue = AddTabToNewGroup }; // LINT.ThenChange(/tools/metrics/histograms/enums.xml)
diff --git a/ios/chrome/browser/ui/menu/tab_context_menu_delegate.h b/ios/chrome/browser/ui/menu/tab_context_menu_delegate.h index 624199d..2805d2c 100644 --- a/ios/chrome/browser/ui/menu/tab_context_menu_delegate.h +++ b/ios/chrome/browser/ui/menu/tab_context_menu_delegate.h
@@ -58,6 +58,10 @@ // Tells the delegate to unpin a tab with the item identifier `identifier`. - (void)unpinTabWithIdentifier:(web::WebStateID)identifier; +// Tells the delegate to create a new tab group with the given identifier +// `identifier`. +- (void)createNewTabGroupWithIdentifier:(web::WebStateID)identifier; + // Tells the delegate to close the tab with the item identifier `identifier`. // `incognito`tracks the incognito state of the tab. // `pinned` tracks the pinned state of the tab.
diff --git a/ios/chrome/browser/ui/reading_list/BUILD.gn b/ios/chrome/browser/ui/reading_list/BUILD.gn index 6394b62..b77d454 100644 --- a/ios/chrome/browser/ui/reading_list/BUILD.gn +++ b/ios/chrome/browser/ui/reading_list/BUILD.gn
@@ -193,6 +193,7 @@ "//components/reading_list/core", "//components/reading_list/core:test_support", "//components/sync:test_support", + "//components/sync/base", "//components/url_formatter", "//ios/chrome/browser/favicon", "//ios/chrome/browser/feature_engagement/model", @@ -284,6 +285,7 @@ "//base", "//base/test:test_support", "//ios/chrome/app/strings", + "//ios/chrome/common/ui/table_view:cells_constants", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/testing/earl_grey:eg_test_support+eg2", "//ui/base",
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_account_storage_egtest.mm b/ios/chrome/browser/ui/reading_list/reading_list_account_storage_egtest.mm index cfab303..92114ed 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_account_storage_egtest.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_account_storage_egtest.mm
@@ -41,6 +41,7 @@ using reading_list_test_utils::AddURLToReadingList; using reading_list_test_utils::OpenReadingList; using reading_list_test_utils::ReadingListItem; +using reading_list_test_utils::VisibleLocalItemIcon; using reading_list_test_utils::VisibleReadingListItem; namespace { @@ -79,14 +80,6 @@ return grey_accessibilityID(kReadingListAddedToAccountSnackbarUndoID); } -// The cloud slash icon that appears for Reading List items that are only stored -// in the local storage. Shown only for signed-in users. -id<GREYMatcher> VisibleLocalItemIcon(NSString* title) { - return grey_allOf(grey_ancestor(ReadingListItem(title)), - grey_accessibilityID(kTableViewURLCellMetadataImageID), - grey_sufficientlyVisible(), nil); -} - // Provides responses containing a custom title for fake URLs. std::unique_ptr<net::test_server::HttpResponse> StandardResponse( const net::test_server::HttpRequest& request) { @@ -162,6 +155,8 @@ - (AppLaunchConfiguration)appConfigurationForTestCase { AppLaunchConfiguration config; + config.features_enabled.push_back( + syncer::kReadingListEnableSyncTransportModeUponSignIn); if ([self isRunningTest:@selector (testSignInWithSecondaryAccountInPromo_WithSnackbar)] || [self isRunningTest:@selector(testAddAccountItemThenUpgradeToFullSync)] ||
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm index e7b84a6..61d25c3 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
@@ -17,6 +17,7 @@ #import "components/reading_list/features/reading_list_switches.h" #import "components/signin/public/base/signin_pref_names.h" #import "components/signin/public/identity_manager/objc/identity_manager_observer_bridge.h" +#import "components/sync/base/features.h" #import "components/sync/base/user_selectable_type.h" #import "components/sync/service/sync_service.h" #import "components/sync/service/sync_user_settings.h" @@ -637,7 +638,10 @@ // Computes whether the sign-in promo should be visible in the reading list and // updates the view accordingly. - (void)updateSignInPromoVisibility { - if (self.isSyncDisabledByAdministrator) { + BOOL areAccountStorageAndPromoEnabled = + base::FeatureList::IsEnabled( + syncer::kReadingListEnableSyncTransportModeUponSignIn); + if (!areAccountStorageAndPromoEnabled || self.isSyncDisabledByAdministrator) { self.shouldShowSignInPromo = NO; return; }
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_egtest_utils.h b/ios/chrome/browser/ui/reading_list/reading_list_egtest_utils.h index bcc1f12e..17e00e8 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_egtest_utils.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_egtest_utils.h
@@ -22,6 +22,10 @@ // Matcher for the currently visible Reading List item cell with a given title. id<GREYMatcher> VisibleReadingListItem(NSString* entryTitle); +// The cloud slash icon that appears for Reading List items that are only stored +// in the local storage. Shown only for signed-in users. +id<GREYMatcher> VisibleLocalItemIcon(NSString* title); + // Opens the reading list. void OpenReadingList();
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_egtest_utils.mm b/ios/chrome/browser/ui/reading_list/reading_list_egtest_utils.mm index 677be05..ebdb2a5 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_egtest_utils.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_egtest_utils.mm
@@ -6,6 +6,7 @@ #import "ios/chrome/browser/ui/reading_list/reading_list_app_interface.h" #import "ios/chrome/browser/ui/reading_list/reading_list_constants.h" +#import "ios/chrome/common/ui/table_view/table_view_cells_constants.h" #import "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" @@ -34,6 +35,12 @@ grey_sufficientlyVisible(), nil); } +id<GREYMatcher> VisibleLocalItemIcon(NSString* title) { + return grey_allOf(grey_ancestor(ReadingListItem(title)), + grey_accessibilityID(kTableViewURLCellMetadataImageID), + grey_sufficientlyVisible(), nil); +} + // Opens the reading list menu. void OpenReadingList() { [ChromeEarlGreyUI openToolsMenu];
diff --git a/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_table/cells/snippet_search_engine_cell.mm b/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_table/cells/snippet_search_engine_cell.mm index 7e6b3a30..be3d213 100644 --- a/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_table/cells/snippet_search_engine_cell.mm +++ b/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_table/cells/snippet_search_engine_cell.mm
@@ -26,7 +26,10 @@ // Horizontal margin between elements in SnippetSearchEngineCell. constexpr CGFloat kInnerHorizontalMargin = 12.; // Chevron button size. -constexpr CGFloat kChevronButtonSize = 24.; +constexpr CGFloat kChevronButtonSize = 44.; +// Horizontal chevron margin with the separtor, the name label and the snippet +// label. +constexpr CGFloat kChevronButtonHorizontalMargin = 2.; // Thickness of the vertical separator. constexpr CGFloat kSeparatorThickness = 1.; // Duration of the snippet animation when changing state. @@ -148,13 +151,13 @@ constant:kVerticalMargin], [_nameLabel.trailingAnchor constraintLessThanOrEqualToAnchor:_chevronButton.leadingAnchor - constant:-kInnerHorizontalMargin], + constant:-kChevronButtonHorizontalMargin], [_nameLabel.bottomAnchor constraintEqualToAnchor:_snippetLabel.topAnchor], [_snippetLabel.leadingAnchor constraintEqualToAnchor:_nameLabel.leadingAnchor], [_snippetLabel.trailingAnchor constraintLessThanOrEqualToAnchor:_chevronButton.leadingAnchor - constant:-kInnerHorizontalMargin], + constant:-kChevronButtonHorizontalMargin], [_chevronButton.heightAnchor constraintEqualToConstant:kChevronButtonSize], [_chevronButton.widthAnchor constraintEqualToConstant:kChevronButtonSize], @@ -162,7 +165,7 @@ constraintEqualToAnchor:_nameLabel.centerYAnchor], [_chevronButton.trailingAnchor constraintEqualToAnchor:separatorLine.leadingAnchor - constant:-kInnerHorizontalMargin], + constant:-kChevronButtonHorizontalMargin], [separatorLine.heightAnchor constraintEqualToAnchor:_nameLabel.heightAnchor], [separatorLine.centerYAnchor
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller+subclassing.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller+subclassing.h index 02a24eb..4122815 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller+subclassing.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller+subclassing.h
@@ -8,8 +8,6 @@ #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.h" -// TODO(crbug.com/1466000): Remove hard-coding of sections. -extern const int kGridOpenTabsSectionIndex; extern NSString* const kGridOpenTabsSectionIdentifier; // To ease the use of generics with the diffable data source, define a Snapshot
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm index bb4df88c..c47a6871 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm
@@ -67,13 +67,9 @@ }; // Needed for subclassing. -constexpr int kGridOpenTabsSectionIndex = 0; NSString* const kGridOpenTabsSectionIdentifier = @"OpenTabsSectionIdentifier"; namespace { -// TODO(crbug.com/1466000): Remove hard-coding of sections. -constexpr int kSuggestedActionsSectionIndex = 1; - NSString* const kSuggestedActionsSectionIdentifier = @"SuggestedActionsSectionIdentifier"; NSString* const kCellIdentifier = @"GridCellIdentifier"; @@ -315,7 +311,7 @@ } - (BOOL)isGridEmpty { - return self.items.count == 0; + return [self numberOfTabs] == 0; } - (BOOL)isContainedGridEmpty { @@ -359,9 +355,7 @@ NSUInteger selectedIndex = self.selectedIndex; if (previousMode != TabGridModeSelection && mode == TabGridModeNormal && selectedIndex != NSNotFound && - static_cast<NSInteger>(selectedIndex) < - [self.collectionView - numberOfItemsInSection:kGridOpenTabsSectionIndex]) { + static_cast<NSInteger>(selectedIndex) < [self numberOfTabs]) { // Scroll to the selected item here, so the action of reloading and // scrolling happens at once. [self.collectionView @@ -433,8 +427,10 @@ [[NSMutableArray alloc] init]; LegacyGridTransitionActiveItem* activeItem; LegacyGridTransitionItem* selectionItem; + NSInteger tabSectionIndex = [self.diffableDataSource + indexForSectionIdentifier:kGridOpenTabsSectionIdentifier]; for (NSIndexPath* path in self.collectionView.indexPathsForVisibleItems) { - if (path.section != kGridOpenTabsSectionIndex) { + if (path.section != tabSectionIndex) { continue; } GridCell* cell = ObjCCastStrict<GridCell>( @@ -523,7 +519,8 @@ [self updateSelectedCollectionViewItemRingAndBringIntoView:YES]; // Update the delegate, in case it wasn't set when `items` was populated. - [self.delegate gridViewController:self didChangeItemCount:self.items.count]; + [self.delegate gridViewController:self + didChangeItemCount:[self numberOfTabs]]; [self removeEmptyStateAnimated:NO]; self.lastInsertedItemID = web::WebStateID(); } @@ -579,7 +576,7 @@ if ([sectionIdentifier isEqualToString:kGridOpenTabsSectionIdentifier]) { gridHeader.title = l10n_util::GetNSString( IDS_IOS_TABS_SEARCH_OPEN_TABS_SECTION_HEADER_TITLE); - NSString* resultsCount = [@(self.items.count) stringValue]; + NSString* resultsCount = [@([self numberOfTabs]) stringValue]; gridHeader.value = l10n_util::GetNSStringF(IDS_IOS_TABS_SEARCH_OPEN_TABS_COUNT, base::SysNSStringToUTF16(resultsCount)); @@ -676,7 +673,9 @@ } // No context menu on suggested actions section. - if (indexPath.section == kSuggestedActionsSectionIndex) { + if (indexPath.section == + [self.diffableDataSource + indexForSectionIdentifier:kSuggestedActionsSectionIdentifier]) { return nil; } @@ -729,7 +728,9 @@ // `prepareLayout` of the layout class. For that specific cell calculate the // anticipated size from the layout section insets and the content view insets // and return it. - if (indexPath.section == kSuggestedActionsSectionIndex) { + if (indexPath.section == + [self.diffableDataSource + indexForSectionIdentifier:kSuggestedActionsSectionIdentifier]) { UIEdgeInsets sectionInset = layout.sectionInset; UIEdgeInsets contentInset = layout.collectionView.adjustedContentInset; CGFloat width = layout.collectionView.frame.size.width - sectionInset.left - @@ -833,7 +834,9 @@ // TODO(crbug.com/1300369): Enable dragging items from search results. return @[]; } - if (indexPath.section == kSuggestedActionsSectionIndex) { + if (indexPath.section == + [self.diffableDataSource + indexForSectionIdentifier:kSuggestedActionsSectionIdentifier]) { // Return an empty array because ther suggested actions cell should not be // dragged. return @[]; @@ -863,7 +866,9 @@ - (UIDragPreviewParameters*)collectionView:(UICollectionView*)collectionView dragPreviewParametersForItemAtIndexPath:(NSIndexPath*)indexPath { - if (indexPath.section == kSuggestedActionsSectionIndex) { + if (indexPath.section == + [self.diffableDataSource + indexForSectionIdentifier:kSuggestedActionsSectionIdentifier]) { // Return nil so that the suggested actions cell doesn't superpose the // dragged cell. return nil; @@ -909,8 +914,9 @@ // The sourceIndexPath is nil if the drop item is not from the same // collection view. Set the destinationIndex to reflect the addition of an // item. + NSInteger numberOfTabs = [self numberOfTabs]; NSUInteger destinationIndex = - item.sourceIndexPath ? self.items.count - 1 : self.items.count; + item.sourceIndexPath ? numberOfTabs - 1 : numberOfTabs; if (coordinator.destinationIndexPath) { destinationIndex = base::checked_cast<NSUInteger>(coordinator.destinationIndexPath.item); @@ -1295,6 +1301,12 @@ } }]; + if ([self shouldShowEmptyState]) { + [self animateEmptyStateIn]; + } else { + [self removeEmptyStateAnimated:YES]; + } + [self updateVisibleCellIdentifiers]; } @@ -1321,8 +1333,6 @@ self.lastInsertedItemID = item.identifier; [self.delegate gridViewController:self didChangeItemCount:self.items.count]; - [self removeEmptyStateAnimated:YES]; - // TODO(crbug.com/1473625): There are crash reports that show there could be // cases where the open tabs section is not present in the snapshot. If so, // don't perform the update. @@ -1352,14 +1362,13 @@ - (void)modelAndViewUpdatesForInsertionDidCompleteAtIndex:(NSUInteger)index { [self updateSelectedCollectionViewItemRingAndBringIntoView:YES]; - [self.delegate gridViewController:self didChangeItemCount:self.items.count]; + NSInteger numberOfTabs = [self numberOfTabs]; + [self.delegate gridViewController:self didChangeItemCount:numberOfTabs]; // Check `index` boundaries in order to filter out possible race conditions // while mutating the collection. if (index == NSNotFound || index >= self.items.count || - static_cast<NSInteger>(index) >= - [self.collectionView - numberOfItemsInSection:kGridOpenTabsSectionIndex]) { + static_cast<NSInteger>(index) >= [self numberOfTabs]) { return; } @@ -1386,18 +1395,16 @@ GridItemIdentifier* removedItemIdentifier = [GridItemIdentifier tabIdentifier:removedItem]; [snapshot deleteItemsWithIdentifiers:@[ removedItemIdentifier ]]; - if ([self shouldShowEmptyState]) { - [self animateEmptyStateIn]; - } } // Makes the required changes when a new item has been removed. - (void)modelAndViewUpdatesForRemovalDidCompleteForItemWithID: (web::WebStateID)removedItemID { - if (self.items.count > 0) { + NSInteger numberOfTabs = [self numberOfTabs]; + if (numberOfTabs > 0) { [self updateSelectedCollectionViewItemRingAndBringIntoView:NO]; } - [self.delegate gridViewController:self didChangeItemCount:self.items.count]; + [self.delegate gridViewController:self didChangeItemCount:numberOfTabs]; [self.delegate gridViewController:self didRemoveItemWIthID:removedItemID]; } @@ -1515,8 +1522,7 @@ // conditions while mutating the collection. if (selectedIndex == NSNotFound || selectedIndex >= static_cast<NSInteger>(self.items.count) || - selectedIndex >= [self.collectionView - numberOfItemsInSection:kGridOpenTabsSectionIndex]) { + selectedIndex >= [self numberOfTabs]) { return; } NSIndexPath* selectedIndexPath = CreateIndexPath(selectedIndex); @@ -1743,21 +1749,22 @@ if (self.showingSuggestedActions) { return NO; } - return self.items.count == 0; + return self.gridEmpty; } // Updates the number of results found on the search open tabs section header. - (void)updateSearchResultsHeader { + NSInteger tabSectionIndex = [self.diffableDataSource + indexForSectionIdentifier:kGridOpenTabsSectionIdentifier]; GridHeader* headerView = (GridHeader*)[self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader - atIndexPath: - [NSIndexPath - indexPathForRow:0 - inSection:kGridOpenTabsSectionIndex]]; + atIndexPath:[NSIndexPath + indexPathForRow:0 + inSection:tabSectionIndex]]; if (!headerView) { return; } - NSString* resultsCount = [@(self.items.count) stringValue]; + NSString* resultsCount = [@([self numberOfTabs]) stringValue]; headerView.value = l10n_util::GetNSStringF(IDS_IOS_TABS_SEARCH_OPEN_TABS_COUNT, base::SysNSStringToUTF16(resultsCount)); @@ -1779,4 +1786,11 @@ return items; } +// Returns the number of tabs in the collection view. +- (NSInteger)numberOfTabs { + NSInteger sectionIndex = [self.diffableDataSource + indexForSectionIdentifier:kGridOpenTabsSectionIdentifier]; + return [self.collectionView numberOfItemsInSection:sectionIndex]; +} + @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_view_controller.mm index c9a0c43..c4e8b3b 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_view_controller.mm
@@ -279,8 +279,10 @@ } - (void)hideInactiveTabsButtonHeader { - NSIndexPath* indexPath = - [NSIndexPath indexPathForItem:0 inSection:kGridOpenTabsSectionIndex]; + NSInteger tabSectionIndex = [self.diffableDataSource + indexForSectionIdentifier:kGridOpenTabsSectionIdentifier]; + NSIndexPath* indexPath = [NSIndexPath indexPathForItem:0 + inSection:tabSectionIndex]; InactiveTabsButtonHeader* header = ObjCCast<InactiveTabsButtonHeader>([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader @@ -328,8 +330,10 @@ // Reconfigures the Inactive Tabs button header. - (void)updateInactiveTabsButtonHeader { - NSIndexPath* indexPath = - [NSIndexPath indexPathForItem:0 inSection:kGridOpenTabsSectionIndex]; + NSInteger tabSectionIndex = [self.diffableDataSource + indexForSectionIdentifier:kGridOpenTabsSectionIdentifier]; + NSIndexPath* indexPath = [NSIndexPath indexPathForItem:0 + inSection:tabSectionIndex]; InactiveTabsButtonHeader* header = ObjCCast<InactiveTabsButtonHeader>([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader @@ -341,8 +345,10 @@ // Reconfigures the Inactive Tabs preamble header. - (void)updateInactiveTabsPreambleHeader { - NSIndexPath* indexPath = - [NSIndexPath indexPathForItem:0 inSection:kGridOpenTabsSectionIndex]; + NSInteger tabSectionIndex = [self.diffableDataSource + indexForSectionIdentifier:kGridOpenTabsSectionIdentifier]; + NSIndexPath* indexPath = [NSIndexPath indexPathForItem:0 + inSection:tabSectionIndex]; InactiveTabsPreambleHeader* header = ObjCCast<InactiveTabsPreambleHeader>([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/BUILD.gn index a29f937a..3b5ae66 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/BUILD.gn +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/BUILD.gn
@@ -19,6 +19,7 @@ "//ios/chrome/browser/ntp/model:util", "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/public/features", "//ios/chrome/browser/tabs/model", "//ios/chrome/browser/tabs/model:features", "//ios/chrome/browser/ui/bookmarks:utils",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_context_menu_helper.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_context_menu_helper.mm index 1de2821..8bb8fec 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_context_menu_helper.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_context_menu_helper.mm
@@ -4,6 +4,7 @@ #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_context_menu_helper.h" +#import "base/check.h" #import "base/metrics/histogram_functions.h" #import "components/bookmarks/browser/bookmark_model.h" #import "components/bookmarks/common/bookmark_pref_names.h" @@ -15,6 +16,7 @@ #import "ios/chrome/browser/shared/model/browser/browser_list.h" #import "ios/chrome/browser/shared/model/browser/browser_list_factory.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/shared/public/features/features.h" #import "ios/chrome/browser/tabs/model/features.h" #import "ios/chrome/browser/tabs/model/tab_title_util.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" @@ -112,6 +114,13 @@ } } + if (base::FeatureList::IsEnabled(kTabGroupsInGrid)) { + [menuElements addObject:[actionFactory actionToAddTabToNewGroupWithBlock:^{ + [self.contextMenuDelegate + createNewTabGroupWithIdentifier:cell.itemIdentifier]; + }]]; + } + if (!IsURLNewTabPage(item.URL)) { [menuElements addObject:[actionFactory actionToShareWithBlock:^{ [self.contextMenuDelegate
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm index f9342b83..8c3e486 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
@@ -1333,6 +1333,13 @@ [self.pinnedTabsMediator setPinState:NO forItemWithID:identifier]; } +- (void)createNewTabGroupWithIdentifier:(web::WebStateID)identifier { + CHECK(base::FeatureList::IsEnabled(kTabGroupsInGrid)) + << "You should not be able to create a new tab group outside the Tab " + "Groups experiment."; + // TODO(crbug.com/1501837): Display the tab group creation view. +} + - (void)closeTabWithIdentifier:(web::WebStateID)identifier incognito:(BOOL)incognito pinned:(BOOL)pinned {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm index 56cd883d..14d3084f 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm
@@ -18,11 +18,8 @@ // The alpha of the close button background color. const CGFloat kCloseButtonBackgroundAlpha = 0.2; -// Corner radius of the top left and right corner of the content view. -const CGFloat kTopCornerRadius = 16; - -// Size of the decoration tails when the cell is selected. -const CGFloat kTailSize = 16; +// Size of the decoration corner when the cell is selected. +const CGFloat kCornerSize = 16; // Content view constants. const CGFloat kFaviconLeadingMargin = 16; @@ -44,15 +41,14 @@ UILabel* _titleLabel; UIImageView* _faviconView; - // Decoration tails, visible when the cell is selected. + // Rounded decoration views, visible when the cell is selected. UIView* _leftTailView; UIView* _rightTailView; + UIView* _topLeftCornerView; + UIView* _topRightCornerView; - // Width of the cell. - CGFloat _cellWidth; - - // Wether the tail layers have been updated. - BOOL _tailLayersUpdated; + // Wether the decoration layers have been updated. + BOOL _decorationLayersUpdated; // Circular spinner that shows the loading state of the tab. MDCActivityIndicator* _activityIndicator; @@ -61,11 +57,16 @@ - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { self.layer.masksToBounds = NO; - _cellWidth = 0; - _tailLayersUpdated = NO; + _decorationLayersUpdated = NO; UIView* contentView = self.contentView; + _topLeftCornerView = [self createTopCornerView]; + [contentView addSubview:_topLeftCornerView]; + + _topRightCornerView = [self createTopCornerView]; + [contentView addSubview:_topRightCornerView]; + _faviconView = [self createFaviconView]; [contentView addSubview:_faviconView]; @@ -85,6 +86,7 @@ [self addSubview:_rightTailView]; [self setupConstraints]; + [self setupDecorationLayers]; self.selected = NO; } @@ -120,20 +122,6 @@ } } -- (void)layoutSubviews { - [super layoutSubviews]; - - CGFloat cellWidth = self.frame.size.width; - if (cellWidth != _cellWidth) { - [self updateContentViewLayer]; - _cellWidth = cellWidth; - } - - if (!_tailLayersUpdated) { - [self updateTailLayers]; - } -} - #pragma mark - Accessor - (void)setSelected:(BOOL)selected { @@ -154,9 +142,11 @@ _titleLabel.textColor = selected ? [UIColor colorNamed:kTextPrimaryColor] : [UIColor colorNamed:kGrey600Color]; - // Update decoration tails visibility. + // Update decoration views visibility. _leftTailView.hidden = !selected; _rightTailView.hidden = !selected; + _topLeftCornerView.hidden = !selected; + _topRightCornerView.hidden = !selected; } #pragma mark - UICollectionViewCell @@ -170,67 +160,43 @@ #pragma mark - Private -/// Updates the `contentView` layer for the `selected` state of the cell. -- (void)updateContentViewLayer { - // Round the top corners of the content view. - UIBezierPath* path = [UIBezierPath - bezierPathWithRoundedRect:self.bounds - byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight - cornerRadii:CGSizeMake(kTopCornerRadius, 0.0)]; - CAShapeLayer* maskLayer = [CAShapeLayer layer]; - maskLayer.path = path.CGPath; - self.contentView.layer.mask = maskLayer; -} - -/// Updates the tail layers for the `selected` state of the cell. -- (void)updateTailLayers { - CGRect leftTailRect = _leftTailView.bounds; - if (leftTailRect.size.width == 0) { - return; - } - - CGFloat radius = kTailSize; +/// Sets the decoration layers for the `selected` state of the cell. +- (void)setupDecorationLayers { + // Bottom left corner path. + UIBezierPath* cornerPath = [UIBezierPath bezierPath]; + [cornerPath moveToPoint:CGPointMake(kCornerSize, kCornerSize)]; + [cornerPath addLineToPoint:CGPointMake(kCornerSize, 0)]; + [cornerPath addArcWithCenter:CGPointMake(0, 0) + radius:kCornerSize + startAngle:0 + endAngle:M_PI_2 + clockwise:YES]; + [cornerPath closePath]; // Round the left tail. - UIBezierPath* leftTailPath = [UIBezierPath bezierPath]; - [leftTailPath moveToPoint:CGPointMake(CGRectGetMaxX(leftTailRect), - CGRectGetMaxY(leftTailRect))]; - [leftTailPath - addLineToPoint:CGPointMake(CGRectGetMaxX(leftTailRect), - CGRectGetMaxY(leftTailRect) - radius)]; - [leftTailPath - addArcWithCenter:CGPointMake(CGRectGetMaxX(leftTailRect) - radius, - CGRectGetMaxY(leftTailRect) - radius) - radius:radius - startAngle:0 - endAngle:M_PI_2 - clockwise:YES]; - [leftTailPath closePath]; CAShapeLayer* leftTailMaskLayer = [CAShapeLayer layer]; - leftTailMaskLayer.path = leftTailPath.CGPath; + leftTailMaskLayer.path = cornerPath.CGPath; _leftTailView.layer.mask = leftTailMaskLayer; // Round the right tail. - CGRect rightTailRect = _rightTailView.bounds; - UIBezierPath* rightTailpath = [UIBezierPath bezierPath]; - [rightTailpath moveToPoint:CGPointMake(CGRectGetMinX(rightTailRect), - CGRectGetMaxY(rightTailRect))]; - [rightTailpath - addLineToPoint:CGPointMake(CGRectGetMinX(rightTailRect), - CGRectGetMaxY(rightTailRect) - radius)]; - [rightTailpath - addArcWithCenter:CGPointMake(CGRectGetMinX(rightTailRect) + radius, - CGRectGetMaxY(rightTailRect) - radius) - radius:radius - startAngle:M_PI - endAngle:M_PI_2 - clockwise:NO]; - [rightTailpath closePath]; CAShapeLayer* rightTailMaskLayer = [CAShapeLayer layer]; - rightTailMaskLayer.path = rightTailpath.CGPath; + rightTailMaskLayer.path = cornerPath.CGPath; _rightTailView.layer.mask = rightTailMaskLayer; + _rightTailView.layer.transform = CATransform3DMakeScale(-1, 1, 1); - _tailLayersUpdated = YES; + // Round the top left corner. + CAShapeLayer* topLeftCornerLayer = [CAShapeLayer layer]; + topLeftCornerLayer.path = cornerPath.CGPath; + _topLeftCornerView.layer.mask = topLeftCornerLayer; + _topLeftCornerView.layer.transform = CATransform3DMakeScale(-1, -1, 1); + + // Round the top right corner. + CAShapeLayer* topRightCornerLayer = [CAShapeLayer layer]; + topRightCornerLayer.path = cornerPath.CGPath; + _topRightCornerView.layer.mask = topRightCornerLayer; + _topRightCornerView.layer.transform = CATransform3DMakeScale(1, -1, 1); + + _decorationLayersUpdated = YES; } // Sets the cell constraints. @@ -280,21 +246,38 @@ constraintEqualToAnchor:contentView.centerYAnchor], ]]; + /// `_topLeftCornerView` and `_topRightCornerView` constraints. + [NSLayoutConstraint activateConstraints:@[ + [_topLeftCornerView.leadingAnchor + constraintEqualToAnchor:contentView.leadingAnchor], + [_topLeftCornerView.topAnchor + constraintEqualToAnchor:contentView.topAnchor], + [_topLeftCornerView.widthAnchor constraintEqualToConstant:kCornerSize], + [_topLeftCornerView.heightAnchor constraintEqualToConstant:kCornerSize], + + [_topRightCornerView.trailingAnchor + constraintEqualToAnchor:contentView.trailingAnchor], + [_topRightCornerView.topAnchor + constraintEqualToAnchor:contentView.topAnchor], + [_topRightCornerView.widthAnchor constraintEqualToConstant:kCornerSize], + [_topRightCornerView.heightAnchor constraintEqualToConstant:kCornerSize], + ]]; + /// `_leftTailView` and `_rightTailView` constraints. [NSLayoutConstraint activateConstraints:@[ [_leftTailView.trailingAnchor constraintEqualToAnchor:contentView.leadingAnchor], [_leftTailView.bottomAnchor constraintEqualToAnchor:contentView.bottomAnchor], - [_leftTailView.widthAnchor constraintEqualToConstant:kTailSize], - [_leftTailView.heightAnchor constraintEqualToConstant:kTailSize], + [_leftTailView.widthAnchor constraintEqualToConstant:kCornerSize], + [_leftTailView.heightAnchor constraintEqualToConstant:kCornerSize], [_rightTailView.leadingAnchor constraintEqualToAnchor:contentView.trailingAnchor], [_rightTailView.bottomAnchor constraintEqualToAnchor:contentView.bottomAnchor], - [_rightTailView.widthAnchor constraintEqualToConstant:kTailSize], - [_rightTailView.heightAnchor constraintEqualToConstant:kTailSize], + [_rightTailView.widthAnchor constraintEqualToConstant:kCornerSize], + [_rightTailView.heightAnchor constraintEqualToConstant:kCornerSize], ]]; } @@ -359,4 +342,14 @@ return tailView; } +// Returns a new top corner view. +- (UIView*)createTopCornerView { + UIView* topCornerView = [[UIView alloc] init]; + topCornerView.backgroundColor = [UIColor colorNamed:kGrey200Color]; + topCornerView.translatesAutoresizingMaskIntoConstraints = NO; + topCornerView.hidden = YES; + + return topCornerView; +} + @end
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index e41da9f..724cc23a 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -287,6 +287,7 @@ "//ios/chrome/browser/reading_list/model", "//ios/chrome/browser/safe_browsing/model", "//ios/chrome/browser/search_engines/model", + "//ios/chrome/browser/segmentation_platform/model:ukm_client", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser_state", "//ios/chrome/browser/shared/model/paths",
diff --git a/ios/chrome/browser/web/DEPS b/ios/chrome/browser/web/DEPS index 331368ed..1f173560 100644 --- a/ios/chrome/browser/web/DEPS +++ b/ios/chrome/browser/web/DEPS
@@ -30,6 +30,7 @@ "+ios/chrome/browser/rlz", "+ios/chrome/browser/safe_browsing/model", "+ios/chrome/browser/search_engines/model", + "+ios/chrome/browser/segmentation_platform/model", "+ios/chrome/browser/sessions", "+ios/chrome/browser/signin/model", "+ios/chrome/browser/snapshots/model/snapshot_tab_helper.h",
diff --git a/ios/chrome/browser/web/chrome_main_parts.mm b/ios/chrome/browser/web/chrome_main_parts.mm index 89b44d9d..466d4f8 100644 --- a/ios/chrome/browser/web/chrome_main_parts.mm +++ b/ios/chrome/browser/web/chrome_main_parts.mm
@@ -62,6 +62,7 @@ #import "ios/chrome/browser/policy/model/browser_policy_connector_ios.h" #import "ios/chrome/browser/promos_manager/promos_manager.h" #import "ios/chrome/browser/safe_browsing/model/safe_browsing_metrics_collector_factory.h" +#import "ios/chrome/browser/segmentation_platform/model/ukm_database_client.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state_manager.h" #import "ios/chrome/browser/shared/model/paths/paths.h" @@ -298,6 +299,10 @@ // Initialize opt guide. OptimizationGuideServiceFactory::InitializePredictionModelStore(); + segmentation_platform::UkmDatabaseClientHolder::GetClientInstance(nullptr) + .PreProfileInit( + /*in_memory_database=*/false); + // Ensure that the browser state is initialized. EnsureBrowserStateKeyedServiceFactoriesBuilt(); ios::ChromeBrowserStateManager* browser_state_manager = @@ -323,6 +328,9 @@ : "Disabled", variations::SyntheticTrialAnnotationMode::kCurrentLog); + segmentation_platform::UkmDatabaseClientHolder::GetClientInstance(nullptr) + .StartObservation(); + #if BUILDFLAG(ENABLE_RLZ) // Init the RLZ library. This just schedules a task on the file thread to be // run sometime later. If this is the first run we record the installation @@ -380,6 +388,10 @@ void IOSChromeMainParts::PostMainMessageLoopRun() { TranslateServiceIOS::Shutdown(); + + segmentation_platform::UkmDatabaseClientHolder::GetClientInstance(nullptr) + .PostMessageLoopRun(); + #if BUILDFLAG(ENABLE_RLZ) rlz::RLZTracker::CleanupRlz(); #endif // BUILDFLAG(ENABLE_RLZ)
diff --git a/ios/chrome/common/ui/promo_style/promo_style_background_view.mm b/ios/chrome/common/ui/promo_style/promo_style_background_view.mm index a8f7a39..206964b0 100644 --- a/ios/chrome/common/ui/promo_style/promo_style_background_view.mm +++ b/ios/chrome/common/ui/promo_style/promo_style_background_view.mm
@@ -6,6 +6,7 @@ #import "base/ios/ios_util.h" #import "ios/chrome/common/ui/util/image_util.h" +#import "ios/chrome/common/ui/util/ui_util.h" namespace { @@ -95,6 +96,21 @@ }); } +/// Returns a resized `image` with a width covering the `horizontalRatio` of the +/// view. The height is computed to keep the same aspect ratio as the original +/// image. +- (UIImage*)resizeImage:(UIImage*)image + horizontalRatio:(CGFloat)horizontalRatio { + CGFloat imageAspectRatio = image.size.height / image.size.width; + const CGFloat width = + AlignValueToPixel(self.bounds.size.width * horizontalRatio); + const CGFloat height = + MIN(self.bounds.size.height, AlignValueToPixel(width * imageAspectRatio)); + + return ResizeImage(image, CGSizeMake(width, height), + ProjectionMode::kAspectFillAlignTop); +} + /// Updates left and right images. - (void)updateImages { // TODO(crbug.com/1503638): Add dark mode assets. @@ -103,20 +119,14 @@ UIImage* leftImage = [UIImage imageNamed:@"promo_background_left"]; CGFloat leftImageHorizontalRatio = isCompact ? kLeftImageRatioCompact : kLeftImageRatioRegular; - _leftImageView.image = - ResizeImage(leftImage, - CGSizeMake(self.bounds.size.width * leftImageHorizontalRatio, - self.bounds.size.height), - ProjectionMode::kAspectFillAlignTop); + _leftImageView.image = [self resizeImage:leftImage + horizontalRatio:leftImageHorizontalRatio]; UIImage* rightImage = [UIImage imageNamed:@"promo_background_right"]; CGFloat rightImageHorizontalRatio = isCompact ? kRightImageRatioCompact : kRightImageRatioRegular; - _rightImageView.image = - ResizeImage(rightImage, - CGSizeMake(self.bounds.size.width * rightImageHorizontalRatio, - self.bounds.size.height), - ProjectionMode::kAspectFillAlignTop); + _rightImageView.image = [self resizeImage:rightImage + horizontalRatio:rightImageHorizontalRatio]; } @end
diff --git a/ios/chrome/common/ui/promo_style/promo_style_view_controller.h b/ios/chrome/common/ui/promo_style/promo_style_view_controller.h index 5991722..38048b39 100644 --- a/ios/chrome/common/ui/promo_style/promo_style_view_controller.h +++ b/ios/chrome/common/ui/promo_style/promo_style_view_controller.h
@@ -79,6 +79,10 @@ // Default to NO. @property(nonatomic, assign) BOOL hideHeaderOnTallContent; +// When set to YES, forces UIUserInterfaceStyleLight for the header views. This +// value has to be set before the view is loaded. Default to NO. +@property(nonatomic, assign) BOOL headerViewForceStyleLight; + // The label of the headline below the image. Must be set before the view is // loaded. This is declared public so the accessibility can be enabled. @property(nonatomic, strong) UILabel* titleLabel;
diff --git a/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm b/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm index b2cc1da7..5cf2d12 100644 --- a/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm +++ b/ios/chrome/common/ui/promo_style/promo_style_view_controller.mm
@@ -651,6 +651,9 @@ _headerImageView.image = _headerImage; _headerImageView.accessibilityLabel = _headerAccessibilityLabel; _headerImageView.isAccessibilityElement = _headerAccessibilityLabel != nil; + if (self.headerViewForceStyleLight) { + _headerImageView.overrideUserInterfaceStyle = UIUserInterfaceStyleLight; + } } return _headerImageView; } @@ -1258,6 +1261,9 @@ UIView* frameView = [[UIView alloc] init]; frameView.translatesAutoresizingMaskIntoConstraints = NO; frameView.backgroundColor = [UIColor colorNamed:kBackgroundColor]; + if (self.headerViewForceStyleLight) { + frameView.overrideUserInterfaceStyle = UIUserInterfaceStyleLight; + } frameView.layer.cornerRadius = kHeaderImageCornerRadius; frameView.layer.shadowOffset = CGSizeMake(kHeaderImageShadowOffsetX, kHeaderImageShadowOffsetY);
diff --git a/ios/chrome/common/ui/promo_style/resources/promo_background_right.imageset/promo_background_right.pdf b/ios/chrome/common/ui/promo_style/resources/promo_background_right.imageset/promo_background_right.pdf index 5cdf65f..f488ac36 100644 --- a/ios/chrome/common/ui/promo_style/resources/promo_background_right.imageset/promo_background_right.pdf +++ b/ios/chrome/common/ui/promo_style/resources/promo_background_right.imageset/promo_background_right.pdf Binary files differ
diff --git a/ios/components/cookie_util/BUILD.gn b/ios/components/cookie_util/BUILD.gn index 6fb177b..32e6f4b 100644 --- a/ios/components/cookie_util/BUILD.gn +++ b/ios/components/cookie_util/BUILD.gn
@@ -8,7 +8,9 @@ "cookie_util.mm", ] deps = [ + ":constants", "//base", + "//components/prefs", "//ios/net", "//ios/web/common", "//ios/web/public", @@ -17,13 +19,24 @@ ] } +source_set("constants") { + sources = [ + "cookie_constants.h", + "cookie_constants.mm", + ] + public_deps = [] +} + source_set("unit_tests") { testonly = true sources = [ "cookie_util_unittest.mm" ] deps = [ + ":constants", ":cookie_util", "//base", "//base/test:test_support", + "//components/prefs", + "//components/prefs:test_support", "//ios/net", "//ios/net:test_support", "//ios/web/common",
diff --git a/ios/components/cookie_util/DEPS b/ios/components/cookie_util/DEPS index ec6e71b..e93ad06 100644 --- a/ios/components/cookie_util/DEPS +++ b/ios/components/cookie_util/DEPS
@@ -1,4 +1,7 @@ include_rules = [ + "+components/prefs/pref_registry_simple.h", + "+components/prefs/pref_service.h", + "+components/prefs/testing_pref_service.h", "+ios/web/common", "+net/cookies", "+net/extras/sqlite",
diff --git a/ios/components/cookie_util/cookie_constants.h b/ios/components/cookie_util/cookie_constants.h new file mode 100644 index 0000000..28497e8 --- /dev/null +++ b/ios/components/cookie_util/cookie_constants.h
@@ -0,0 +1,11 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_COMPONENTS_COOKIE_UTIL_COOKIE_CONSTANTS_H_ +#define IOS_COMPONENTS_COOKIE_UTIL_COOKIE_CONSTANTS_H_ + +// Prefs key used to store the most recent cookie deletion date. +extern const char kLastCookieDeletionDate[]; + +#endif // IOS_COMPONENTS_COOKIE_UTIL_COOKIE_CONSTANTS_H_
diff --git a/ios/components/cookie_util/cookie_constants.mm b/ios/components/cookie_util/cookie_constants.mm new file mode 100644 index 0000000..0840a34 --- /dev/null +++ b/ios/components/cookie_util/cookie_constants.mm
@@ -0,0 +1,7 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/components/cookie_util/cookie_constants.h" + +const char kLastCookieDeletionDate[] = "LastCookieDeletionDate";
diff --git a/ios/components/cookie_util/cookie_util.h b/ios/components/cookie_util/cookie_util.h index 6b503737..82e8ef7 100644 --- a/ios/components/cookie_util/cookie_util.h +++ b/ios/components/cookie_util/cookie_util.h
@@ -10,6 +10,8 @@ #include "base/files/file_path.h" #include "net/cookies/canonical_cookie.h" +class PrefService; + namespace net { class CookieStore; class SystemCookieStore; @@ -72,7 +74,7 @@ // Returns true if the cookies should be cleared. // Current implementation returns true if the device has rebooted since the // last time cookies have been cleared. -bool ShouldClearSessionCookies(); +bool ShouldClearSessionCookies(PrefService* pref_service); // Clears the session cookies for `browser_state`. void ClearSessionCookies(web::BrowserState* browser_state);
diff --git a/ios/components/cookie_util/cookie_util.mm b/ios/components/cookie_util/cookie_util.mm index 598b625d..a97ccf5 100644 --- a/ios/components/cookie_util/cookie_util.mm +++ b/ios/components/cookie_util/cookie_util.mm
@@ -14,6 +14,8 @@ #import "base/functional/callback_helpers.h" #import "base/memory/ref_counted.h" #import "base/task/thread_pool.h" +#import "components/prefs/pref_service.h" +#import "ios/components/cookie_util/cookie_constants.h" #import "ios/net/cookies/cookie_store_ios.h" #import "ios/net/cookies/system_cookie_store.h" #import "ios/web/common/features.h" @@ -31,9 +33,6 @@ namespace { -// Date of the last cookie deletion. -NSString* const kLastCookieDeletionDate = @"LastCookieDeletionDate"; - // Creates a SQLitePersistentCookieStore running on a background thread. scoped_refptr<net::SQLitePersistentCookieStore> CreatePersistentCookieStore( const base::FilePath& path, @@ -94,22 +93,27 @@ net_log); } -bool ShouldClearSessionCookies() { - NSUserDefaults* standardDefaults = [NSUserDefaults standardUserDefaults]; - struct timeval boottime; - int mib[2] = {CTL_KERN, KERN_BOOTTIME}; - size_t size = sizeof(boottime); - time_t lastCookieDeletionDate = - [standardDefaults integerForKey:kLastCookieDeletionDate]; - time_t now; - time(&now); +bool ShouldClearSessionCookies(PrefService* pref_service) { + const base::Time last_cookie_deletion_date = + pref_service->GetTime(kLastCookieDeletionDate); + bool clear_cookies = true; - if (lastCookieDeletionDate != 0 && - sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0) { - clear_cookies = boottime.tv_sec > lastCookieDeletionDate; + if (!last_cookie_deletion_date.is_null()) { + struct timeval boottime; + int mib[2] = {CTL_KERN, KERN_BOOTTIME}; + size_t size = sizeof(boottime); + + if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1) { + if (boottime.tv_sec != 0) { + const base::Time boot = base::Time::FromTimeVal(boottime); + + clear_cookies = boot > last_cookie_deletion_date; + } + } } - if (clear_cookies) - [standardDefaults setInteger:now forKey:kLastCookieDeletionDate]; + if (clear_cookies) { + pref_service->SetTime(kLastCookieDeletionDate, base::Time::Now()); + } return clear_cookies; }
diff --git a/ios/components/cookie_util/cookie_util_unittest.mm b/ios/components/cookie_util/cookie_util_unittest.mm index 0af89fc8..d056c15 100644 --- a/ios/components/cookie_util/cookie_util_unittest.mm +++ b/ios/components/cookie_util/cookie_util_unittest.mm
@@ -10,6 +10,10 @@ #import "base/run_loop.h" #import "base/strings/sys_string_conversions.h" #import "base/test/ios/wait_util.h" +#import "components/prefs/pref_registry_simple.h" +#import "components/prefs/pref_service.h" +#import "components/prefs/testing_pref_service.h" +#import "ios/components/cookie_util/cookie_constants.h" #import "ios/net/cookies/cookie_store_ios_test_util.h" #import "ios/net/cookies/ns_http_system_cookie_store.h" #import "ios/net/cookies/system_cookie_store.h" @@ -23,9 +27,6 @@ namespace { -// Date of the last cookie deletion. -NSString* const kLastCookieDeletionDate = @"LastCookieDeletionDate"; - class CookieUtilTest : public PlatformTest { public: CookieUtilTest() @@ -41,26 +42,28 @@ }; TEST_F(CookieUtilTest, ShouldClearSessionCookies) { - time_t start_test_time; - time(&start_test_time); - NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + std::unique_ptr<TestingPrefServiceSimple> pref_service = + std::make_unique<TestingPrefServiceSimple>(); + pref_service->registry()->RegisterTimePref(kLastCookieDeletionDate, + base::Time()); + base::Time start_test_time = base::Time::Now(); // Delete cookies if the key is not present. - [defaults removeObjectForKey:kLastCookieDeletionDate]; - EXPECT_TRUE(cookie_util::ShouldClearSessionCookies()); + pref_service->ClearPref(kLastCookieDeletionDate); + EXPECT_TRUE(cookie_util::ShouldClearSessionCookies(pref_service.get())); // The deletion time should be created. - time_t deletion_time = [defaults integerForKey:kLastCookieDeletionDate]; - time_t now; - time(&now); + base::Time deletion_time = pref_service->GetTime(kLastCookieDeletionDate); + base::Time now = base::Time::Now(); EXPECT_LE(start_test_time, deletion_time); EXPECT_LE(deletion_time, now); // Cookies are not deleted again. - EXPECT_FALSE(cookie_util::ShouldClearSessionCookies()); + EXPECT_FALSE(cookie_util::ShouldClearSessionCookies(pref_service.get())); // Set the deletion time before the machine was started. // Sometime in year 1980. - [defaults setInteger:328697227 forKey:kLastCookieDeletionDate]; - EXPECT_TRUE(cookie_util::ShouldClearSessionCookies()); - EXPECT_LE(now, [defaults integerForKey:kLastCookieDeletionDate]); + pref_service->SetTime(kLastCookieDeletionDate, + base::Time::FromTimeT(328697227)); + EXPECT_TRUE(cookie_util::ShouldClearSessionCookies(pref_service.get())); + EXPECT_LE(now, pref_service->GetTime(kLastCookieDeletionDate)); } // Tests that CreateCookieStore returns the correct type of net::CookieStore
diff --git a/ios_internal b/ios_internal index 37b0236..1be329b 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit 37b02362be97b8b735e8a28a496f01e664ddc9ea +Subproject commit 1be329bcbd76dfac79c8324e6fee465326c761d5
diff --git a/mojo/public/tools/bindings/README.md b/mojo/public/tools/bindings/README.md index 717d778c..b27b2d0 100644 --- a/mojo/public/tools/bindings/README.md +++ b/mojo/public/tools/bindings/README.md
@@ -96,7 +96,7 @@ | `string` | UTF-8 encoded string. | `array<T>` | Array of any Mojom type *T*; for example, `array<uint8>` or `array<array<string>>`. | `array<T, N>` | Fixed-length array of any Mojom type *T*. The parameter *N* must be an integral constant. -| `map<S, T>` | Associated array maping values of type *S* to values of type *T*. *S* may be a `string`, `enum`, or numeric type. +| `map<S, T>` | Associated array mapping values of type *S* to values of type *T*. *S* may be a `string`, `enum`, or numeric type. | `handle` | Generic Mojo handle. May be any type of handle, including a wrapped native platform handle. | `handle<message_pipe>` | Generic message pipe handle. | `handle<shared_buffer>` | Shared buffer handle. @@ -355,8 +355,8 @@ Features can be declared with a `name` and `default_state` and can be attached in mojo to interfaces or methods using the `RuntimeFeature` attribute. If the -feature is disabled at runtime the method will crash, and the interface will -refused to be bound / instantiated. Features cannot serialized to be sent over +feature is disabled at runtime, the method will crash and the interface will +refuse to be bound / instantiated. Features cannot be serialized to be sent over IPC at this time. ``` @@ -378,7 +378,7 @@ CallElevator(int floor); // This method can be called. - RingDoorbell(int volune); + RingDoorbell(int volume); } ``` @@ -935,7 +935,7 @@ | InterfaceBody Const | InterfaceBody Enum | InterfaceBody Method -Method = AttributeSection Name Ordinal "(" ParamterList ")" Response ";" +Method = AttributeSection Name Ordinal "(" ParameterList ")" Response ";" ParameterList = <empty> | NonEmptyParameterList NonEmptyParameterList = Parameter | Parameter "," NonEmptyParameterList
diff --git a/net/base/proxy_delegate.h b/net/base/proxy_delegate.h index 15ed95d..acfdc3b 100644 --- a/net/base/proxy_delegate.h +++ b/net/base/proxy_delegate.h
@@ -20,6 +20,7 @@ class HttpRequestHeaders; class HttpResponseHeaders; class ProxyInfo; +class ProxyResolutionService; // Delegate for setting up a connection. class NET_EXPORT ProxyDelegate { @@ -66,6 +67,11 @@ size_t chain_index, const HttpResponseHeaders& response_headers) = 0; + // Associates a `ProxyResolutionService` with this `ProxyDelegate`. + // `proxy_resolution_service` must outlive `this`. + virtual void SetProxyResolutionService( + ProxyResolutionService* proxy_resolution_service) = 0; + void OnBeforeTunnelRequestServerOnly(const ProxyChain& proxy_chain, size_t proxy_chain_index, HttpRequestHeaders* extra_headers) {
diff --git a/net/base/test_proxy_delegate.cc b/net/base/test_proxy_delegate.cc index a06a3733..8dd60298 100644 --- a/net/base/test_proxy_delegate.cc +++ b/net/base/test_proxy_delegate.cc
@@ -10,6 +10,7 @@ #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" #include "net/proxy_resolution/proxy_info.h" +#include "net/proxy_resolution/proxy_resolution_service.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" @@ -76,4 +77,7 @@ return OK; } +void TestProxyDelegate::SetProxyResolutionService( + ProxyResolutionService* proxy_resolution_service) {} + } // namespace net
diff --git a/net/base/test_proxy_delegate.h b/net/base/test_proxy_delegate.h index 9aedd03..00ad6a9a 100644 --- a/net/base/test_proxy_delegate.h +++ b/net/base/test_proxy_delegate.h
@@ -17,6 +17,7 @@ namespace net { class ProxyInfo; +class ProxyResolutionService; class TestProxyDelegate : public ProxyDelegate { public: @@ -56,6 +57,8 @@ const ProxyChain& proxy_chain, size_t chain_index, const HttpResponseHeaders& response_headers) override; + void SetProxyResolutionService( + ProxyResolutionService* proxy_resolution_service) override; private: bool on_before_tunnel_request_called_ = false;
diff --git a/net/cert/asn1_util.h b/net/cert/asn1_util.h index c150068c..e1ca60f 100644 --- a/net/cert/asn1_util.h +++ b/net/cert/asn1_util.h
@@ -20,8 +20,8 @@ // ExtractSPKIFromDERCert parses the DER encoded certificate in |cert| and // extracts the bytes of the SubjectPublicKeyInfo. On successful return, // |spki_out| is set to contain the SPKI, pointing into |cert|. -NET_EXPORT_PRIVATE bool ExtractSPKIFromDERCert(base::StringPiece cert, - base::StringPiece* spki_out); +NET_EXPORT bool ExtractSPKIFromDERCert(base::StringPiece cert, + base::StringPiece* spki_out); // ExtractSubjectPublicKeyFromSPKI parses the DER encoded SubjectPublicKeyInfo // in |spki| and extracts the bytes of the SubjectPublicKey. On successful
diff --git a/net/cert/cert_verify_proc.h b/net/cert/cert_verify_proc.h index 18fe23b..c94402d 100644 --- a/net/cert/cert_verify_proc.h +++ b/net/cert/cert_verify_proc.h
@@ -123,6 +123,9 @@ // certs from the configured system store. This is implementation-specific // plumbing for passing additional intermediates through. CertificateList additional_untrusted_authorities; + + // Additional SPKIs to consider as distrusted during path validation. + std::vector<std::vector<uint8_t>> additional_distrusted_spkis; }; // These values are persisted to logs. Entries should not be renumbered and
diff --git a/net/cert/cert_verify_proc_builtin.cc b/net/cert/cert_verify_proc_builtin.cc index 15ed412..92b810a8 100644 --- a/net/cert/cert_verify_proc_builtin.cc +++ b/net/cert/cert_verify_proc_builtin.cc
@@ -532,7 +532,19 @@ NetLogWithSource::Make(net::NetLogSourceType::CERT_VERIFY_PROC_CREATED); net_log.BeginEvent(NetLogEventType::CERT_VERIFY_PROC_CREATED); - // Parse the additional trust anchors and setup trust store. + for (const auto& spki : instance_params.additional_distrusted_spkis) { + additional_trust_store_.AddDistrustedCertificateBySPKI( + std::string(spki.begin(), spki.end())); + net_log.AddEvent(NetLogEventType::CERT_VERIFY_PROC_ADDITIONAL_CERT, [&] { + base::Value::Dict results; + results.Set("spki", NetLogBinaryValue(base::make_span(spki))); + results.Set("trust", + bssl::CertificateTrust::ForDistrusted().ToDebugString()); + return results; + }); + } + + // Parse the additional certificates and setup trust store. for (const auto& x509_cert : instance_params.additional_trust_anchors) { bssl::CertErrors parsing_errors; std::shared_ptr<const bssl::ParsedCertificate> cert =
diff --git a/net/cert/cert_verify_proc_builtin_unittest.cc b/net/cert/cert_verify_proc_builtin_unittest.cc index 3b65d823..3b47753 100644 --- a/net/cert/cert_verify_proc_builtin_unittest.cc +++ b/net/cert/cert_verify_proc_builtin_unittest.cc
@@ -25,6 +25,7 @@ #include "net/cert/internal/system_trust_store.h" #include "net/cert/sct_status_flags.h" #include "net/cert/time_conversions.h" +#include "net/cert/x509_util.h" #include "net/cert_net/cert_net_fetcher_url_request.h" #include "net/http/transport_security_state.h" #include "net/log/net_log_with_source.h" @@ -200,10 +201,30 @@ void TearDown() override { cert_net_fetcher_->Shutdown(); } void InitializeVerifyProc(const CertificateList& additional_trust_anchors) { + InitializeVerifyProc(/*additional_trust_anchors=*/additional_trust_anchors, + /*additional_distrusted_certificates=*/{}); + } + + void InitializeVerifyProc( + const CertificateList& additional_trust_anchors, + const CertificateList& additional_distrusted_certificates) { auto mock_system_trust_store = std::make_unique<MockSystemTrustStore>(); mock_system_trust_store_ = mock_system_trust_store.get(); CertVerifyProc::InstanceParams instance_params; instance_params.additional_trust_anchors = additional_trust_anchors; + std::vector<std::vector<uint8_t>> distrusted_spkis; + for (const auto& x509_cert : additional_distrusted_certificates) { + std::shared_ptr<const bssl::ParsedCertificate> cert = + bssl::ParsedCertificate::Create( + bssl::UpRef(x509_cert->cert_buffer()), + net::x509_util::DefaultParseCertificateOptions(), + /*errors=*/nullptr); + EXPECT_TRUE(cert); + std::string spki_string = cert->tbs().spki_tlv.AsString(); + distrusted_spkis.push_back( + std::vector<uint8_t>(spki_string.begin(), spki_string.end())); + } + instance_params.additional_distrusted_spkis = distrusted_spkis; auto mock_ct_verifier = std::make_unique<MockCTVerifier>(); mock_ct_verifier_ = mock_ct_verifier.get(); mock_ct_policy_enforcer_ = base::MakeRefCounted<MockCTPolicyEnforcer>(); @@ -457,6 +478,31 @@ EXPECT_EQ(verify_result.scts.size(), 0u); } +TEST_F(CertVerifyProcBuiltinTest, DistrustedIntermediate) { + auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3(); + InitializeVerifyProc( + /*additional_trust_anchors=*/{root->GetX509Certificate()}, + /*additional_distrusted_certificates=*/{ + intermediate->GetX509Certificate()}); + + scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain(); + ASSERT_TRUE(chain.get()); + + base::HistogramTester histogram_tester; + CertVerifyResult verify_result; + NetLogSource verify_net_log_source; + TestCompletionCallback callback; + Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result, + &verify_net_log_source, callback.callback()); + + int error = callback.WaitForResult(); + EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID)); + EXPECT_EQ(1u, verify_result.verified_cert->intermediate_buffers().size()); + EXPECT_THAT(histogram_tester.GetAllSamples( + "Net.CertVerifier.PathBuilderIterationCount"), + testing::ElementsAre(base::Bucket(/*min=*/2, /*count=*/1))); +} + TEST_F(CertVerifyProcBuiltinTest, CRLNotCheckedForKnownRoots) { auto [leaf, root] = CertBuilder::CreateSimpleChain2(); InitializeVerifyProc(
diff --git a/net/dns/host_cache.cc b/net/dns/host_cache.cc index 661e6556..1632c20 100644 --- a/net/dns/host_cache.cc +++ b/net/dns/host_cache.cc
@@ -29,6 +29,7 @@ #include "base/value_iterators.h" #include "net/base/address_family.h" #include "net/base/ip_endpoint.h" +#include "net/base/network_anonymization_key.h" #include "net/base/trace_constants.h" #include "net/base/tracing.h" #include "net/dns/host_resolver.h" @@ -921,7 +922,7 @@ continue; } } else { - // ToValue() fails for transient NIKs, since they should never be + // ToValue() fails for transient NAKs, since they should never be // serialized to disk in a restorable format, so use ToDebugString() when // serializing for debugging instead of for restoring from disk. network_anonymization_key_value =
diff --git a/net/dns/host_cache_unittest.cc b/net/dns/host_cache_unittest.cc index 01d0901..57de3ec 100644 --- a/net/dns/host_cache_unittest.cc +++ b/net/dns/host_cache_unittest.cc
@@ -1651,10 +1651,10 @@ ASSERT_EQ(1u, serialized_cache.size()); ASSERT_TRUE(serialized_cache[0].is_dict()); - const std::string* nik_string = + const std::string* nak_string = serialized_cache[0].GetDict().FindString("network_anonymization_key"); - ASSERT_TRUE(nik_string); - ASSERT_EQ(kNetworkAnonymizationKey.ToDebugString(), *nik_string); + ASSERT_TRUE(nak_string); + ASSERT_EQ(kNetworkAnonymizationKey.ToDebugString(), *nak_string); } TEST(HostCacheTest, SerializeAndDeserialize_Text) {
diff --git a/net/dns/host_resolver_cache.cc b/net/dns/host_resolver_cache.cc index 00871ce..eafd1c6 100644 --- a/net/dns/host_resolver_cache.cc +++ b/net/dns/host_resolver_cache.cc
@@ -28,7 +28,7 @@ namespace { -constexpr base::StringPiece kNikKey = "network_anonymization_key"; +constexpr base::StringPiece kNakKey = "network_anonymization_key"; constexpr base::StringPiece kSourceKey = "source"; constexpr base::StringPiece kSecureKey = "secure"; constexpr base::StringPiece kResultKey = "result"; @@ -196,7 +196,7 @@ return false; } - const base::Value* anonymization_key_value = dict->Find(kNikKey); + const base::Value* anonymization_key_value = dict->Find(kNakKey); NetworkAnonymizationKey anonymization_key; if (!anonymization_key_value || !NetworkAnonymizationKey::FromValue(*anonymization_key_value, @@ -441,7 +441,7 @@ } } - dict.Set(kNikKey, std::move(anonymization_key_value)); + dict.Set(kNakKey, std::move(anonymization_key_value)); dict.Set(kSourceKey, ToValue(entry.source)); dict.Set(kSecureKey, entry.secure); dict.Set(kResultKey, entry.result->ToValue());
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc index d8ceb1ac..79701db 100644 --- a/net/dns/host_resolver_manager_unittest.cc +++ b/net/dns/host_resolver_manager_unittest.cc
@@ -4250,7 +4250,7 @@ return config; } -// Check that entries are written to the cache with the right NIK. +// Check that entries are written to the cache with the right NAK. TEST_F(HostResolverManagerTest, NetworkAnonymizationKeyWriteToHostCache) { const SchemefulSite kSite1(GURL("https://origin1.test/")); const SchemefulSite kSite2(GURL("https://origin2.test/")); @@ -4365,7 +4365,7 @@ } } -// Check that entries are read to the cache with the right NIK. +// Check that entries are read to the cache with the right NAK. TEST_F(HostResolverManagerTest, NetworkAnonymizationKeyReadFromHostCache) { const SchemefulSite kSite1(GURL("https://origin1.test/")); const SchemefulSite kSite2(GURL("https://origin2.test/")); @@ -4385,7 +4385,7 @@ {kNetworkAnonymizationKey2, "192.168.1.44"}, }; - // Add entries to cache for the empty NIK, NIK1, and NIK2. Only the + // Add entries to cache for the empty NAK, NAK1, and NAK2. Only the // HostResolverManager obeys network state partitioning, so this is fine to do // regardless of the feature value. for (const auto& cache_entry : kCacheEntries) {
diff --git a/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc b/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc index 0fabd3c7..08a7d63 100644 --- a/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc +++ b/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc
@@ -702,8 +702,8 @@ // // For migration purposes, the NetworkAnonymizationKey field of the stored // policies will be populated with an empty list, which corresponds to an - // empty NIK. This matches the behavior when NIKs are disabled. This will - // result in effectively clearing all policies once NIKs are enabled, at + // empty NAK. This matches the behavior when NAKs are disabled. This will + // result in effectively clearing all policies once NAKs are enabled, at // which point the the migration code should just be switched to deleting // the old tables instead. if (cur_version == 1) {
diff --git a/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc b/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc index d840314..9567da9 100644 --- a/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc +++ b/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc
@@ -239,10 +239,10 @@ // from different sources. const NetworkAnonymizationKey kNak1_ = NetworkAnonymizationKey::CreateCrossSite( - SchemefulSite(GURL("https://top-frame-origin-nik1.test"))); + SchemefulSite(GURL("https://top-frame-origin-nak1.test"))); const NetworkAnonymizationKey kNak2_ = NetworkAnonymizationKey::CreateCrossSite( - SchemefulSite(GURL("https://top-frame-origin-nik2.test"))); + SchemefulSite(GURL("https://top-frame-origin-nak2.test"))); base::ScopedTempDir temp_dir_; std::unique_ptr<SQLitePersistentReportingAndNelStore> store_; @@ -771,9 +771,9 @@ TEST_F(SQLitePersistNelTest, ExpirationTimeIsPersisted) { const GURL kUrl("https://www.foo.test"); const url::Origin kOrigin = url::Origin::Create(kUrl); - const NetworkAnonymizationKey kNik; + const NetworkAnonymizationKey kNak; - service_->OnHeader(kNik, kOrigin, kServerIP, kHeader); + service_->OnHeader(kNak, kOrigin, kServerIP, kHeader); RunUntilIdle(); // Makes the policy we just added expired. @@ -781,17 +781,17 @@ SimulateRestart(); - service_->OnRequest(MakeRequestDetails(kNik, kUrl, ERR_INVALID_RESPONSE)); + service_->OnRequest(MakeRequestDetails(kNak, kUrl, ERR_INVALID_RESPONSE)); RunUntilIdle(); EXPECT_EQ(0u, reporting_service_->reports().size()); // Add the policy again so that it is not expired. - service_->OnHeader(kNik, kOrigin, kServerIP, kHeader); + service_->OnHeader(kNak, kOrigin, kServerIP, kHeader); SimulateRestart(); - service_->OnRequest(MakeRequestDetails(kNik, kUrl, ERR_INVALID_RESPONSE)); + service_->OnRequest(MakeRequestDetails(kNak, kUrl, ERR_INVALID_RESPONSE)); RunUntilIdle(); EXPECT_THAT(reporting_service_->reports(),
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index b3af8a2..ce15ef0 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -49,6 +49,8 @@ #include "net/base/load_timing_info.h" #include "net/base/load_timing_info_test_util.h" #include "net/base/net_errors.h" +#include "net/base/network_anonymization_key.h" +#include "net/base/network_isolation_key.h" #include "net/base/privacy_mode.h" #include "net/base/proxy_chain.h" #include "net/base/proxy_delegate.h" @@ -394,6 +396,8 @@ const HttpResponseHeaders& response_headers) override { return OK; } + void SetProxyResolutionService( + ProxyResolutionService* proxy_resolution_service) override {} size_t on_before_tunnel_request_call_count() const { return on_before_tunnel_request_call_count_; @@ -4594,10 +4598,10 @@ // Test the no-tunnel HTTP auth case where proxy and server origins and realms // are the same, but the user/passwords are different, and with different -// NetworkAnonymizationKeys. Sends one request with a NIK, response to both -// proxy and auth challenges, sends another request with another NIK, expecting +// NetworkAnonymizationKeys. Sends one request with a NAK, response to both +// proxy and auth challenges, sends another request with another NAK, expecting // only the proxy credentials to be cached, and thus sees only a server auth -// challenge. Then sends a request with the original NIK, expecting cached proxy +// challenge. Then sends a request with the original NAK, expecting cached proxy // and auth credentials that match the ones used in the first request. // // Serves to verify credentials are correctly separated based on @@ -4650,7 +4654,7 @@ "Proxy-Connection: keep-alive\r\n" "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n" "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), - // Another request to the same server and using the same NIK should + // Another request to the same server and using the same NAK should // preemptively send the correct cached proxy and server // auth headers. MockWrite("GET http://myproxy:70/ HTTP/1.1\r\n" @@ -4916,7 +4920,7 @@ "Host: myproxy:70\r\n" "Connection: keep-alive\r\n" "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"), - // Another request to the same server and using the same NIK should + // Another request to the same server and using the same NAK should // preemptively send the correct cached server // auth header. Since a tunnel was already established, the proxy headers // won't be sent again except when establishing another tunnel. @@ -4967,7 +4971,7 @@ "Proxy-Connection: keep-alive\r\n" "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), // Request over the tunnel, which gets a server auth challenge. Cached - // credentials cannot be used, since the NIK is different. + // credentials cannot be used, since the NAK is different. MockWrite("GET / HTTP/1.1\r\n" "Host: myproxy:70\r\n" "Connection: keep-alive\r\n\r\n"), @@ -27187,6 +27191,8 @@ const HttpResponseHeaders& response_headers) override { return OK; } + void SetProxyResolutionService( + ProxyResolutionService* proxy_resolution_service) override {} static std::string GetAuthorizationHeaderValue( const ProxyServer& proxy_server) {
diff --git a/net/http/http_server_properties.cc b/net/http/http_server_properties.cc index c6f77d1..455d55f 100644 --- a/net/http/http_server_properties.cc +++ b/net/http/http_server_properties.cc
@@ -18,6 +18,7 @@ #include "base/time/default_tick_clock.h" #include "base/values.h" #include "net/base/features.h" +#include "net/base/network_anonymization_key.h" #include "net/base/url_util.h" #include "net/http/http_network_session.h" #include "net/http/http_server_properties_manager.h"
diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h index 4477e16..71b7fe96 100644 --- a/net/http/http_server_properties.h +++ b/net/http/http_server_properties.h
@@ -644,7 +644,7 @@ IPAddress last_local_address_when_quic_worked_; // Contains a map of servers which could share the same alternate protocol. - // Map from a Canonical scheme/host/port/NIK (host is some postfix of host + // Map from a Canonical scheme/host/port/NAK (host is some postfix of host // names) to an actual origin, which has a plausible alternate protocol // mapping. CanonicalMap canonical_alt_svc_map_;
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc index df9247af7..db9a890 100644 --- a/net/http/http_server_properties_manager.cc +++ b/net/http/http_server_properties_manager.cc
@@ -18,6 +18,7 @@ #include "net/base/features.h" #include "net/base/host_port_pair.h" #include "net/base/ip_address.h" +#include "net/base/network_anonymization_key.h" #include "net/base/port_util.h" #include "net/base/privacy_mode.h" #include "net/http/http_server_properties.h" @@ -152,13 +153,13 @@ (server_id.privacy_mode_enabled() ? "/private" : ""); } -// Takes in a base::Value::Dict, and whether NetworkIsolationKeys are enabled -// for HttpServerProperties, and extracts the NetworkAnonymizationKey stored -// with the |kNetworkAnonymizationKey| in the dictionary, and writes it to -// |out_network_anonymization_key|. Returns false if unable to load a +// Takes in a base::Value::Dict, and whether NetworkAnonymizationKeys are +// enabled for HttpServerProperties, and extracts the NetworkAnonymizationKey +// stored with the `kNetworkAnonymizationKey` in the dictionary, and writes it +// to `out_network_anonymization_key`. Returns false if unable to load a // NetworkAnonymizationKey, or the NetworkAnonymizationKey is non-empty, but -// |use_network_anonymization_key| is false. -bool GetNetworkIsolationKeyFromDict( +// `use_network_anonymization_key` is false. +bool GetNetworkAnonymizationKeyFromDict( const base::Value::Dict& dict, bool use_network_anonymization_key, NetworkAnonymizationKey* out_network_anonymization_key) { @@ -171,8 +172,8 @@ return false; } - // Fail if NetworkIsolationKeys are disabled, but the entry has a non-empty - // NetworkAnonymizationKey. + // Fail if NetworkAnonymizationKeys are disabled, but the entry has a + // non-empty NetworkAnonymizationKey. if (!use_network_anonymization_key && !network_anonymization_key.IsEmpty()) return false; @@ -341,9 +342,9 @@ } NetworkAnonymizationKey network_anonymization_key; - if (!GetNetworkIsolationKeyFromDict(broken_alt_svc_entry_dict, - use_network_anonymization_key, - &network_anonymization_key)) { + if (!GetNetworkAnonymizationKeyFromDict(broken_alt_svc_entry_dict, + use_network_anonymization_key, + &network_anonymization_key)) { return; } @@ -409,9 +410,9 @@ // Get server's scheme/host/pair. const std::string* server_str = server_dict.FindString(kServerKey); NetworkAnonymizationKey network_anonymization_key; - // Can't load entry if server name missing, or if the network isolation key is - // missing or invalid. - if (!server_str || !GetNetworkIsolationKeyFromDict( + // Can't load entry if server name missing, or if the network anonymization + // key is missing or invalid. + if (!server_str || !GetNetworkAnonymizationKeyFromDict( server_dict, use_network_anonymization_key, &network_anonymization_key)) { return; @@ -661,9 +662,9 @@ } NetworkAnonymizationKey network_anonymization_key; - if (!GetNetworkIsolationKeyFromDict(*quic_server_info_dict, - use_network_anonymization_key, - &network_anonymization_key)) { + if (!GetNetworkAnonymizationKeyFromDict(*quic_server_info_dict, + use_network_anonymization_key, + &network_anonymization_key)) { DVLOG(1) << "Malformed http_server_properties quic server dict: " << *quic_server_id_str; continue; @@ -835,7 +836,7 @@ base::Value::List quic_servers_list; for (const auto& [key, server_info] : base::Reversed(quic_server_info_map)) { base::Value network_anonymization_key_value; - // Don't save entries with ephemeral NIKs. + // Don't save entries with ephemeral NAKs. if (!key.network_anonymization_key.ToValue( &network_anonymization_key_value)) { continue;
diff --git a/net/http/http_stream_factory_job_controller_unittest.cc b/net/http/http_stream_factory_job_controller_unittest.cc index a6d9079..24583eae 100644 --- a/net/http/http_stream_factory_job_controller_unittest.cc +++ b/net/http/http_stream_factory_job_controller_unittest.cc
@@ -50,6 +50,7 @@ #include "net/proxy_resolution/proxy_config_service_fixed.h" #include "net/proxy_resolution/proxy_info.h" #include "net/proxy_resolution/proxy_list.h" +#include "net/proxy_resolution/proxy_resolution_service.h" #include "net/quic/crypto/proof_verifier_chromium.h" #include "net/quic/mock_crypto_client_stream_factory.h" #include "net/quic/mock_quic_context.h" @@ -243,6 +244,8 @@ job_controller_ = nullptr; session_.reset(); + session_deps_.proxy_resolution_service->SetProxyDelegate(nullptr); + session_deps_ = SpdySessionDependencies( ConfiguredProxyResolutionService::CreateDirect()); session_deps_.enable_quic = true;
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins index b7616e5..d821d64 100644 --- a/net/http/transport_security_state_static.pins +++ b/net/http/transport_security_state_static.pins
@@ -43,9 +43,9 @@ # hash function for preloaded entries again (we have already done so once). # -# Last updated: 2023-12-17 12:54 UTC +# Last updated: 2023-12-19 12:55 UTC PinsListTimestamp -1702817676 +1702990535 TestSPKI sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/net/http/transport_security_state_static_pins.json b/net/http/transport_security_state_static_pins.json index 8a718a7..1fe2cc7f 100644 --- a/net/http/transport_security_state_static_pins.json +++ b/net/http/transport_security_state_static_pins.json
@@ -31,7 +31,7 @@ // the 'static_spki_hashes' and 'bad_static_spki_hashes' fields in 'pinsets' // refer to, and the timestamp at which the pins list was last updated. // -// Last updated: 2023-12-17 12:54 UTC +// Last updated: 2023-12-19 12:55 UTC // { "pinsets": [
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index 652995a..feace6a 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -3320,10 +3320,12 @@ // The event parameters are: // { // "certificate": <The PEM encoded certificate.> +// "spki": <The SPKI that this applies to> // "trust": <The trust setting used for this certificate.> // "errors": <Optionally, a string describing any errors or warnings // encountered while parsing the certificate.> // } +// Only one of certificate or spki will be provided, never both. EVENT_TYPE(CERT_VERIFY_PROC_ADDITIONAL_CERT) // This event is created for each path building attempt performed by
diff --git a/net/network_error_logging/network_error_logging_service.cc b/net/network_error_logging/network_error_logging_service.cc index 77afad3..500057b2 100644 --- a/net/network_error_logging/network_error_logging_service.cc +++ b/net/network_error_logging/network_error_logging_service.cc
@@ -23,6 +23,7 @@ #include "net/base/features.h" #include "net/base/ip_address.h" #include "net/base/net_errors.h" +#include "net/base/network_anonymization_key.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/base/url_util.h" #include "net/log/net_log.h" @@ -286,7 +287,7 @@ } private: - // Map from (NIK, origin) to owned policy. + // Map from (NAK, origin) to owned policy. using PolicyMap = std::map<NelPolicyKey, NelPolicy>; // Wildcard policies are policies for which the include_subdomains flag is @@ -300,7 +301,7 @@ // the longest host part (most specific subdomain) that is a substring of the // domain. // - // When multiple policies with the same (NIK, origin.host()) are present, they + // When multiple policies with the same (NAK, origin.host()) are present, they // are all stored, the policy returned is not well defined. // // Policies in the map are unowned; they are pointers to the original in
diff --git a/net/network_error_logging/network_error_logging_service.h b/net/network_error_logging/network_error_logging_service.h index 3b08f839..9532b6b 100644 --- a/net/network_error_logging/network_error_logging_service.h +++ b/net/network_error_logging/network_error_logging_service.h
@@ -44,7 +44,7 @@ public: class PersistentNelStore; - // Every (NIK, origin) pair can have at most one policy. + // Every (NAK, origin) pair can have at most one policy. struct NET_EXPORT NelPolicyKey { NelPolicyKey(); NelPolicyKey(const NetworkAnonymizationKey& network_anonymization_key, @@ -56,7 +56,7 @@ bool operator==(const NelPolicyKey& other) const; bool operator!=(const NelPolicyKey& other) const; - // The NIK of the request this policy was received from. This will be used + // The NAK of the request this policy was received from. This will be used // for any requests uploading reports according to this policy. (Not // included in the report itself.) NetworkAnonymizationKey network_anonymization_key; @@ -77,7 +77,7 @@ bool operator<(const WildcardNelPolicyKey& other) const; - // The NIK of the request this policy was received from. This will be used + // The NAK of the request this policy was received from. This will be used // for any requests uploading reports according to this policy. (Not // included in the report itself.) NetworkAnonymizationKey network_anonymization_key; @@ -282,7 +282,7 @@ // Used to display information about NEL policies on the NetLog Reporting tab. virtual base::Value StatusAsValue() const; - // Gets the (NIK, origin) keys of all currently stored policies, including + // Gets the (NAK, origin) keys of all currently stored policies, including // expired ones. virtual std::set<NelPolicyKey> GetPolicyKeysForTesting();
diff --git a/net/network_error_logging/network_error_logging_service_unittest.cc b/net/network_error_logging/network_error_logging_service_unittest.cc index c8f9164..1ed715ae 100644 --- a/net/network_error_logging/network_error_logging_service_unittest.cc +++ b/net/network_error_logging/network_error_logging_service_unittest.cc
@@ -17,6 +17,7 @@ #include "net/base/features.h" #include "net/base/ip_address.h" #include "net/base/net_errors.h" +#include "net/base/network_anonymization_key.h" #include "net/base/schemeful_site.h" #include "net/network_error_logging/mock_persistent_nel_store.h" #include "net/network_error_logging/network_error_logging_service.h" @@ -254,7 +255,7 @@ EXPECT_TRUE(reports().empty()); } -TEST_P(NetworkErrorLoggingServiceTest, PolicyKeyMatchesNikAndOrigin) { +TEST_P(NetworkErrorLoggingServiceTest, PolicyKeyMatchesNakAndOrigin) { service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeader_); // Make the rest of the test run synchronously. @@ -287,7 +288,7 @@ } TEST_P(NetworkErrorLoggingServiceTest, - PolicyKeyMatchesNikAndOriginIncludeSubdomains) { + PolicyKeyMatchesNakAndOriginIncludeSubdomains) { service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderIncludeSubdomains_); // Make the rest of the test run synchronously. @@ -348,7 +349,7 @@ } TEST_P(NetworkErrorLoggingServiceTest, - PolicyKeyMatchesNikAndOriginIncludeSubdomainsAndSuccess) { + PolicyKeyMatchesNakAndOriginIncludeSubdomainsAndSuccess) { service()->OnHeader(kNak_, kOrigin_, kServerIP_, kHeaderIncludeSubdomainsAndSuccess_);
diff --git a/net/proxy_resolution/configured_proxy_resolution_service.h b/net/proxy_resolution/configured_proxy_resolution_service.h index 25a508c9..49a62124f 100644 --- a/net/proxy_resolution/configured_proxy_resolution_service.h +++ b/net/proxy_resolution/configured_proxy_resolution_service.h
@@ -405,7 +405,7 @@ THREAD_CHECKER(thread_checker_); - raw_ptr<ProxyDelegate, DanglingUntriaged> proxy_delegate_ = nullptr; + raw_ptr<ProxyDelegate> proxy_delegate_ = nullptr; // Flag used by |SetReady()| to check if |this| has been deleted by a // synchronous callback.
diff --git a/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc b/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc index 23a8207..cf6a667 100644 --- a/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc +++ b/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc
@@ -254,6 +254,9 @@ return OK; } + void SetProxyResolutionService( + ProxyResolutionService* proxy_resolution_service) override {} + private: int num_resolve_proxy_called_ = 0; bool add_proxy_ = false; @@ -290,6 +293,9 @@ return OK; } + void SetProxyResolutionService( + ProxyResolutionService* proxy_resolution_service) override {} + bool num_proxy_fallback_called() const { return num_proxy_fallback_called_; } const ProxyChain& proxy_chain() const { return proxy_chain_; }
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index cbcddcd..18b525b2 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc
@@ -35,6 +35,7 @@ #include "net/base/features.h" #include "net/base/ip_address.h" #include "net/base/net_errors.h" +#include "net/base/network_anonymization_key.h" #include "net/base/trace_constants.h" #include "net/base/tracing.h" #include "net/cert/cert_verifier.h"
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h index 71583e4..78aa7c1 100644 --- a/net/quic/quic_stream_factory.h +++ b/net/quic/quic_stream_factory.h
@@ -718,13 +718,13 @@ const raw_ptr<SSLConfigService> ssl_config_service_; // Whether NetworkAnonymizationKeys should be used for - // |active_crypto_config_map_|. If false, there will just be one config with + // `active_crypto_config_map_`. If false, there will just be one config with // an empty NetworkAnonymizationKey. Whether QuicSessionAliasKeys all have an - // empty NIK is based on whether socket pools are respecting NIKs, but whether - // those NIKs are also used when accessing |active_crypto_config_map_| is also + // empty NAK is based on whether socket pools are respecting NAKs, but whether + // those NAKs are also used when accessing `active_crypto_config_map_` is also // gated this, which is set based on whether HttpServerProperties is - // respecting NIKs, as that data is fed into the crypto config map using the - // corresponding NIK. + // respecting NAKs, as that data is fed into the crypto config map using the + // corresponding NAK. const bool use_network_anonymization_key_for_crypto_configs_; quic::DeterministicConnectionIdGenerator connection_id_generator_{
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index d09dd9e..3b53f58 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc
@@ -12953,7 +12953,7 @@ EXPECT_EQ(kUserAgentId1, crypto_config_handle1->GetConfig()->user_agent_id()); EXPECT_EQ(kUserAgentId2, crypto_config_handle2->GetConfig()->user_agent_id()); - // Creating handles with the same NIKs while the old handles are still alive + // Creating handles with the same NAKs while the old handles are still alive // should result in getting the same CryptoConfigs. std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle1_2 = QuicStreamFactoryPeer::GetCryptoConfig(factory_.get(), @@ -12982,7 +12982,7 @@ crypto_config_handle3.reset(); // The old CryptoConfigs should be recovered when creating handles with the - // same NIKs as before. + // same NAKs as before. crypto_config_handle2 = QuicStreamFactoryPeer::GetCryptoConfig( factory_.get(), kNetworkAnonymizationKey2); crypto_config_handle1 = QuicStreamFactoryPeer::GetCryptoConfig( @@ -13036,7 +13036,7 @@ EXPECT_EQ(base::NumberToString(i), crypto_config_handles[i]->GetConfig()->user_agent_id()); - // A new handle for the same NIK returns the same crypto config. + // A new handle for the same NAK returns the same crypto config. std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle = QuicStreamFactoryPeer::GetCryptoConfig(factory_.get(), network_anonymization_keys[i]); @@ -13044,7 +13044,7 @@ crypto_config_handle->GetConfig()->user_agent_id()); } - // Destroying the only remaining handle for a NIK results in evicting entries, + // Destroying the only remaining handle for a NAK results in evicting entries, // until there are exactly |kMaxRecentCryptoConfigs| handles. for (int i = 0; i < kNumSessionsToMake; ++i) { SCOPED_TRACE(i); @@ -13053,7 +13053,7 @@ crypto_config_handles[i].reset(); - // A new handle for the same NIK will return a new config, if the config was + // A new handle for the same NAK will return a new config, if the config was // evicted. Otherwise, it will return the same one. std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle = QuicStreamFactoryPeer::GetCryptoConfig(factory_.get(),
diff --git a/net/reporting/README.md b/net/reporting/README.md index 34eea769..3d58efb 100644 --- a/net/reporting/README.md +++ b/net/reporting/README.md
@@ -132,7 +132,7 @@ any successful document load. All V0 reports destined for the same endpoint group may be bundled together for -delivery, regardless of their source (subject to NIK isolation). +delivery, regardless of their source (subject to NAK isolation). V1 reporting drops the `Report-To` header in favor of `Reporting-Endpoints`, which configures named endpoints (single URLs) which are only valid for the
diff --git a/net/reporting/reporting_browsing_data_remover_unittest.cc b/net/reporting/reporting_browsing_data_remover_unittest.cc index 73cdda9..8ba5380 100644 --- a/net/reporting/reporting_browsing_data_remover_unittest.cc +++ b/net/reporting/reporting_browsing_data_remover_unittest.cc
@@ -41,14 +41,14 @@ } } - // TODO(chlily): Take NIK. + // TODO(chlily): Take NAK. void AddReport(const GURL& url) { cache()->AddReport(absl::nullopt, NetworkAnonymizationKey(), url, kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(), 0); } - // TODO(chlily): Take NIK. + // TODO(chlily): Take NAK. void SetEndpoint(const url::Origin& origin) { SetEndpointInCache( ReportingEndpointGroupKey(NetworkAnonymizationKey(), origin, kGroup_),
diff --git a/net/reporting/reporting_cache.h b/net/reporting/reporting_cache.h index 6f8922b..905a6f8 100644 --- a/net/reporting/reporting_cache.h +++ b/net/reporting/reporting_cache.h
@@ -28,6 +28,7 @@ class ReportingContext; class IsolationInfo; +class NetworkAnonymizationKey; // The cache holds undelivered reports and clients (per-origin endpoint // configurations) in memory. (It is not responsible for persisting them.) @@ -184,7 +185,7 @@ // Gets all the origins of clients in the cache. virtual std::set<url::Origin> GetAllOrigins() const = 0; - // Remove client for the given (NIK, origin) pair, if it exists in the cache. + // Remove client for the given (NAK, origin) pair, if it exists in the cache. // All endpoint groups and endpoints for that client are also removed. virtual void RemoveClient( const NetworkAnonymizationKey& network_anonymization_key, @@ -281,7 +282,7 @@ OriginSubdomains include_subdomains, base::Time expires) const = 0; - // Returns whether a client for the given (NIK, Origin) exists. + // Returns whether a client for the given (NAK, Origin) exists. virtual bool ClientExistsForTesting( const NetworkAnonymizationKey& network_anonymization_key, const url::Origin& origin) const = 0;
diff --git a/net/reporting/reporting_cache_impl.cc b/net/reporting/reporting_cache_impl.cc index 6efc2507..067a5bd 100644 --- a/net/reporting/reporting_cache_impl.cc +++ b/net/reporting/reporting_cache_impl.cc
@@ -14,6 +14,7 @@ #include "base/stl_util.h" #include "base/time/clock.h" #include "base/time/tick_clock.h" +#include "net/base/network_anonymization_key.h" #include "net/base/url_util.h" #include "net/log/net_log.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -382,7 +383,7 @@ // Creates an endpoint group and sets its |last_used| to |now|. CachedReportingEndpointGroup new_group(parsed_endpoint_group, now); - // Consistency check: the new client should have the same NIK and origin as + // Consistency check: the new client should have the same NAK and origin as // all groups parsed from this header. DCHECK(new_group.group_key.network_anonymization_key == new_client.network_anonymization_key); @@ -1020,7 +1021,7 @@ auto inserted = nik_origin_pairs_in_cache.insert( std::make_pair(client.network_anonymization_key, client.origin)); - // We have not seen a duplicate client with the same NIK and origin. + // We have not seen a duplicate client with the same NAK and origin. DCHECK(inserted.second); } @@ -1179,7 +1180,7 @@ ClientMap::iterator client_it = FindClientIt(new_client.network_anonymization_key, new_client.origin); - // Add a new client for this NIK and origin. + // Add a new client for this NAK and origin. if (client_it == clients_.end()) { std::string domain = new_client.origin.host(); client_it = clients_.insert( @@ -1445,7 +1446,7 @@ DCHECK(client_it != clients_.end()); size_t client_endpoint_count = client_it->second.endpoint_count; // TODO(chlily): This is actually a limit on the endpoints for a given client - // (for a NIK, origin pair). Rename this. + // (for a NAK, origin pair). Rename this. size_t max_endpoints_per_origin = context_->policy().max_endpoints_per_origin; if (client_endpoint_count > max_endpoints_per_origin) { EvictEndpointsFromClient(client_it,
diff --git a/net/reporting/reporting_cache_impl.h b/net/reporting/reporting_cache_impl.h index 6394955..46e7aec7 100644 --- a/net/reporting/reporting_cache_impl.h +++ b/net/reporting/reporting_cache_impl.h
@@ -22,6 +22,7 @@ #include "base/unguessable_token.h" #include "base/values.h" #include "net/base/isolation_info.h" +#include "net/base/network_anonymization_key.h" #include "net/reporting/reporting_cache.h" #include "net/reporting/reporting_context.h" #include "net/reporting/reporting_endpoint.h" @@ -138,7 +139,7 @@ const ReportingEndpoint& endpoint) const override; private: - // Represents the entire Report-To configuration for a (NIK, origin) pair. + // Represents the entire Report-To configuration for a (NAK, origin) pair. struct Client { Client(const NetworkAnonymizationKey& network_anonymization_key, const url::Origin& origin); @@ -151,7 +152,7 @@ ~Client(); - // NIK of the context associated with this client. Needed to prevent leaking + // NAK of the context associated with this client. Needed to prevent leaking // third party contexts across sites. NetworkAnonymizationKey network_anonymization_key; @@ -242,7 +243,7 @@ const ReportingEndpointGroupKey& group_key, const std::set<GURL>& endpoints_to_keep_urls); - // Remove all the endpoint groups for the NIK and origin whose names are not + // Remove all the endpoint groups for the NAK and origin whose names are not // in |groups_to_keep_names|. Does not guarantee that all the groups in // |groups_to_keep_names| exist in the cache for that client. void RemoveEndpointGroupsForClientOtherThan( @@ -357,8 +358,8 @@ // configured through the Report-To HTTP header, and are currently used for // both document and network reports. - // Map of clients for all configured origins and NIKs, keyed on domain name - // (there may be multiple NIKs and origins per domain name). + // Map of clients for all configured origins and NAKs, keyed on domain name + // (there may be multiple NAKs and origins per domain name). ClientMap clients_; // Map of endpoint groups, keyed on origin and group name. Keys and values
diff --git a/net/reporting/reporting_delivery_agent.cc b/net/reporting/reporting_delivery_agent.cc index 4adb28e..f131acb 100644 --- a/net/reporting/reporting_delivery_agent.cc +++ b/net/reporting/reporting_delivery_agent.cc
@@ -81,15 +81,15 @@ // Note that |origin| here (which matches the report's |origin|) is not // necessarily the same as the |origin| of the ReportingEndpoint's group key // (if the endpoint is configured to include subdomains). Reports with - // different group keys can be in the same delivery, as long as the NIK, + // different group keys can be in the same delivery, as long as the NAK, // report origin and reporting source are the same, and they all get assigned // to the same endpoint URL. // |isolation_info| is the IsolationInfo struct associated with the reporting // endpoint, and is used to determine appropriate credentials for the upload. - // |network_anonymization_key| is the NIK from the ReportingEndpoint, which + // |network_anonymization_key| is the NAK from the ReportingEndpoint, which // may have been cleared in the ReportingService if reports are not being - // partitioned by NIK. (This is why a separate parameter is used here, rather - // than simply using the computed NIK from |isolation_info|.) + // partitioned by NAK. (This is why a separate parameter is used here, rather + // than simply using the computed NAK from |isolation_info|.) struct Target { Target(const IsolationInfo& isolation_info, const NetworkAnonymizationKey& network_anonymization_key, @@ -109,7 +109,7 @@ ~Target() = default; bool operator<(const Target& other) const { - // Note that sorting by NIK here is required for V0 reports; V1 reports + // Note that sorting by NAK here is required for V0 reports; V1 reports // should not need this (but it doesn't hurt). We can remove that as a // comparison key when V0 reporting endpoints are removed. return std::tie(network_anonymization_key, origin, endpoint_url, @@ -378,9 +378,9 @@ delivery->network_anonymization_key(), delivery->endpoint_url(), success); - // TODO(chlily): This leaks information across NIKs. If the endpoint URL is - // configured for both NIK1 and NIK2, and it responds with a 410 on a NIK1 - // connection, then the change in configuration will be detectable on a NIK2 + // TODO(chlily): This leaks information across NAKs. If the endpoint URL is + // configured for both NAK1 and NAK2, and it responds with a 410 on a NAK1 + // connection, then the change in configuration will be detectable on a NAK2 // connection. // TODO(rodneyding): Handle Remove endpoint for Reporting-Endpoints header. if (outcome == ReportingUploader::Outcome::REMOVE_ENDPOINT)
diff --git a/net/reporting/reporting_delivery_agent.h b/net/reporting/reporting_delivery_agent.h index 470be91c..b25ad92 100644 --- a/net/reporting/reporting_delivery_agent.h +++ b/net/reporting/reporting_delivery_agent.h
@@ -27,13 +27,13 @@ // - Uploads are allowed for the report's origin (i.e. the origin of the URL // associated with the reported event). // - There is not already a pending upload for any reports sharing the same -// (NIK, origin, group) key. +// (NAK, origin, group) key. // // Reports are batched for upload to an endpoint URL such that: -// - The available reports with the same (NIK, origin, group) are always +// - The available reports with the same (NAK, origin, group) are always // uploaded together. -// - All reports uploaded together must share a NIK and origin. -// - Reports for the same (NIK, origin) can be uploaded separately if they are +// - All reports uploaded together must share a NAK and origin. +// - Reports for the same (NAK, origin) can be uploaded separately if they are // for different groups. // - Reports for different groups can be batched together, if they are assigned // to ReportingEndpoints sharing a URL (that is, the upload URL).
diff --git a/net/reporting/reporting_delivery_agent_unittest.cc b/net/reporting/reporting_delivery_agent_unittest.cc index abdaf2b..68b76b1 100644 --- a/net/reporting/reporting_delivery_agent_unittest.cc +++ b/net/reporting/reporting_delivery_agent_unittest.cc
@@ -90,7 +90,7 @@ // has matching reporting_source. void UploadFirstDocumentReportAndStartTimer() { ReportingEndpointGroupKey dummy_group( - kNik_, kDocumentReportingSource_, + kNak_, kDocumentReportingSource_, url::Origin::Create(GURL("https://dummy.test")), "dummy"); SetV1EndpointInCache(dummy_group, kDocumentReportingSource_, kIsolationInfo_, GURL("https://dummy.test/upload")); @@ -119,9 +119,9 @@ absl::nullopt; const base::UnguessableToken kDocumentReportingSource_ = base::UnguessableToken::Create(); - const NetworkAnonymizationKey kNik_ = + const NetworkAnonymizationKey kNak_ = NetworkAnonymizationKey::CreateSameSite(SchemefulSite(kOrigin_)); - const NetworkAnonymizationKey kOtherNik_ = + const NetworkAnonymizationKey kOtherNak_ = NetworkAnonymizationKey::CreateSameSite(SchemefulSite(kOtherOrigin_)); const IsolationInfo kIsolationInfo_ = IsolationInfo::Create(IsolationInfo::RequestType::kOther, @@ -139,7 +139,7 @@ const std::string kType_ = "type"; const base::Time kExpires_ = base::Time::Now() + base::Days(7); const ReportingEndpointGroupKey kGroupKey_ = - ReportingEndpointGroupKey(kNik_, kOrigin_, kGroup_); + ReportingEndpointGroupKey(kNak_, kOrigin_, kGroup_); const ReportingEndpointGroupKey kDocumentGroupKey_ = ReportingEndpointGroupKey(kGroupKey_, kDocumentReportingSource_); }; @@ -147,7 +147,7 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUpload) { base::HistogramTester histograms; ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); // Upload is automatically started when cache is modified. @@ -205,7 +205,7 @@ ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); // Add and upload a report with an associated source. - AddReport(kDocumentReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kDocumentReportingSource_, kNak_, kUrl_, kGroup_); pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); // Successful upload should count this as a Report-To delivery, even though @@ -224,7 +224,7 @@ SetV1EndpointInCache(kDocumentGroupKey_, kDocumentReportingSource_, kIsolationInfo_, kEndpoint_); - AddReport(kDocumentReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kDocumentReportingSource_, kNak_, kUrl_, kGroup_); // Upload is automatically started when cache is modified. @@ -277,10 +277,10 @@ SetV1EndpointInCache(kDocumentGroupKey_, kDocumentReportingSource_, kIsolationInfo_, kEndpoint_); - AddReport(kDocumentReportingSource_, kNik_, kUrl_, kGroup_); - AddReport(kDocumentReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kDocumentReportingSource_, kNak_, kUrl_, kGroup_); + AddReport(kDocumentReportingSource_, kNak_, kUrl_, kGroup_); - // There should be one upload per (NIK, origin, reporting source). + // There should be one upload per (NAK, origin, reporting source). EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -303,7 +303,7 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateSubdomainUpload) { ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_, OriginSubdomains::INCLUDE)); - AddReport(kEmptyReportingSource_, kNik_, kSubdomainUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kSubdomainUrl_, kGroup_); // Upload is automatically started when cache is modified. @@ -350,7 +350,7 @@ SuccessfulImmediateSubdomainUploadWithOverwrittenEndpoint) { ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_, OriginSubdomains::INCLUDE)); - AddReport(kEmptyReportingSource_, kNik_, kSubdomainUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kSubdomainUrl_, kGroup_); // Upload is automatically started when cache is modified. @@ -378,11 +378,11 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulDelayedUpload) { // Trigger and complete an upload to start the delivery timer. ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); // Add another report to upload after a delay. - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -428,7 +428,7 @@ TEST_F(ReportingDeliveryAgentTest, FailedUpload) { ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -476,7 +476,7 @@ static const int kAgeMillis = 12345; ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); tick_clock()->Advance(base::Milliseconds(kAgeMillis)); @@ -503,13 +503,13 @@ } TEST_F(ReportingDeliveryAgentTest, RemoveEndpointUpload) { - static const ReportingEndpointGroupKey kOtherGroupKey(kNik_, kOtherOrigin_, + static const ReportingEndpointGroupKey kOtherGroupKey(kNak_, kOtherOrigin_, kGroup_); ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); ASSERT_TRUE(SetEndpointInCache(kOtherGroupKey, kEndpoint_, kExpires_)); - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -536,7 +536,7 @@ TEST_F(ReportingDeliveryAgentTest, ConcurrentRemove) { ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -570,7 +570,7 @@ context()->test_delegate()->set_pause_permissions_check(true); ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); ASSERT_TRUE(context()->test_delegate()->PermissionsCheckPaused()); @@ -596,16 +596,16 @@ EXPECT_TRUE(reports.empty()); } -// Reports uploaded together must share a NIK and origin. +// Reports uploaded together must share a NAK and origin. // Test that the agent will not combine reports destined for the same endpoint -// if the reports are from different origins or NIKs, but does combine all -// reports for the same (NIK, origin). -TEST_F(ReportingDeliveryAgentTest, OnlyBatchSameNikAndOrigin) { +// if the reports are from different origins or NAKs, but does combine all +// reports for the same (NAK, origin). +TEST_F(ReportingDeliveryAgentTest, OnlyBatchSameNakAndOrigin) { const ReportingEndpointGroupKey kGroupKeys[] = { - ReportingEndpointGroupKey(kNik_, kOrigin_, kGroup_), - ReportingEndpointGroupKey(kNik_, kOtherOrigin_, kGroup_), - ReportingEndpointGroupKey(kOtherNik_, kOrigin_, kGroup_), - ReportingEndpointGroupKey(kOtherNik_, kOtherOrigin_, kGroup_), + ReportingEndpointGroupKey(kNak_, kOrigin_, kGroup_), + ReportingEndpointGroupKey(kNak_, kOtherOrigin_, kGroup_), + ReportingEndpointGroupKey(kOtherNak_, kOrigin_, kGroup_), + ReportingEndpointGroupKey(kOtherNak_, kOtherOrigin_, kGroup_), }; for (const ReportingEndpointGroupKey& group_key : kGroupKeys) { ASSERT_TRUE(SetEndpointInCache(group_key, kEndpoint_, kExpires_)); @@ -616,19 +616,19 @@ // Now that the delivery timer is running, these reports won't be immediately // uploaded. - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); - AddReport(kEmptyReportingSource_, kNik_, kOtherUrl_, kGroup_); - AddReport(kEmptyReportingSource_, kNik_, kOtherUrl_, kGroup_); - AddReport(kEmptyReportingSource_, kOtherNik_, kUrl_, kGroup_); - AddReport(kEmptyReportingSource_, kOtherNik_, kUrl_, kGroup_); - AddReport(kEmptyReportingSource_, kOtherNik_, kUrl_, kGroup_); - AddReport(kEmptyReportingSource_, kOtherNik_, kOtherUrl_, kGroup_); - AddReport(kEmptyReportingSource_, kOtherNik_, kOtherUrl_, kGroup_); - AddReport(kEmptyReportingSource_, kOtherNik_, kOtherUrl_, kGroup_); - AddReport(kEmptyReportingSource_, kOtherNik_, kOtherUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kOtherUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kOtherUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kOtherNak_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kOtherNak_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kOtherNak_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kOtherNak_, kOtherUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kOtherNak_, kOtherUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kOtherNak_, kOtherUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kOtherNak_, kOtherUrl_, kGroup_); EXPECT_EQ(0u, pending_uploads().size()); - // There should be one upload per (NIK, origin). + // There should be one upload per (NAK, origin). EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); ASSERT_EQ(4u, pending_uploads().size()); @@ -649,9 +649,9 @@ } } -// Test that the agent won't start a second upload for a (NIK, origin, group) +// Test that the agent won't start a second upload for a (NAK, origin, group) // while one is pending, even if a different endpoint is available, but will -// once the original delivery is complete and the (NIK, origin, group) is no +// once the original delivery is complete and the (NAK, origin, group) is no // longer pending. TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToGroup) { static const GURL kDifferentEndpoint("https://endpoint2/"); @@ -663,14 +663,14 @@ UploadFirstReportAndStartTimer(); // First upload causes this group key to become pending. - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); EXPECT_EQ(0u, pending_uploads().size()); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); EXPECT_EQ(1u, pending_uploads().size()); // Second upload isn't started because the group is pending. - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); @@ -700,11 +700,11 @@ } // Tests that the agent will start parallel uploads to different groups within -// the same (NIK, origin) to endpoints with different URLs. +// the same (NAK, origin) to endpoints with different URLs. TEST_F(ReportingDeliveryAgentTest, ParallelizeUploadsAcrossGroups) { static const GURL kDifferentEndpoint("https://endpoint2/"); static const std::string kDifferentGroup("group2"); - const ReportingEndpointGroupKey kDifferentGroupKey(kNik_, kOrigin_, + const ReportingEndpointGroupKey kDifferentGroupKey(kNak_, kOrigin_, kDifferentGroup); ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); @@ -714,8 +714,8 @@ // Trigger and complete an upload to start the delivery timer. UploadFirstReportAndStartTimer(); - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kDifferentGroup); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kDifferentGroup); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -744,11 +744,11 @@ } // Tests that the agent will include reports for different groups for the same -// (NIK, origin) in the same upload if they are destined for the same endpoint +// (NAK, origin) in the same upload if they are destined for the same endpoint // URL. TEST_F(ReportingDeliveryAgentTest, BatchReportsAcrossGroups) { static const std::string kDifferentGroup("group2"); - const ReportingEndpointGroupKey kDifferentGroupKey(kNik_, kOrigin_, + const ReportingEndpointGroupKey kDifferentGroupKey(kNak_, kOrigin_, kDifferentGroup); ASSERT_TRUE(SetEndpointInCache(kGroupKey_, kEndpoint_, kExpires_)); @@ -756,8 +756,8 @@ UploadFirstReportAndStartTimer(); - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kGroup_); - AddReport(kEmptyReportingSource_, kNik_, kUrl_, kDifferentGroup); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kGroup_); + AddReport(kEmptyReportingSource_, kNak_, kUrl_, kDifferentGroup); EXPECT_TRUE(delivery_timer()->IsRunning()); delivery_timer()->Fire(); @@ -812,15 +812,15 @@ // Set up identical endpoint configuration for kReportingSource1 and // kReportingSource2. kReportingSource3 is independent. - const ReportingEndpointGroupKey kGroup1Key1(kNik_, kReportingSource1, + const ReportingEndpointGroupKey kGroup1Key1(kNak_, kReportingSource1, kOrigin_, kGroup_); - const ReportingEndpointGroupKey kGroup2Key1(kNik_, kReportingSource1, + const ReportingEndpointGroupKey kGroup2Key1(kNak_, kReportingSource1, kOrigin_, kGroup2); - const ReportingEndpointGroupKey kGroup1Key2(kNik_, kReportingSource2, + const ReportingEndpointGroupKey kGroup1Key2(kNak_, kReportingSource2, kOrigin_, kGroup_); - const ReportingEndpointGroupKey kGroup2Key2(kNik_, kReportingSource2, + const ReportingEndpointGroupKey kGroup2Key2(kNak_, kReportingSource2, kOrigin_, kGroup2); - const ReportingEndpointGroupKey kOtherGroupKey(kOtherNik_, kReportingSource3, + const ReportingEndpointGroupKey kOtherGroupKey(kOtherNak_, kReportingSource3, kOtherOrigin_, kGroup_); SetV1EndpointInCache(kGroup1Key1, kReportingSource1, kIsolationInfo1, kUrl_); @@ -832,10 +832,10 @@ UploadFirstReportAndStartTimer(); - AddReport(kReportingSource1, kNik_, kUrl_, kGroup_); - AddReport(kReportingSource1, kNik_, kUrl_, kGroup2); - AddReport(kReportingSource2, kNik_, kUrl_, kGroup_); - AddReport(kReportingSource3, kOtherNik_, kUrl_, kGroup_); + AddReport(kReportingSource1, kNak_, kUrl_, kGroup_); + AddReport(kReportingSource1, kNak_, kUrl_, kGroup2); + AddReport(kReportingSource2, kNak_, kUrl_, kGroup_); + AddReport(kReportingSource3, kOtherNak_, kUrl_, kGroup_); // There should be four queued reports at this point. EXPECT_EQ(4u, cache()->GetReportCountWithStatusForTesting( @@ -882,15 +882,15 @@ // Set up identical endpoint configuration for kReportingSource1 and // kReportingSource2. kReportingSource3 is independent. - const ReportingEndpointGroupKey kGroup1Key1(kNik_, kReportingSource1, + const ReportingEndpointGroupKey kGroup1Key1(kNak_, kReportingSource1, kOrigin_, kGroup_); - const ReportingEndpointGroupKey kGroup2Key1(kNik_, kReportingSource1, + const ReportingEndpointGroupKey kGroup2Key1(kNak_, kReportingSource1, kOrigin_, kGroup2); - const ReportingEndpointGroupKey kGroup1Key2(kNik_, kReportingSource2, + const ReportingEndpointGroupKey kGroup1Key2(kNak_, kReportingSource2, kOrigin_, kGroup_); - const ReportingEndpointGroupKey kGroup2Key2(kNik_, kReportingSource2, + const ReportingEndpointGroupKey kGroup2Key2(kNak_, kReportingSource2, kOrigin_, kGroup2); - const ReportingEndpointGroupKey kOtherGroupKey(kOtherNik_, kReportingSource3, + const ReportingEndpointGroupKey kOtherGroupKey(kOtherNak_, kReportingSource3, kOtherOrigin_, kGroup_); SetV1EndpointInCache(kGroup1Key1, kReportingSource1, kIsolationInfo1, kUrl_); @@ -902,10 +902,10 @@ UploadFirstReportAndStartTimer(); - AddReport(kReportingSource1, kNik_, kUrl_, kGroup_); - AddReport(kReportingSource1, kNik_, kUrl_, kGroup2); - AddReport(kReportingSource2, kNik_, kUrl_, kGroup_); - AddReport(kReportingSource3, kOtherNik_, kUrl_, kGroup_); + AddReport(kReportingSource1, kNak_, kUrl_, kGroup_); + AddReport(kReportingSource1, kNak_, kUrl_, kGroup2); + AddReport(kReportingSource2, kNak_, kUrl_, kGroup_); + AddReport(kReportingSource3, kOtherNak_, kUrl_, kGroup_); // There should be four queued reports at this point. EXPECT_EQ(4u, cache()->GetReportCountWithStatusForTesting(
diff --git a/net/reporting/reporting_endpoint.cc b/net/reporting/reporting_endpoint.cc index 1405aff..eb62f5c8 100644 --- a/net/reporting/reporting_endpoint.cc +++ b/net/reporting/reporting_endpoint.cc
@@ -8,6 +8,7 @@ #include <tuple> #include "base/time/time.h" +#include "net/base/network_anonymization_key.h" #include "url/gurl.h" #include "url/origin.h" @@ -90,7 +91,7 @@ std::string ReportingEndpointGroupKey::ToString() const { return "Source: " + (reporting_source ? reporting_source->ToString() : "null") + - "; NIK: " + network_anonymization_key.ToDebugString() + + "; NAK: " + network_anonymization_key.ToDebugString() + "; Origin: " + origin.Serialize() + "; Group name: " + group_name; }
diff --git a/net/reporting/reporting_endpoint_manager_unittest.cc b/net/reporting/reporting_endpoint_manager_unittest.cc index d870224a..2e398b1 100644 --- a/net/reporting/reporting_endpoint_manager_unittest.cc +++ b/net/reporting/reporting_endpoint_manager_unittest.cc
@@ -282,12 +282,12 @@ ReportingEndpoint::EndpointInfo{endpoint, priority, weight})); } - const NetworkAnonymizationKey kNik; + const NetworkAnonymizationKey kNak; const url::Origin kOrigin = url::Origin::Create(GURL("https://origin/")); const SchemefulSite kSite = SchemefulSite(kOrigin); const std::string kGroup = "group"; const ReportingEndpointGroupKey kGroupKey = - ReportingEndpointGroupKey(kNik, kOrigin, kGroup); + ReportingEndpointGroupKey(kNak, kOrigin, kGroup); const GURL kEndpoint = GURL("https://endpoint/"); ReportingPolicy policy_;
diff --git a/net/reporting/reporting_garbage_collector_unittest.cc b/net/reporting/reporting_garbage_collector_unittest.cc index baeb01a5..c9b07fd 100644 --- a/net/reporting/reporting_garbage_collector_unittest.cc +++ b/net/reporting/reporting_garbage_collector_unittest.cc
@@ -31,7 +31,7 @@ const absl::optional<base::UnguessableToken> kReportingSource_ = base::UnguessableToken::Create(); - const NetworkAnonymizationKey kNik_; + const NetworkAnonymizationKey kNak_; const IsolationInfo kIsolationInfo_; const GURL kUrl_ = GURL("https://origin/path"); const std::string kUserAgent_ = "Mozilla/1.0"; @@ -48,7 +48,7 @@ TEST_F(ReportingGarbageCollectorTest, Timer) { EXPECT_FALSE(garbage_collection_timer()->IsRunning()); - cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_, + cache()->AddReport(absl::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(), 0); EXPECT_TRUE(garbage_collection_timer()->IsRunning()); @@ -59,7 +59,7 @@ } TEST_F(ReportingGarbageCollectorTest, Report) { - cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_, + cache()->AddReport(absl::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(), 0); garbage_collection_timer()->Fire(); @@ -67,7 +67,7 @@ } TEST_F(ReportingGarbageCollectorTest, ExpiredReport) { - cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_, + cache()->AddReport(absl::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(), 0); tick_clock()->Advance(2 * policy().max_report_age); garbage_collection_timer()->Fire(); @@ -76,7 +76,7 @@ } TEST_F(ReportingGarbageCollectorTest, FailedReport) { - cache()->AddReport(absl::nullopt, kNik_, kUrl_, kUserAgent_, kGroup_, kType_, + cache()->AddReport(absl::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(), 0); std::vector<const ReportingReport*> reports; @@ -91,7 +91,7 @@ } TEST_F(ReportingGarbageCollectorTest, ExpiredSource) { - ReportingEndpointGroupKey group_key(kNik_, kReportingSource_, + ReportingEndpointGroupKey group_key(kNak_, kReportingSource_, url::Origin::Create(kUrl_), kGroup_); cache()->SetV1EndpointForTesting(group_key, *kReportingSource_, kIsolationInfo_, kUrl_); @@ -111,11 +111,11 @@ } TEST_F(ReportingGarbageCollectorTest, ExpiredSourceWithPendingReports) { - ReportingEndpointGroupKey group_key(kNik_, kReportingSource_, + ReportingEndpointGroupKey group_key(kNak_, kReportingSource_, url::Origin::Create(kUrl_), kGroup_); cache()->SetV1EndpointForTesting(group_key, *kReportingSource_, kIsolationInfo_, kUrl_); - cache()->AddReport(kReportingSource_, kNik_, kUrl_, kUserAgent_, kGroup_, + cache()->AddReport(kReportingSource_, kNak_, kUrl_, kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0, tick_clock()->NowTicks(), 0); // Mark the source as expired. The source data should be removed as soon as
diff --git a/net/reporting/reporting_header_parser.h b/net/reporting/reporting_header_parser.h index 3ca9980..76ff3b21 100644 --- a/net/reporting/reporting_header_parser.h +++ b/net/reporting/reporting_header_parser.h
@@ -53,8 +53,8 @@ const base::Value::List& list); // `isolation_info` here will be stored in the cache, associated with the - // `reporting_source`. `network_anonymization_key` is the NIK which will be - // passed in with reports to be queued. This must match the NIK from + // `reporting_source`. `network_anonymization_key` is the NAK which will be + // passed in with reports to be queued. This must match the NAK from // `isolation_source`, unless it is empty (which will be the case if the // network state partitioning is disabled). static void ProcessParsedReportingEndpointsHeader(
diff --git a/net/reporting/reporting_header_parser_unittest.cc b/net/reporting/reporting_header_parser_unittest.cc index 1c27ac23..6c0baa4 100644 --- a/net/reporting/reporting_header_parser_unittest.cc +++ b/net/reporting/reporting_header_parser_unittest.cc
@@ -19,6 +19,7 @@ #include "base/values.h" #include "net/base/features.h" #include "net/base/isolation_info.h" +#include "net/base/network_anonymization_key.h" #include "net/base/schemeful_site.h" #include "net/reporting/mock_persistent_reporting_store.h" #include "net/reporting/reporting_cache.h" @@ -91,7 +92,7 @@ const std::string kGroup1_ = "group1"; const std::string kGroup2_ = "group2"; // There are 2^3 = 8 of these to test the different combinations of matching - // vs mismatching NIK, origin, and group. + // vs mismatching NAK, origin, and group. const ReportingEndpointGroupKey kGroupKey11_ = ReportingEndpointGroupKey(kNak_, kOrigin1_, kGroup1_); const ReportingEndpointGroupKey kGroupKey21_ = @@ -758,7 +759,7 @@ } } -// Test that each combination of NIK, origin, and group name is considered +// Test that each combination of NAK, origin, and group name is considered // distinct. // See also: ReportingCacheTest.ClientsKeyedByEndpointGroupKey TEST_P(ReportingHeaderParserTest, EndpointGroupKey) { @@ -801,7 +802,7 @@ MockPersistentReportingStore::CommandList expected_commands; // Set 2 endpoints in each of 2 groups for each of 2x2 combinations of - // (NIK, origin). + // (NAK, origin). for (const auto& source : kHeaderSources) { // Verify pre-parsing state EXPECT_FALSE(FindEndpointInCache(source.group1_key, kEndpoint1_));
diff --git a/net/reporting/reporting_policy.h b/net/reporting/reporting_policy.h index a3e41f22..6c6f757 100644 --- a/net/reporting/reporting_policy.h +++ b/net/reporting/reporting_policy.h
@@ -35,7 +35,7 @@ // Maximum number of endpoints for a given origin before evicting // TODO(chlily): This is actually a limit on the endpoints for a given client - // (for a NIK, origin pair), so rename this. + // (for a NAK, origin pair), so rename this. size_t max_endpoints_per_origin = 40u; // Minimum interval at which to attempt delivery of queued reports.
diff --git a/net/reporting/reporting_report.cc b/net/reporting/reporting_report.cc index b0da461..ecb36458 100644 --- a/net/reporting/reporting_report.cc +++ b/net/reporting/reporting_report.cc
@@ -10,6 +10,7 @@ #include "base/time/time.h" #include "base/values.h" +#include "net/base/network_isolation_key.h" #include "url/gurl.h" namespace net {
diff --git a/net/reporting/reporting_report.h b/net/reporting/reporting_report.h index 79a1248..27f8d8d 100644 --- a/net/reporting/reporting_report.h +++ b/net/reporting/reporting_report.h
@@ -60,10 +60,10 @@ ReportingReport& operator=(ReportingReport&& other); ~ReportingReport(); - // Bundles together the NIK, origin of the report URL, and group name. + // Bundles together the NAK, origin of the report URL, and group name. // This is not exactly the same as the group key of the endpoint that the // report will be delivered to. The origin may differ if the endpoint is - // configured for a superdomain of the report's origin. The NIK and group name + // configured for a superdomain of the report's origin. The NAK and group name // will be the same. ReportingEndpointGroupKey GetGroupKey() const;
diff --git a/net/reporting/reporting_service_unittest.cc b/net/reporting/reporting_service_unittest.cc index ba221d1..123c63ea 100644 --- a/net/reporting/reporting_service_unittest.cc +++ b/net/reporting/reporting_service_unittest.cc
@@ -216,7 +216,7 @@ context()->cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_); EXPECT_TRUE(cached_endpoint); - // Ensure that the NIK is stored properly with the endpoint group. + // Ensure that the NAK is stored properly with the endpoint group. EXPECT_FALSE(cached_endpoint.group_key.network_anonymization_key.IsEmpty()); } @@ -244,7 +244,7 @@ context()->cache()->GetV1EndpointForTesting(*kReportingSource_, kGroup_); EXPECT_TRUE(cached_endpoint); - // When isolation is disabled, cached endpoints should have a null NIK. + // When isolation is disabled, cached endpoints should have a null NAK. EXPECT_TRUE(cached_endpoint.group_key.network_anonymization_key.IsEmpty()); }
diff --git a/net/reporting/reporting_uploader_unittest.cc b/net/reporting/reporting_uploader_unittest.cc index b879625..c51c7f8 100644 --- a/net/reporting/reporting_uploader_unittest.cc +++ b/net/reporting/reporting_uploader_unittest.cc
@@ -637,8 +637,6 @@ const SchemefulSite kSite1 = SchemefulSite(kOrigin); const SchemefulSite kSite2(GURL("https://origin2/")); ASSERT_NE(kSite1, kSite2); - const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1); - const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2); const url::Origin kSiteOrigin1 = url::Origin::Create(kSite1.GetURL()); const url::Origin kSiteOrigin2 = url::Origin::Create(kSite2.GetURL()); const IsolationInfo kIsolationInfo1 =
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc index 6a99e21e..b42fe31 100644 --- a/net/socket/socket_test_util.cc +++ b/net/socket/socket_test_util.cc
@@ -798,6 +798,10 @@ next_ssl_data->next_protos_expected_in_ssl_config.value(), ssl_config.alpn_protos)); } + if (next_ssl_data->expected_application_settings) { + EXPECT_EQ(*next_ssl_data->expected_application_settings, + ssl_config.application_settings); + } // The protocol version used is a combination of the per-socket SSLConfig and // the SSLConfigService.
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h index 68212a65..abfe661 100644 --- a/net/socket/socket_test_util.h +++ b/net/socket/socket_test_util.h
@@ -501,6 +501,7 @@ std::vector<uint8_t> ech_retry_configs; absl::optional<NextProtoVector> next_protos_expected_in_ssl_config; + absl::optional<SSLConfig::ApplicationSettings> expected_application_settings; uint16_t expected_ssl_version_min; uint16_t expected_ssl_version_max;
diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc index e27fa2bb..43a5cc86 100644 --- a/net/socket/transport_client_socket_pool_unittest.cc +++ b/net/socket/transport_client_socket_pool_unittest.cc
@@ -23,6 +23,7 @@ #include "net/base/load_timing_info.h" #include "net/base/load_timing_info_test_util.h" #include "net/base/net_errors.h" +#include "net/base/network_anonymization_key.h" #include "net/base/privacy_mode.h" #include "net/base/proxy_chain.h" #include "net/base/proxy_server.h" @@ -1848,7 +1849,7 @@ session_deps_.host_resolver->request_network_anonymization_key(1)); } -TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySsl) { +TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKeySsl) { const SchemefulSite kSite(GURL("https://foo.test/")); const auto kNetworkAnonymizationKey = NetworkAnonymizationKey::CreateSameSite(kSite); @@ -1891,8 +1892,8 @@ // Test that, in the case of an HTTP proxy, the same transient // NetworkAnonymizationKey is reused for resolving the proxy's host, regardless -// of input NIK. -TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeyHttpProxy) { +// of input NAK. +TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKeyHttpProxy) { const SchemefulSite kSite1(GURL("https://foo.test/")); const auto kNetworkAnonymizationKey1 = NetworkAnonymizationKey::CreateSameSite(kSite1); @@ -1964,8 +1965,8 @@ // Test that, in the case of an HTTPS proxy, the same transient // NetworkAnonymizationKey is reused for resolving the proxy's host, regardless -// of input NIK. -TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeyHttpsProxy) { +// of input NAK. +TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKeyHttpsProxy) { const SchemefulSite kSite1(GURL("https://foo.test/")); const auto kNetworkAnonymizationKey1 = NetworkAnonymizationKey::CreateSameSite(kSite1); @@ -2040,8 +2041,8 @@ // Test that, in the case of a SOCKS5 proxy, the passed in // NetworkAnonymizationKey is used for the destination DNS lookup, and the same // transient NetworkAnonymizationKey is reused for resolving the proxy's host, -// regardless of input NIK. -TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks4Proxy) { +// regardless of input NAK. +TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKeySocks4Proxy) { const SchemefulSite kSite1(GURL("https://foo.test/")); const auto kNetworkAnonymizationKey1 = NetworkAnonymizationKey::CreateSameSite(kSite1); @@ -2110,7 +2111,7 @@ IsError(ERR_IO_PENDING)); // First two lookups are for the proxy's hostname, and should use the same - // transient NIK. + // transient NAK. ASSERT_EQ(2u, session_deps_.host_resolver->last_id()); EXPECT_EQ(kProxyChain.proxy_server().host_port_pair().host(), session_deps_.host_resolver->request_host(1)); @@ -2122,7 +2123,7 @@ session_deps_.host_resolver->request_network_anonymization_key(2)); // First two lookups completes, starting the next two, which should be for the - // destination's hostname, and should use the passed in NIKs. + // destination's hostname, and should use the passed in NAKs. session_deps_.host_resolver->ResolveNow(1); session_deps_.host_resolver->ResolveNow(2); ASSERT_EQ(4u, session_deps_.host_resolver->last_id()); @@ -2136,8 +2137,8 @@ // Test that, in the case of a SOCKS5 proxy, the same transient // NetworkAnonymizationKey is reused for resolving the proxy's host, regardless -// of input NIK. -TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks5Proxy) { +// of input NAK. +TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKeySocks5Proxy) { const SchemefulSite kSite1(GURL("https://foo.test/")); const auto kNetworkAnonymizationKey1 = NetworkAnonymizationKey::CreateSameSite(kSite1);
diff --git a/net/socket/transport_connect_job.h b/net/socket/transport_connect_job.h index 4626837..06000c9 100644 --- a/net/socket/transport_connect_job.h +++ b/net/socket/transport_connect_job.h
@@ -44,10 +44,10 @@ // transport parameters. using Endpoint = absl::variant<url::SchemeHostPort, HostPortPair>; - // |host_resolution_callback| will be invoked after the the hostname is - // resolved. |network_anonymization_key| is passed to the HostResolver to - // prevent cross-NIK leaks. If |host_resolution_callback| does not return OK, - // then the connection will be aborted with that value. |supported_alpns| + // `host_resolution_callback` will be invoked after the the hostname is + // resolved. `network_anonymization_key` is passed to the HostResolver to + // prevent cross-NAK leaks. If `host_resolution_callback` does not return OK, + // then the connection will be aborted with that value. `supported_alpns` // specifies ALPN protocols for selecting HTTPS/SVCB records. If empty, // addresses from HTTPS/SVCB records will be ignored and only A/AAAA will be // used.
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index c8127a5..fefc840 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -270,6 +270,11 @@ data_vector_.push_back(data); if (ssl_provider->next_proto == kProtoUnknown) ssl_provider->next_proto = kProtoHTTP2; + // Even when next_protos only includes HTTP1, `application_settions` + // always includes the full list from the HttpNetworkSession. The + // SSLClientSocket layer, which is mocked out in these tests, is the layer + // responsible for only sending the relevant settings. + ssl_provider->expected_application_settings = {{{kProtoHTTP2, {}}}}; session_deps_->socket_factory->AddSSLSocketDataProvider( ssl_provider.get());
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc index 84343a5..04eef93 100644 --- a/net/spdy/spdy_test_util_common.cc +++ b/net/spdy/spdy_test_util_common.cc
@@ -443,6 +443,7 @@ auto ssl_config = std::make_unique<SSLConfig>(); ssl_config->alpn_protos = http_session->GetAlpnProtos(); + ssl_config->application_settings = http_session->GetApplicationSettings(); scoped_refptr<ClientSocketPool::SocketParams> socket_params = base::MakeRefCounted<ClientSocketPool::SocketParams>( /*ssl_config_for_origin=*/std::move(ssl_config),
diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc index 5e0a0b1a..9864694a 100644 --- a/net/url_request/url_request_context.cc +++ b/net/url_request/url_request_context.cc
@@ -77,6 +77,15 @@ // down before this cancels the ProxyResolutionService's URLRequests. proxy_resolution_service()->OnShutdown(); + // If a ProxyDelegate is set then the builder gave it a pointer to the + // ProxyResolutionService, so clear that here to avoid having a dangling + // pointer. There's no need to clear the ProxyResolutionService's pointer to + // ProxyDelegate because the member destruction order ensures that + // ProxyResolutionService is destroyed first. + if (proxy_delegate()) { + proxy_delegate()->SetProxyResolutionService(nullptr); + } + DCHECK(host_resolver()); host_resolver()->OnShutdown();
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h index 843ae71a..f9f66e3 100644 --- a/net/url_request/url_request_context.h +++ b/net/url_request/url_request_context.h
@@ -312,8 +312,10 @@ std::unique_ptr<HostResolver> host_resolver_; std::unique_ptr<CertVerifier> cert_verifier_; std::unique_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_; - std::unique_ptr<ProxyDelegate> proxy_delegate_; std::unique_ptr<NetworkDelegate> network_delegate_; + // `proxy_resolution_service_` may store a pointer to `proxy_delegate_`, so + // ensure that the latter outlives the former. + std::unique_ptr<ProxyDelegate> proxy_delegate_; std::unique_ptr<ProxyResolutionService> proxy_resolution_service_; std::unique_ptr<SSLConfigService> ssl_config_service_; std::unique_ptr<HttpServerProperties> http_server_properties_;
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc index f7fb0518..ef9d468 100644 --- a/net/url_request/url_request_context_builder.cc +++ b/net/url_request/url_request_context_builder.cc
@@ -452,6 +452,14 @@ proxy_resolution_service_.get(); context->set_proxy_resolution_service(std::move(proxy_resolution_service_)); + if (proxy_delegate_) { + ProxyDelegate* proxy_delegate = proxy_delegate_.get(); + context->set_proxy_delegate(std::move(proxy_delegate_)); + + proxy_resolution_service->SetProxyDelegate(proxy_delegate); + proxy_delegate->SetProxyResolutionService(proxy_resolution_service); + } + #if BUILDFLAG(ENABLE_REPORTING) // Note: ReportingService::Create and NetworkErrorLoggingService::Create can // both return nullptr if the corresponding base::Feature is disabled. @@ -488,11 +496,6 @@ } #endif // BUILDFLAG(ENABLE_REPORTING) - if (proxy_delegate_) { - proxy_resolution_service->SetProxyDelegate(proxy_delegate_.get()); - context->set_proxy_delegate(std::move(proxy_delegate_)); - } - HttpNetworkSessionContext network_session_context; // Unlike the other fields of HttpNetworkSession::Context, // |client_socket_factory| is not mirrored in URLRequestContext.
diff --git a/net/websockets/websocket_end_to_end_test.cc b/net/websockets/websocket_end_to_end_test.cc index b4021c3..cc5f2040 100644 --- a/net/websockets/websocket_end_to_end_test.cc +++ b/net/websockets/websocket_end_to_end_test.cc
@@ -303,6 +303,9 @@ return OK; } + void SetProxyResolutionService( + ProxyResolutionService* proxy_resolution_service) override {} + private: ResolvedProxyInfo resolved_proxy_info_; };
diff --git a/services/cert_verifier/cert_verifier_service.cc b/services/cert_verifier/cert_verifier_service.cc index 03657128..a98a7ee 100644 --- a/services/cert_verifier/cert_verifier_service.cc +++ b/services/cert_verifier/cert_verifier_service.cc
@@ -136,6 +136,8 @@ additional_certificates->trust_anchors; instance_params_.additional_untrusted_authorities = additional_certificates->all_certificates; + instance_params_.additional_distrusted_spkis = + additional_certificates->distrusted_spkis; verifier_->UpdateVerifyProcData(cert_net_fetcher_, service_factory_impl_->get_impl_params(),
diff --git a/services/cert_verifier/cert_verifier_service_factory.cc b/services/cert_verifier/cert_verifier_service_factory.cc index 424fcdd..bdb3cf9 100644 --- a/services/cert_verifier/cert_verifier_service_factory.cc +++ b/services/cert_verifier/cert_verifier_service_factory.cc
@@ -72,6 +72,8 @@ creation_params->initial_additional_certificates->trust_anchors; instance_params.additional_untrusted_authorities = creation_params->initial_additional_certificates->all_certificates; + instance_params.additional_distrusted_spkis = + creation_params->initial_additional_certificates->distrusted_spkis; } std::unique_ptr<net::CertVerifierWithUpdatableProc> cert_verifier =
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 122dcc7b..83fe86b 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -2382,6 +2382,12 @@ std::move(params_->custom_proxy_config_client_receiver), std::move(params_->custom_proxy_connection_observer_remote), network_service_->network_service_proxy_allow_list()); + if (params_->ip_protection_config_getter) { + proxy_delegate->SetIpProtectionConfigCache( + std::make_unique<IpProtectionConfigCacheImpl>( + std::move(params_->ip_protection_config_getter))); + proxy_delegate->GetIpProtectionConfigCache()->SetUp(); + } proxy_delegate_ = proxy_delegate.get(); builder.set_proxy_delegate(std::move(proxy_delegate)); } @@ -2753,18 +2759,6 @@ params_->discard_domain_reliablity_uploads); } - if (proxy_delegate_) { - proxy_delegate_->SetProxyResolutionService( - result.url_request_context->proxy_resolution_service()); - - if (params_->ip_protection_config_getter) { - proxy_delegate_->SetIpProtectionConfigCache( - std::make_unique<IpProtectionConfigCacheImpl>( - std::move(params_->ip_protection_config_getter))); - proxy_delegate_->GetIpProtectionConfigCache()->SetUp(); - } - } - return result; }
diff --git a/services/network/network_context.h b/services/network/network_context.h index 3ef62e2a..2d1f87a 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -903,6 +903,7 @@ host_resolvers_; std::unique_ptr<net::HostResolver::ProbeRequest> doh_probes_request_; + // Owned by URLRequestContext. raw_ptr<NetworkServiceProxyDelegate> proxy_delegate_ = nullptr; // Used for Signed Exchange certificate verification.
diff --git a/services/network/network_service_proxy_delegate.cc b/services/network/network_service_proxy_delegate.cc index e4c67ad4..d144bbf 100644 --- a/services/network/network_service_proxy_delegate.cc +++ b/services/network/network_service_proxy_delegate.cc
@@ -315,6 +315,11 @@ return net::OK; } +void NetworkServiceProxyDelegate::SetProxyResolutionService( + net::ProxyResolutionService* proxy_resolution_service) { + proxy_resolution_service_ = proxy_resolution_service; +} + void NetworkServiceProxyDelegate::OnCustomProxyConfigUpdated( mojom::CustomProxyConfigPtr proxy_config, OnCustomProxyConfigUpdatedCallback callback) {
diff --git a/services/network/network_service_proxy_delegate.h b/services/network/network_service_proxy_delegate.h index 6ab4965..4159c66 100644 --- a/services/network/network_service_proxy_delegate.h +++ b/services/network/network_service_proxy_delegate.h
@@ -43,11 +43,6 @@ ~NetworkServiceProxyDelegate() override; - void SetProxyResolutionService( - net::ProxyResolutionService* proxy_resolution_service) { - proxy_resolution_service_ = proxy_resolution_service; - } - void SetIpProtectionConfigCache( std::unique_ptr<IpProtectionConfigCache> ipp_config_cache) { ipp_config_cache_ = std::move(ipp_config_cache); @@ -68,6 +63,8 @@ const net::ProxyChain& proxy_chain, size_t chain_index, const net::HttpResponseHeaders& response_headers) override; + void SetProxyResolutionService( + net::ProxyResolutionService* proxy_resolution_service) override; IpProtectionConfigCache* GetIpProtectionConfigCache() { return ipp_config_cache_.get(); @@ -112,8 +109,7 @@ mojo::Remote<mojom::CustomProxyConnectionObserver> observer_; raw_ptr<NetworkServiceProxyAllowList> network_service_proxy_allow_list_; - raw_ptr<net::ProxyResolutionService, DanglingUntriaged> - proxy_resolution_service_ = nullptr; + raw_ptr<net::ProxyResolutionService> proxy_resolution_service_ = nullptr; std::unique_ptr<IpProtectionConfigCache> ipp_config_cache_; };
diff --git a/services/network/public/mojom/cert_verifier_service.mojom b/services/network/public/mojom/cert_verifier_service.mojom index d2e28ea..145dff4 100644 --- a/services/network/public/mojom/cert_verifier_service.mojom +++ b/services/network/public/mojom/cert_verifier_service.mojom
@@ -38,6 +38,9 @@ // List of additional trust anchors. array<network.mojom.X509Certificate> trust_anchors; + + // List of SPKIs that are explicitly distrusted. + array<array<uint8>> distrusted_spkis; }; // Allows the CertVerifierService to connect a new URLLoaderFactory if its
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index cfbd006..655ef94 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -1581,12 +1581,12 @@ LoadHttpAuthCacheProxyEntries(mojo_base.mojom.UnguessableToken cache_key) => (); -// Adds an entry to the HttpAuthCache. |network_anonymization_key| is the -// NetworkAnonymizationKney to restrict the credentials to, and is only -// respected for server (not proxy) HTTP auth and only when the NetworkService -// was configured to split the auth cache by NetworkAnonymizationKey. -// |challenge| may not necessarily contain a stateful challenge that requires a -// persistent connection, allowing the cache to be pre-populated. + // Adds an entry to the HttpAuthCache. `network_anonymization_key` is the + // NetworkAnonymizationKey to restrict the credentials to, and is only + // respected for server (not proxy) HTTP auth and only when the NetworkService + // was configured to split the auth cache by NetworkAnonymizationKey. + // `challenge` may not necessarily contain a stateful challenge that requires + // a persistent connection, allowing the cache to be pre-populated. AddAuthCacheEntry(AuthChallengeInfo challenge, NetworkAnonymizationKey network_anonymization_key, AuthCredentials credentials) => ();
diff --git a/testing/buildbot/autoshard_exceptions.json b/testing/buildbot/autoshard_exceptions.json index e61c7ae..0c940264 100644 --- a/testing/buildbot/autoshard_exceptions.json +++ b/testing/buildbot/autoshard_exceptions.json
@@ -97,18 +97,18 @@ "chromeos-amd64-generic-rel-renamed": { "chrome_all_tast_tests": { "debug": { - "avg_num_builds_per_peak_hour": 103, - "estimated_bot_hour_delta": 90.64, - "prev_avg_pending_time_sec": 58.5, + "avg_num_builds_per_peak_hour": 92, + "estimated_bot_hour_delta": 43.11, + "prev_avg_pending_time_sec": 53.6, "prev_p50_pending_time_sec": 2.0, - "prev_p90_pending_time_sec": 210.0, - "prev_percentile_duration_minutes": 20.67, - "prev_shard_count": 13, - "simulated_max_shard_duration": 12.21, - "test_overhead_min": 5.866666666666666, + "prev_p90_pending_time_sec": 212.0, + "prev_percentile_duration_minutes": 18.21, + "prev_shard_count": 22, + "simulated_max_shard_duration": 13.81, + "test_overhead_min": 4.016666666666667, "try_builder": "chromeos-amd64-generic-rel-renamed" }, - "shards": 22 + "shards": 29 } }, "linux-chromeos-rel": { @@ -467,32 +467,33 @@ "Linux ASan LSan Tests (1)": { "content_browsertests": { "debug": { - "avg_num_builds_per_peak_hour": "73.0", - "estimated_bot_hour_delta": "-3.01", - "prev_avg_pending_time_sec": "240.9", - "prev_p50_pending_time_sec": "29.0", - "prev_p90_pending_time_sec": "748.0", - "prev_percentile_duration_minutes": "14.56", - "prev_shard_count": "42", - "simulated_max_shard_duration": "14.92", + "avg_num_builds_per_peak_hour": 91, + "estimated_bot_hour_delta": 4.63, + "prev_avg_pending_time_sec": 41.1, + "prev_p50_pending_time_sec": 3.0, + "prev_p90_pending_time_sec": 143.0, + "prev_percentile_duration_minutes": 16.02, + "prev_shard_count": 41, + "simulated_max_shard_duration": 14.93, + "test_overhead_min": 1.0166666666666666, "try_builder": "linux_chromium_asan_rel_ng" }, - "shards": "41" + "shards": 44 }, "interactive_ui_tests": { "debug": { - "avg_num_builds_per_peak_hour": 103, - "estimated_bot_hour_delta": 12.79, - "prev_avg_pending_time_sec": 49.9, + "avg_num_builds_per_peak_hour": 91, + "estimated_bot_hour_delta": 12.23, + "prev_avg_pending_time_sec": 39.1, "prev_p50_pending_time_sec": 2.0, - "prev_p90_pending_time_sec": 155.0, - "prev_percentile_duration_minutes": 16.62, - "prev_shard_count": 23, - "simulated_max_shard_duration": 14.7, - "test_overhead_min": 2.4833333333333334, + "prev_p90_pending_time_sec": 137.0, + "prev_percentile_duration_minutes": 16.52, + "prev_shard_count": 26, + "simulated_max_shard_duration": 14.32, + "test_overhead_min": 2.0166666666666666, "try_builder": "linux_chromium_asan_rel_ng" }, - "shards": 26 + "shards": 30 }, "sync_integration_tests": { "debug": {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index f822b78..461775d 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -1144,7 +1144,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 22 + "shards": 29 }, "test": "chrome_all_tast_tests", "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/"
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 7349c4f..e8e9b11 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -378,7 +378,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 41 + "shards": 44 }, "test": "content_browsertests", "test_id_prefix": "ninja://content/test:content_browsertests/" @@ -779,7 +779,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 26 + "shards": 30 }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/"
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index 64dadeb1..ed47650 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -2161,6 +2161,106 @@ "script": "//tools/perf/process_perf_results.py" } }, + "win-11-perf": { + "isolated_scripts": [ + { + "args": [ + "-v", + "--browser=release_x64", + "--upload-results", + "--test-shard-map-filename=win-11-perf_map.json", + "--ignore-benchmark-exit-code", + "--assert-gpu-compositing" + ], + "merge": { + "args": [ + "--lightweight", + "--skip-perf" + ], + "script": "//tools/perf/process_perf_results.py" + }, + "name": "performance_test_suite", + "resultdb": { + "enable": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimensions": { + "gpu": "102b:0536-4.5.0.5", + "os": "Windows-11-22631.2428", + "pool": "chrome.tests.perf", + "synthetic_product_name": "PowerEdge R350 (Dell Inc.)" + }, + "expiration": 7200, + "hard_timeout": 21600, + "io_timeout": 21600, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 20 + }, + "test": "performance_test_suite", + "trigger_script": { + "args": [ + "--multiple-dimension-script-verbose", + "True" + ], + "requires_simultaneous_shard_dispatch": true, + "script": "//testing/trigger_scripts/perf_device_trigger.py" + } + } + ] + }, + "win-11-perf-pgo": { + "isolated_scripts": [ + { + "args": [ + "-v", + "--browser=release_x64", + "--upload-results", + "--test-shard-map-filename=win-11-perf-pgo_map.json", + "--ignore-benchmark-exit-code", + "--assert-gpu-compositing" + ], + "merge": { + "script": "//tools/perf/process_perf_results.py" + }, + "name": "performance_test_suite", + "resultdb": { + "enable": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimensions": { + "gpu": "102b:0536-4.5.0.5", + "os": "Windows-11-22631.2428", + "pool": "chrome.tests.perf", + "synthetic_product_name": "PowerEdge R350 (Dell Inc.)" + }, + "expiration": 7200, + "hard_timeout": 21600, + "io_timeout": 21600, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 26 + }, + "test": "performance_test_suite", + "trigger_script": { + "args": [ + "--multiple-dimension-script-verbose", + "True" + ], + "requires_simultaneous_shard_dispatch": true, + "script": "//testing/trigger_scripts/perf_device_trigger.py" + } + } + ] + }, + "win-11-processor-perf": { + "merge": { + "args": [ + "--lightweight" + ], + "script": "//tools/perf/process_perf_results.py" + } + }, "win64-builder-perf": { "additional_compile_targets": [ "chromedriver"
diff --git a/testing/buildbot/chromium.perf.pinpoint.json b/testing/buildbot/chromium.perf.pinpoint.json index d23a3ce..d549179 100644 --- a/testing/buildbot/chromium.perf.pinpoint.json +++ b/testing/buildbot/chromium.perf.pinpoint.json
@@ -1823,6 +1823,106 @@ "script": "//tools/perf/process_perf_results.py" } }, + "win-11-perf": { + "isolated_scripts": [ + { + "args": [ + "-v", + "--browser=release_x64", + "--upload-results", + "--test-shard-map-filename=win-11-perf_map.json", + "--ignore-benchmark-exit-code", + "--assert-gpu-compositing" + ], + "merge": { + "args": [ + "--lightweight", + "--skip-perf" + ], + "script": "//tools/perf/process_perf_results.py" + }, + "name": "performance_test_suite", + "resultdb": { + "enable": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimensions": { + "gpu": "102b:0536-4.5.0.5", + "os": "Windows-11-22631.2428", + "pool": "chrome.tests.perf", + "synthetic_product_name": "PowerEdge R350 (Dell Inc.)" + }, + "expiration": 7200, + "hard_timeout": 21600, + "io_timeout": 21600, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 20 + }, + "test": "performance_test_suite", + "trigger_script": { + "args": [ + "--multiple-dimension-script-verbose", + "True" + ], + "requires_simultaneous_shard_dispatch": true, + "script": "//testing/trigger_scripts/perf_device_trigger.py" + } + } + ] + }, + "win-11-perf-pgo": { + "isolated_scripts": [ + { + "args": [ + "-v", + "--browser=release_x64", + "--upload-results", + "--test-shard-map-filename=win-11-perf-pgo_map.json", + "--ignore-benchmark-exit-code", + "--assert-gpu-compositing" + ], + "merge": { + "script": "//tools/perf/process_perf_results.py" + }, + "name": "performance_test_suite", + "resultdb": { + "enable": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimensions": { + "gpu": "102b:0536-4.5.0.5", + "os": "Windows-11-22631.2428", + "pool": "chrome.tests.perf", + "synthetic_product_name": "PowerEdge R350 (Dell Inc.)" + }, + "expiration": 7200, + "hard_timeout": 21600, + "io_timeout": 21600, + "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 26 + }, + "test": "performance_test_suite", + "trigger_script": { + "args": [ + "--multiple-dimension-script-verbose", + "True" + ], + "requires_simultaneous_shard_dispatch": true, + "script": "//testing/trigger_scripts/perf_device_trigger.py" + } + } + ] + }, + "win-11-processor-perf": { + "merge": { + "args": [ + "--lightweight" + ], + "script": "//tools/perf/process_perf_results.py" + } + }, "win64-builder-perf": {}, "win64-builder-perf-pgo": {} }
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 7331318..0dbcbd0 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -350,27 +350,6 @@ ] } ], - "AndroidBackPressRefactorSecondaryActivity": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled_20230629", - "enable_features": [ - "BackGestureRefactorActivityAndroid" - ] - }, - { - "name": "Control_20230629", - "disable_features": [ - "BackGestureRefactorActivityAndroid" - ] - } - ] - } - ], "AndroidDropIntoOmnibox": [ { "platforms": [ @@ -4559,25 +4538,6 @@ ] } ], - "ContextMenuGoogleLensChip": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "ShoppingChipEnabled1Percent_20210211", - "params": { - "disableOnIncognito": "true", - "logUkm": "true" - }, - "enable_features": [ - "ContextMenuGoogleLensChip" - ] - } - ] - } - ], "ContextualPageActionReaderMode": [ { "platforms": [ @@ -6883,26 +6843,6 @@ ] } ], - "EvictSubtree": [ - { - "platforms": [ - "android", - "chromeos", - "chromeos_lacros", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "EvictSubtree" - ] - } - ] - } - ], "ExcludeBrokenImageIconFromBeingLcpEligible": [ { "platforms": [ @@ -7763,7 +7703,6 @@ "enableContextMenuSearchOnTablet": "true" }, "enable_features": [ - "ContextMenuSearchWithGoogleLens", "LensCameraAssistedSearch", "LensOnQuickActionSearchWidget" ] @@ -9712,6 +9651,28 @@ ] } ], + "IndexedHostContentSettingsMap": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IndexedHostContentSettingsMap" + ] + } + ] + } + ], "InputDeviceSettingsSplit": [ { "platforms": [ @@ -11072,26 +11033,6 @@ ] } ], - "NavigationUpdatesChildViewsVisibility": [ - { - "platforms": [ - "android", - "chromeos", - "chromeos_lacros", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "NavigationUpdatesChildViewsVisibility" - ] - } - ] - } - ], "NearbyShareNameEnabled": [ { "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 11cfff4..b0fa1d9d 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -1955,32 +1955,6 @@ #endif ); -const base::FeatureParam<int> kStorageAccessAPIImplicitGrantLimit{ - &kStorageAccessAPI, "storage-access-api-implicit-grant-limit", 0}; -const base::FeatureParam<bool> kStorageAccessAPIAutoGrantInFPS{ - &kStorageAccessAPI, "storage_access_api_auto_grant_in_fps", true}; -const base::FeatureParam<bool> kStorageAccessAPIAutoDenyOutsideFPS{ - &kStorageAccessAPI, "storage_access_api_auto_deny_outside_fps", true}; -const base::FeatureParam<bool> kStorageAccessAPIRefreshGrantsOnUserInteraction{ - &kStorageAccessAPI, "storage_access_api_refresh_grants_on_user_interaction", - true}; -const base::FeatureParam<base::TimeDelta> - kStorageAccessAPITopLevelUserInteractionBound{ - &kStorageAccessAPI, - "storage_access_api_top_level_user_interaction_bound", base::Days(30)}; -const base::FeatureParam<base::TimeDelta> - kStorageAccessAPIRelatedWebsiteSetsLifetime{ - &kStorageAccessAPI, "related_website_sets_permission_lifetime", - base::Days(30)}; -const base::FeatureParam<base::TimeDelta> - kStorageAccessAPIImplicitPermissionLifetime{ - &kStorageAccessAPI, "storage_access_api_implicit_permission_lifetime", - base::Hours(24)}; -const base::FeatureParam<base::TimeDelta> - kStorageAccessAPIExplicitPermissionLifetime{ - &kStorageAccessAPI, "storage_access_api_explicit_permission_lifetime", - base::Days(30)}; - BASE_FEATURE(kStylusPointerAdjustment, "StylusPointerAdjustment", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 1a6905f..09d2ffe 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -1293,44 +1293,6 @@ BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kStopInBackground); -// The number of "automatic" implicit storage access grants per third-party -// origin that can be granted. -// -// Note that if `kStorageAccessAPIAutoGrantInFPS` and -// `kStorageAccessAPIAutoDenyOutsideFPS` are both true, then this parameter has -// no effect. -BLINK_COMMON_EXPORT extern const base::FeatureParam<int> - kStorageAccessAPIImplicitGrantLimit; -// Whether to auto-grant storage access requests when the top level origin and -// the requesting origin are in the same First-Party Set. -BLINK_COMMON_EXPORT extern const base::FeatureParam<bool> - kStorageAccessAPIAutoGrantInFPS; -// Whether to auto-deny storage access requests when the top level origin and -// the requesting origin are not in the same First-Party Set. -BLINK_COMMON_EXPORT extern const base::FeatureParam<bool> - kStorageAccessAPIAutoDenyOutsideFPS; -// Whether to renew Storage Access API permission grants after user interaction -// in the relevant contexts. -BLINK_COMMON_EXPORT extern const base::FeatureParam<bool> - kStorageAccessAPIRefreshGrantsOnUserInteraction; -// How far back to look when requiring top-level user interaction on the -// requesting site for Storage Access API permission grants. If this value is an -// empty duration (e.g. "0s"), then no top-level user interaction is required. -BLINK_COMMON_EXPORT extern const base::FeatureParam<base::TimeDelta> - kStorageAccessAPITopLevelUserInteractionBound; -// How long a Related Website Sets Storage Access API permission -// grant/denial should last (not taking renewals into account). -BLINK_COMMON_EXPORT extern const base::FeatureParam<base::TimeDelta> - kStorageAccessAPIRelatedWebsiteSetsLifetime; -// How long an implicit Storage Access API permission grant/denial should last -// (not taking renewals into account). -BLINK_COMMON_EXPORT extern const base::FeatureParam<base::TimeDelta> - kStorageAccessAPIImplicitPermissionLifetime; -// How long an explicit Storage Access API permission grant/denial should last -// (not taking renewals into account). -BLINK_COMMON_EXPORT extern const base::FeatureParam<base::TimeDelta> - kStorageAccessAPIExplicitPermissionLifetime; - // Stylus gestures for editable web content. BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kStylusRichGestures); // Stylus handwriting recognition to text input feature.
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index a413656..b9d3ff9d8 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -1083,6 +1083,8 @@ string autofillType # The filling strategy FillingStrategy fillingStrategy + # The form field's DOM node + DOM.BackendNodeId fieldId # Emitted when an address form is filled. event addressFormFilled
diff --git a/third_party/blink/renderer/bindings/modules/v8/webgl_any.cc b/third_party/blink/renderer/bindings/modules/v8/webgl_any.cc index 495502dc..ffc2031 100644 --- a/third_party/blink/renderer/bindings/modules/v8/webgl_any.cc +++ b/third_party/blink/renderer/bindings/modules/v8/webgl_any.cc
@@ -5,8 +5,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/webgl_any.h" #include "base/containers/span.h" -#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h" -#include "third_party/blink/renderer/platform/bindings/to_v8.h" +#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -20,19 +19,27 @@ const bool* value, uint32_t size) { auto span = base::make_span(value, size); - return ScriptValue(script_state->GetIsolate(), ToV8(span, script_state)); + return ScriptValue( + script_state->GetIsolate(), + ToV8Traits<IDLSequence<IDLBoolean>>::ToV8(script_state, span)); } ScriptValue WebGLAny(ScriptState* script_state, const Vector<bool>& value) { - return ScriptValue(script_state->GetIsolate(), ToV8(value, script_state)); + return ScriptValue( + script_state->GetIsolate(), + ToV8Traits<IDLSequence<IDLBoolean>>::ToV8(script_state, value)); } ScriptValue WebGLAny(ScriptState* script_state, const Vector<unsigned>& value) { - return ScriptValue(script_state->GetIsolate(), ToV8(value, script_state)); + return ScriptValue( + script_state->GetIsolate(), + ToV8Traits<IDLSequence<IDLUnsignedShort>>::ToV8(script_state, value)); } ScriptValue WebGLAny(ScriptState* script_state, const Vector<int>& value) { - return ScriptValue(script_state->GetIsolate(), ToV8(value, script_state)); + return ScriptValue( + script_state->GetIsolate(), + ToV8Traits<IDLSequence<IDLLong>>::ToV8(script_state, value)); } ScriptValue WebGLAny(ScriptState* script_state, int value) { @@ -70,23 +77,29 @@ } ScriptValue WebGLAny(ScriptState* script_state, WebGLObject* value) { - return ScriptValue(script_state->GetIsolate(), ToV8(value, script_state)); + return ScriptValue( + script_state->GetIsolate(), + ToV8Traits<IDLNullable<WebGLObject>>::ToV8(script_state, value)); } ScriptValue WebGLAny(ScriptState* script_state, DOMFloat32Array* value) { - return ScriptValue(script_state->GetIsolate(), ToV8(value, script_state)); + return ScriptValue(script_state->GetIsolate(), + ToV8Traits<DOMFloat32Array>::ToV8(script_state, value)); } ScriptValue WebGLAny(ScriptState* script_state, DOMInt32Array* value) { - return ScriptValue(script_state->GetIsolate(), ToV8(value, script_state)); + return ScriptValue(script_state->GetIsolate(), + ToV8Traits<DOMInt32Array>::ToV8(script_state, value)); } ScriptValue WebGLAny(ScriptState* script_state, DOMUint8Array* value) { - return ScriptValue(script_state->GetIsolate(), ToV8(value, script_state)); + return ScriptValue(script_state->GetIsolate(), + ToV8Traits<DOMUint8Array>::ToV8(script_state, value)); } ScriptValue WebGLAny(ScriptState* script_state, DOMUint32Array* value) { - return ScriptValue(script_state->GetIsolate(), ToV8(value, script_state)); + return ScriptValue(script_state->GetIsolate(), + ToV8Traits<DOMUint32Array>::ToV8(script_state, value)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_counter_style_rule.h b/third_party/blink/renderer/core/css/css_counter_style_rule.h index 8b852e2..a9044da6 100644 --- a/third_party/blink/renderer/core/css/css_counter_style_rule.h +++ b/third_party/blink/renderer/core/css/css_counter_style_rule.h
@@ -15,7 +15,7 @@ class ExecutionContext; class StyleRuleCounterStyle; -class CSSCounterStyleRule final : public CSSRule { +class CORE_EXPORT CSSCounterStyleRule final : public CSSRule { DEFINE_WRAPPERTYPEINFO(); public:
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 298325ec..2ded417f 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -8259,8 +8259,9 @@ void Document::AdjustQuadsForScrollAndAbsoluteZoom( Vector<gfx::QuadF>& quads, const LayoutObject& layout_object) const { - if (!View()) + if (!View()) { return; + } for (auto& quad : quads) AdjustForAbsoluteZoom::AdjustQuad(quad, layout_object); @@ -8269,10 +8270,11 @@ void Document::AdjustRectForScrollAndAbsoluteZoom( gfx::RectF& rect, const LayoutObject& layout_object) const { - if (!View()) + if (!View()) { return; + } - AdjustForAbsoluteZoom::AdjustRectF(rect, layout_object); + AdjustForAbsoluteZoom::AdjustRectMaybeExcludingCSSZoom(rect, layout_object); } void Document::SetForceSynchronousParsingForTesting(bool enabled) {
diff --git a/third_party/blink/renderer/core/dom/document.idl b/third_party/blink/renderer/core/dom/document.idl index 9b2f968e..ce66c2a 100644 --- a/third_party/blink/renderer/core/dom/document.idl +++ b/third_party/blink/renderer/core/dom/document.idl
@@ -184,8 +184,8 @@ [MeasureAs=DocumentCaretRangeFromPoint] Range caretRangeFromPoint(optional long x = 0, optional long y = 0); // Storage Access API - [CallWith=ScriptState, NewObject, RuntimeEnabled=StorageAccessAPI, MeasureAs=StorageAccessAPI_HasStorageAccess_Method] Promise<boolean> hasStorageAccess(); - [CallWith=ScriptState, NewObject, RuntimeEnabled=StorageAccessAPI, MeasureAs=StorageAccessAPI_requestStorageAccess_Method] Promise<void> requestStorageAccess(); + [CallWith=ScriptState, NewObject, MeasureAs=StorageAccessAPI_HasStorageAccess_Method] Promise<boolean> hasStorageAccess(); + [CallWith=ScriptState, NewObject, MeasureAs=StorageAccessAPI_requestStorageAccess_Method] Promise<void> requestStorageAccess(); [CallWith=ScriptState, NewObject, RuntimeEnabled=StorageAccessAPIForOriginExtension, MeasureAs=StorageAccessAPI_requestStorageAccessFor_Method] Promise<void> requestStorageAccessFor(USVString requestedOrigin); // Text fragment directive API
diff --git a/third_party/blink/renderer/core/frame/attribution_src_loader.cc b/third_party/blink/renderer/core/frame/attribution_src_loader.cc index 8609dfa..53ef8d05 100644 --- a/third_party/blink/renderer/core/frame/attribution_src_loader.cc +++ b/third_party/blink/renderer/core/frame/attribution_src_loader.cc
@@ -71,7 +71,6 @@ #include "third_party/blink/renderer/platform/network/http_names.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" -#include "third_party/blink/renderer/platform/wtf/gc_plugin.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -305,7 +304,9 @@ const SourceType source_type_; // Remote used for registering responses with the browser-process. - GC_PLUGIN_IGNORE("https://crbug.com/1381979") + // Note that there's no check applied for `SharedRemote`, and it should be + // memory safe as long as `SharedRemote::set_disconnect_handler` is not + // installed. See https://crbug.com/1512895 for details. mojo::SharedRemote<mojom::blink::AttributionDataHost> data_host_; wtf_size_t num_registrations_ = 0;
diff --git a/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.cc b/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.cc index 26ddd9d0..e88415b 100644 --- a/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.cc +++ b/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.cc
@@ -342,13 +342,8 @@ network::mojom::blink::WebSandboxFlags::kNone; if (!params.new_value.IsNull()) { using network::mojom::blink::WebSandboxFlags; - WebSandboxFlags ignored_flags = - !RuntimeEnabledFeatures::StorageAccessAPIEnabled() - ? WebSandboxFlags::kStorageAccessByUserActivation - : WebSandboxFlags::kNone; - auto parsed = network::ParseWebSandboxPolicy(sandbox_->value().Utf8(), - ignored_flags); + WebSandboxFlags::kNone); current_flags = parsed.flags; if (!parsed.error_message.empty()) { GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.cc b/third_party/blink/renderer/core/html/html_iframe_element.cc index b0a94702..7c4a309d 100644 --- a/third_party/blink/renderer/core/html/html_iframe_element.cc +++ b/third_party/blink/renderer/core/html/html_iframe_element.cc
@@ -202,13 +202,8 @@ network::mojom::blink::WebSandboxFlags::kNone; if (!value.IsNull()) { using network::mojom::blink::WebSandboxFlags; - WebSandboxFlags ignored_flags = - !RuntimeEnabledFeatures::StorageAccessAPIEnabled() - ? WebSandboxFlags::kStorageAccessByUserActivation - : WebSandboxFlags::kNone; - auto parsed = network::ParseWebSandboxPolicy(sandbox_->value().Utf8(), - ignored_flags); + WebSandboxFlags::kNone); current_flags = parsed.flags; if (!parsed.error_message.empty()) { GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
diff --git a/third_party/blink/renderer/core/html/html_iframe_element_sandbox.cc b/third_party/blink/renderer/core/html/html_iframe_element_sandbox.cc index 061f2ae..66a312f 100644 --- a/third_party/blink/renderer/core/html/html_iframe_element_sandbox.cc +++ b/third_party/blink/renderer/core/html/html_iframe_element_sandbox.cc
@@ -41,15 +41,7 @@ return true; } - // The Storage Access API and corresponding sandbox token is behind the - // |StorageAccessAPI| runtimeflag. Only check this token if - // the feature is enabled. - if (RuntimeEnabledFeatures::StorageAccessAPIEnabled() && - (token == kStorageAccessAPISandboxToken)) { - return true; - } - - return false; + return token == kStorageAccessAPISandboxToken; } } // namespace
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc index e335251..47d947e 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -598,8 +598,9 @@ // LCPP experiment in crbug.com/1498777. If the image is potentially a LCP // element, the scanner doesn't mark it as a deferable image regardless of // whether it has loading="lazy" attribute or not, in order to make the LCP - // image load completion faster. - if (is_potentially_lcp_element) { + // image load completion faster. An exception to this is "lazy load auto + // sizes" which must defer because sizes=auto requires layout information. + if (is_potentially_lcp_element && !source_size_is_auto_) { switch (document_parameters.preload_lazy_load_image_type) { case features::LcppPreloadLazyLoadImageType::kNativeLazyLoading: case features::LcppPreloadLazyLoadImageType::kCustomLazyLoading: @@ -737,8 +738,9 @@ } void ParseSourceSize(const String& attribute_value) { - source_size_ = - SizesAttributeParser(media_values_, attribute_value, nullptr).Size(); + SizesAttributeParser sizes_parser(media_values_, attribute_value, nullptr); + source_size_ = sizes_parser.Size(); + source_size_is_auto_ = sizes_parser.IsAuto(); source_size_set_ = true; } @@ -785,6 +787,7 @@ AtomicString resources_attribute_value_; bool nomodule_attribute_value_ = false; float source_size_ = 0; + bool source_size_is_auto_ = false; bool source_size_set_ = false; FetchParameters::DeferOption defer_ = FetchParameters::kNoDefer; CrossOriginAttributeValue cross_origin_ = kCrossOriginAttributeNotSet;
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc index 144f1ed..470d3f7 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
@@ -114,6 +114,7 @@ ElementLocator locator; const char* input_html; const char* potentially_lcp_preload_url; + bool should_preload; }; struct SharedStorageWritableTestCase { @@ -499,7 +500,8 @@ count++; } } - EXPECT_EQ(1, count); + + EXPECT_EQ(test_case.should_preload ? 1 : 0, count); } void Test(SharedStorageWritableTestCase test_case) { @@ -1678,7 +1680,7 @@ <img src="not-interesting2.jpg"> </div> )HTML", - "super-interesting.jpg"}; + "super-interesting.jpg", true}; Test(test_case); } @@ -1784,7 +1786,7 @@ <img src="not-interesting2.jpg"> </div> )HTML", - "super-interesting.jpg"}); + "super-interesting.jpg", true}); break; case LcppPreloadLazyLoadImageType::kCustomLazyLoad: Test(TokenStreamMatcherTestCase{locator, R"HTML( @@ -1794,7 +1796,7 @@ <img src="not-interesting2.jpg"> </div> )HTML", - "super-interesting.jpg"}); + "super-interesting.jpg", true}); break; case LcppPreloadLazyLoadImageType::kAll: Test(TokenStreamMatcherTestCase{locator, R"HTML( @@ -1804,7 +1806,7 @@ <img src="not-interesting2.jpg"> </div> )HTML", - "super-interesting.jpg"}); + "super-interesting.jpg", true}); Test(TokenStreamMatcherTestCase{locator, R"HTML( <div> <img src="not-interesting.jpg"> @@ -1812,7 +1814,29 @@ <img src="not-interesting2.jpg"> </div> )HTML", - "super-interesting.jpg"}); + "super-interesting.jpg", true}); + break; + } +} + +TEST_P(HTMLPreloadScannerLCPPLazyLoadImageTest, + TokenStreamMatcherWithLoadingLazyAutoSizes) { + ElementLocator locator; + auto* c = locator.add_components()->mutable_id(); + c->set_id_attr("target"); + + switch (GetParam()) { + case LcppPreloadLazyLoadImageType::kNativeLazyLoad: + case LcppPreloadLazyLoadImageType::kCustomLazyLoad: + case LcppPreloadLazyLoadImageType::kAll: + Test(TokenStreamMatcherTestCase{locator, R"HTML( + <div> + <img src="not-interesting.jpg"> + <img src="super-interesting.jpg" id="target" loading="lazy" sizes="auto"> + <img src="not-interesting2.jpg"> + </div> + )HTML", + nullptr, false}); break; } }
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc index 6dd0d53..1413912 100644 --- a/third_party/blink/renderer/core/input/event_handler.cc +++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -827,10 +827,17 @@ // EmbeddedContentView entered a modal event loop. The capturing should be // done only when the result indicates it has been handled. See // crbug.com/269917 + // + // TODO(mustaq): The only user of `MouseEventManager::captures_dragging_` is + // the following `if` condition. After shipping the feature + // MouseDragFromIframeOnCancelledMouseDown, remove `captures_dragging_` plus + // the old comment block above. mouse_event_manager_->SetCapturesDragging( subframe->GetEventHandler().mouse_event_manager_->CapturesDragging()); if (mouse_event_manager_->MousePressed() && - mouse_event_manager_->CapturesDragging()) { + (RuntimeEnabledFeatures:: + MouseDragFromIframeOnCancelledMouseDownEnabled() || + mouse_event_manager_->CapturesDragging())) { capturing_mouse_events_element_ = mev.InnerElement(); capturing_subframe_element_ = mev.InnerElement(); } @@ -1113,8 +1120,8 @@ WebInputEventResult event_result = WebInputEventResult::kNotHandled; bool is_remote_frame = false; - LocalFrame* current_subframe = event_handling_util::GetTargetSubframe( - mev, capturing_mouse_events_element_, &is_remote_frame); + LocalFrame* current_subframe = + event_handling_util::GetTargetSubframe(mev, &is_remote_frame); // We want mouseouts to happen first, from the inside out. First send a // move event to the last subframe so that it will fire mouseouts. @@ -1257,8 +1264,7 @@ HitTestRequest::HitTestRequestType hit_type = HitTestRequest::kRelease; HitTestRequest request(hit_type); MouseEventWithHitTestResults mev = GetMouseEventTarget(request, mouse_event); - LocalFrame* subframe = event_handling_util::GetTargetSubframe( - mev, capturing_mouse_events_element_.Get()); + LocalFrame* subframe = event_handling_util::GetTargetSubframe(mev); capturing_mouse_events_element_ = nullptr; if (subframe) return PassMouseReleaseEventToSubframe(mev, subframe);
diff --git a/third_party/blink/renderer/core/input/event_handling_util.cc b/third_party/blink/renderer/core/input/event_handling_util.cc index 402866ab..9acc102f 100644 --- a/third_party/blink/renderer/core/input/event_handling_util.cc +++ b/third_party/blink/renderer/core/input/event_handling_util.cc
@@ -196,7 +196,6 @@ LocalFrame* GetTargetSubframe( const MouseEventWithHitTestResults& hit_test_result, - Node* capturing_node, bool* is_remote_frame) { if (!hit_test_result.IsOverEmbeddedContentView()) return nullptr;
diff --git a/third_party/blink/renderer/core/input/event_handling_util.h b/third_party/blink/renderer/core/input/event_handling_util.h index 9b4e552..389185e9 100644 --- a/third_party/blink/renderer/core/input/event_handling_util.h +++ b/third_party/blink/renderer/core/input/event_handling_util.h
@@ -48,7 +48,6 @@ const WebMouseEvent&); LocalFrame* GetTargetSubframe(const MouseEventWithHitTestResults&, - Node* capturing_node = nullptr, bool* is_remote_frame = nullptr); LocalFrame* SubframeForTargetNode(Node*, bool* is_remote_frame = nullptr);
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc index 949e04d5..4c5edd0 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
@@ -637,9 +637,11 @@ } if (flags_ & kShouldConvertToCSSPixels) { - AdjustForAbsoluteZoom::AdjustRectF(target_rect_, *target); - AdjustForAbsoluteZoom::AdjustRectF(intersection_rect_, *target); - AdjustForAbsoluteZoom::AdjustRectF(root_rect_, *root); + AdjustForAbsoluteZoom::AdjustRectMaybeExcludingCSSZoom(target_rect_, + *target); + AdjustForAbsoluteZoom::AdjustRectMaybeExcludingCSSZoom(intersection_rect_, + *target); + AdjustForAbsoluteZoom::AdjustRectMaybeExcludingCSSZoom(root_rect_, *root); } if (cached_rects) {
diff --git a/third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h b/third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h index 73f4e092..1687a50 100644 --- a/third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h +++ b/third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h
@@ -26,10 +26,12 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_ADJUST_FOR_ABSOLUTE_ZOOM_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_ADJUST_FOR_ABSOLUTE_ZOOM_H_ +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/layout/geometry/physical_size.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { @@ -92,11 +94,19 @@ if (zoom != 1) quad.Scale(1 / zoom, 1 / zoom); } - inline static void AdjustRectF(gfx::RectF& rect, - const LayoutObject& layout_object) { - float zoom = layout_object.StyleRef().EffectiveZoom(); - if (zoom != 1) + inline static void AdjustRectMaybeExcludingCSSZoom( + gfx::RectF& rect, + const LayoutObject& layout_object) { + float zoom; + if (RuntimeEnabledFeatures::RemoveZoomAdjustmentOfBoundingBoxEnabled()) { + zoom = layout_object.GetFrame()->PageZoomFactor(); + } else { + zoom = layout_object.StyleRef().EffectiveZoom(); + } + + if (zoom != 1) { rect.Scale(1 / zoom, 1 / zoom); + } } inline static float AdjustScroll(float scroll_offset, float zoom_factor) {
diff --git a/third_party/blink/renderer/core/layout/fragment_builder.cc b/third_party/blink/renderer/core/layout/fragment_builder.cc index c8a06819..17967bb7 100644 --- a/third_party/blink/renderer/core/layout/fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/fragment_builder.cc
@@ -594,7 +594,7 @@ new_inline_container); } - auto* oof_data = fragment.GetFragmentedOofData(); + const auto* oof_data = fragment.GetFragmentedOofData(); if (!oof_data) return; DCHECK(!oof_data->multicols_with_pending_oofs.empty() || @@ -687,7 +687,7 @@ const OofContainingBlock<LogicalOffset>* containing_block, const OofContainingBlock<LogicalOffset>* fixedpos_containing_block, HeapVector<LogicalOofNodeForFragmentation>* out_list) { - auto* oof_data = fragment.GetFragmentedOofData(); + const auto* oof_data = fragment.GetFragmentedOofData(); if (!oof_data || oof_data->oof_positioned_fragmentainer_descendants.empty()) return; @@ -695,20 +695,14 @@ const auto* box_fragment = DynamicTo<PhysicalBoxFragment>(&fragment); bool is_column_spanner = box_fragment && box_fragment->IsColumnSpanAll(); - auto& out_of_flow_fragmentainer_descendants = - oof_data->oof_positioned_fragmentainer_descendants; - wtf_size_t next_idx; - for (wtf_size_t idx = 0; idx < out_of_flow_fragmentainer_descendants.size(); - idx = next_idx) { - next_idx = idx + 1; - const auto& descendant = out_of_flow_fragmentainer_descendants[idx]; + for (const PhysicalOofNodeForFragmentation& descendant : + oof_data->oof_positioned_fragmentainer_descendants) { const PhysicalFragment* containing_block_fragment = descendant.containing_block.Fragment(); bool container_inside_column_spanner = descendant.containing_block.IsInsideColumnSpanner(); bool fixedpos_container_inside_column_spanner = descendant.fixedpos_containing_block.IsInsideColumnSpanner(); - bool remove_descendant = false; if (!containing_block_fragment) { DCHECK(box_fragment); @@ -727,7 +721,6 @@ // the OOF past the next fragmentation context root ancestor. container_inside_column_spanner = false; fixedpos_container_inside_column_spanner = false; - remove_descendant = true; } else { DCHECK(!fixedpos_container_inside_column_spanner); continue; @@ -863,13 +856,6 @@ out_list->emplace_back(oof_node); } else { AddOutOfFlowFragmentainerDescendant(oof_node); - - // Remove any descendants that were propagated to the next fragmentation - // context root (as a result of a column spanner). - if (remove_descendant) { - out_of_flow_fragmentainer_descendants.EraseAt(idx); - next_idx = idx; - } } } }
diff --git a/third_party/blink/renderer/core/layout/list/layout_inline_list_item.cc b/third_party/blink/renderer/core/layout/list/layout_inline_list_item.cc index afb4539..391186af 100644 --- a/third_party/blink/renderer/core/layout/list/layout_inline_list_item.cc +++ b/third_party/blink/renderer/core/layout/list/layout_inline_list_item.cc
@@ -86,6 +86,9 @@ return; } list_marker->CounterStyleChanged(*marker); + if (RuntimeEnabledFeatures::CounterStyleChangeShouleCollectInlinesEnabled()) { + SetNeedsCollectInlines(); + } } int LayoutInlineListItem::Value() const {
diff --git a/third_party/blink/renderer/core/layout/list/layout_inline_list_item_test.cc b/third_party/blink/renderer/core/layout/list/layout_inline_list_item_test.cc index 25fe0a2..cd1ff8e 100644 --- a/third_party/blink/renderer/core/layout/list/layout_inline_list_item_test.cc +++ b/third_party/blink/renderer/core/layout/list/layout_inline_list_item_test.cc
@@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "third_party/blink/renderer/core/css/css_counter_style_rule.h" +#include "third_party/blink/renderer/core/css/css_rule_list.h" +#include "third_party/blink/renderer/core/html/html_style_element.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" namespace blink { @@ -36,4 +39,27 @@ EXPECT_TRUE(InlineNode::GetOffsetMapping(block_flow)); } +// crbug.com/1512284 +TEST_F(LayoutInlineListItemTest, OffsetMappingBuilderNoCrash) { + SetBodyInnerHTML(R"HTML(<style id="s"> +@counter-style foo { symbols: A; } +li { display: inline list-item; } +</style> +<ol style="list-style-type: foo;"><li id="target"></li>)HTML"); + + CSSStyleSheet* sheet = To<HTMLStyleElement>(GetElementById("s"))->sheet(); + auto* rule = + To<CSSCounterStyleRule>(sheet->cssRules(ASSERT_NO_EXCEPTION)->item(0)); + rule->setPrefix(GetDocument().GetExecutionContext(), "p"); + UpdateAllLifecyclePhasesForTest(); + + auto* block_flow = OffsetMapping::GetInlineFormattingContextOf( + *GetLayoutObjectByElementId("target")); + ASSERT_TRUE(block_flow); + EXPECT_TRUE(InlineNode::GetOffsetMapping(block_flow)); + // We had a bug that updating a counter-style didn't trigger CollectInlines. + // This test passes if the above GetOffsetMapping() doesn't crash by CHECK + // failures. +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc index 9d3ffff..065d6eb 100644 --- a/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc
@@ -1145,9 +1145,13 @@ const PhysicalFragment* containing_block_fragment = descendant.containing_block.Fragment(); // If the containing block is not set, that means that the inner multicol - // was its containing block, and the OOF will be laid out elsewhere. - if (!containing_block_fragment) + // was its containing block, and the OOF will be laid out elsewhere. Also + // skip descendants whose containing block is a column spanner, because + // those need to be laid out further up in the tree. + if (!containing_block_fragment || + descendant.containing_block.IsInsideColumnSpanner()) { continue; + } LogicalOffset containing_block_offset = converter.ToLogical(descendant.containing_block.Offset(), containing_block_fragment->Size());
diff --git a/third_party/blink/renderer/core/layout/physical_fragment.cc b/third_party/blink/renderer/core/layout/physical_fragment.cc index 9876ab0b..6c2fe279 100644 --- a/third_party/blink/renderer/core/layout/physical_fragment.cc +++ b/third_party/blink/renderer/core/layout/physical_fragment.cc
@@ -485,7 +485,7 @@ oof_data_->oof_positioned_descendants.size()}; } -FragmentedOofData* PhysicalFragment::GetFragmentedOofData() const { +const FragmentedOofData* PhysicalFragment::GetFragmentedOofData() const { if (!has_fragmented_out_of_flow_data_) return nullptr; auto* oof_data = reinterpret_cast<FragmentedOofData*>(oof_data_.Get());
diff --git a/third_party/blink/renderer/core/layout/physical_fragment.h b/third_party/blink/renderer/core/layout/physical_fragment.h index 0403f49..f305371 100644 --- a/third_party/blink/renderer/core/layout/physical_fragment.h +++ b/third_party/blink/renderer/core/layout/physical_fragment.h
@@ -710,7 +710,7 @@ return &oof_data_->anchor_query; } - FragmentedOofData* GetFragmentedOofData() const; + const FragmentedOofData* GetFragmentedOofData() const; // Return true if there are nested multicol container descendants with OOFs // inside.
diff --git a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc index 5bdfd94..2ebc909 100644 --- a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc
@@ -264,7 +264,6 @@ DCHECK(ThreadState::Current()->IsMainThread()); records_manager_.AssignPaintTimeToRegisteredQueuedRecords( timestamp, last_queued_frame_index); - frame_view_->GetPaintTimingDetector().UpdateLargestContentfulPaintCandidate(); } void ImageRecordsManager::AssignPaintTimeToRegisteredQueuedRecords(
diff --git a/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5 b/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5 index c407cf5..e66777a 100644 --- a/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5 +++ b/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5
@@ -391,7 +391,6 @@ name: "StorageAccessAPI", feature_default: "EnableForAll", permissions_policy_name: "storage-access", - depends_on: ["StorageAccessAPI"], }, { name: "SubApps",
diff --git a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc index b15de56..385079c 100644 --- a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc +++ b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
@@ -131,6 +131,7 @@ did_commit_previous_paints_ = false; soft_navigation_conditions_met_ = false; pending_interaction_timestamp_ = base::TimeTicks(); + softnav_painted_area_ = 0; } void SoftNavigationHeuristics::InteractionCallbackCalled(
diff --git a/third_party/blink/renderer/modules/accessibility/ax_debug_utils.cc b/third_party/blink/renderer/modules/accessibility/ax_debug_utils.cc index 6dcd0bc..33de5aa 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_debug_utils.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_debug_utils.cc
@@ -76,17 +76,19 @@ } std::string ParentChainToStringHelper(const AXObject* obj) { + bool cached = !obj->IsDetached() && !obj->AXObjectCache().IsFrozen(); + AXObject::AXObjectVector ancestors; - for (AXObject::AncestorsIterator iter = obj->UnignoredAncestorsBegin(); - iter != obj->UnignoredAncestorsEnd(); iter++) { - ancestors.push_back(*iter); + while (obj) { + ancestors.push_back(const_cast<AXObject*>(obj)); + obj = obj->ParentObject(); } size_t indent = 0; std::string builder; for (auto iter = ancestors.rbegin(); iter != ancestors.rend(); iter++) { builder = builder + std::string(2 * indent, ' ') + - (*iter)->ToString(true, true).Utf8() + '\n'; + (*iter)->ToString(true, cached).Utf8() + '\n'; ++indent; } return builder;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index cbba4fbc..6705736 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -2163,6 +2163,8 @@ // Clear updates from both documents. tree_update_callback_queue_main_.clear(); tree_update_callback_queue_popup_.clear(); + notifications_to_post_main_.clear(); + notifications_to_post_popup_.clear(); return true; } @@ -2863,6 +2865,7 @@ CHECK(nodes_with_pending_children_changed_.empty()); CHECK(tree_update_callback_queue_main_.empty()); CHECK(tree_update_callback_queue_popup_.empty()); + CHECK(!Root()->NeedsToUpdateCachedValues()); #if DCHECK_IS_ON() // The following checks can make tests flaky if the tree being checked @@ -2987,17 +2990,6 @@ CHECK(!processing_deferred_events_); - if (tree_updates_paused_) { - tree_updates_paused_ = false; - if (!force) { - LOG(INFO) - << "Accessibility tree updates will be resumed after rebuilding " - "the tree from root"; - MarkDocumentDirty(); - return; - } - } - // Don't update the tree at an awkward time during page load. // Example: when the last node is whitespace, there is not yet enough context // to determine the relevance of the whitespace. @@ -3009,6 +3001,17 @@ node_to_parse_before_more_tree_updates_ = nullptr; } + if (tree_updates_paused_) { + // Unpause tree updates and rebuild the tree from the root. + // TODO(accessibility): Add more testing for this feature. + // TODO(accessibility): Consider waiting until serialization batching timer + // fires, so that the pause is a bit longer. + LOG(INFO) << "Accessibility tree updates will be resumed after rebuilding " + "the tree from root"; + mark_all_dirty_ = true; + tree_updates_paused_ = false; + } + if (GetPopupDocumentIfShowing()) { UpdateLifecycleIfNeeded(*GetPopupDocumentIfShowing()); CheckStyleIsComplete(*GetPopupDocumentIfShowing()); @@ -3184,6 +3187,12 @@ if (Root()->NeedsToUpdateChildren() || Root()->HasDirtyDescendants()) { return true; } + // If tree updates are paused, consider the cache dirty. The next time + // ProcessDeferredAccessibilityEvents() is called, the entire tree will be + // rebuilt from the root. + if (tree_updates_paused_) { + return true; + } return false; }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h index 7774dd5..f351570 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -1127,6 +1127,8 @@ bool mark_all_dirty_ = false; FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, PauseUpdatesAfterMaxNumberQueued); + FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, + UpdateAXForAllDocumentsAfterPausedUpdates); FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, RemoveReferencesToAXID); // So we can ensure the serialization pipeline never stalls with dirty objects
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc index 36efc276..3f83cdb 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc
@@ -191,6 +191,28 @@ ASSERT_EQ(0u, MockAXObject::num_children_changed_calls_); } +TEST_F(AccessibilityTest, UpdateAXForAllDocumentsAfterPausedUpdates) { + auto& document = GetDocument(); + auto* ax_object_cache = + To<AXObjectCacheImpl>(document.ExistingAXObjectCache()); + DCHECK(ax_object_cache); + + wtf_size_t max_updates = 1; + ax_object_cache->SetMaxPendingUpdatesForTesting(max_updates); + + UpdateAllLifecyclePhasesForTest(); + AXObject* root = ax_object_cache->Root(); + // Queue one update too many. + ax_object_cache->DeferTreeUpdate( + AXObjectCacheImpl::TreeUpdateReason::kChildrenChanged, root); + ax_object_cache->DeferTreeUpdate( + AXObjectCacheImpl::TreeUpdateReason::kChildrenChanged, root); + + ax_object_cache->UpdateAXForAllDocuments(); + ScopedFreezeAXCache freeze(*ax_object_cache); + CHECK(!root->NeedsToUpdateCachedValues()); +} + class AXViewTransitionTest : public testing::Test { public: AXViewTransitionTest() {}
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc index dfcb829..ee218ce 100644 --- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc +++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -15,6 +15,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_unsanitized_formats.h" #include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h" #include "third_party/blink/renderer/core/clipboard/system_clipboard.h" @@ -349,8 +350,9 @@ items.ReserveInitialCapacity(clipboard_item_data_.size()); for (const auto& item : clipboard_item_data_) { - ScriptPromise promise = - ScriptPromise::Cast(script_state_, ToV8(item.second, script_state_)); + ScriptPromise promise = ScriptPromise::Cast( + script_state_, + ToV8Traits<Blob>::ToV8(script_state_, item.second).ToLocalChecked()); items.emplace_back(item.first, promise); } HeapVector<Member<ClipboardItem>> clipboard_items = {
diff --git a/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc b/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc index 55e7052..451a969 100644 --- a/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc +++ b/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_contact_info.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" @@ -259,7 +260,9 @@ ScriptPromise ContactsManager::getProperties(ScriptState* script_state) { return ScriptPromise::Cast(script_state, - ToV8(GetProperties(script_state), script_state)); + ToV8Traits<IDLSequence<IDLString>>::ToV8( + script_state, GetProperties(script_state)) + .ToLocalChecked()); } void ContactsManager::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/csspaint/nativepaint/clip_path_paint_definition.cc b/third_party/blink/renderer/modules/csspaint/nativepaint/clip_path_paint_definition.cc index abed7a01..4b8bb14 100644 --- a/third_party/blink/renderer/modules/csspaint/nativepaint/clip_path_paint_definition.cc +++ b/third_party/blink/renderer/modules/csspaint/nativepaint/clip_path_paint_definition.cc
@@ -116,7 +116,7 @@ bool ValueChangeShouldCauseRepaint(const PropertyValue& val1, const PropertyValue& val2) const override { return !val1.float_value.has_value() || !val2.float_value.has_value() || - GetAdjustedProgress(*val1.float_value) == + GetAdjustedProgress(*val1.float_value) != GetAdjustedProgress(*val2.float_value); }
diff --git a/third_party/blink/renderer/modules/exported/web_dom_file_system.cc b/third_party/blink/renderer/modules/exported/web_dom_file_system.cc index 476686b..b132e4b 100644 --- a/third_party/blink/renderer/modules/exported/web_dom_file_system.cc +++ b/third_party/blink/renderer/modules/exported/web_dom_file_system.cc
@@ -31,6 +31,7 @@ #include "third_party/blink/public/web/web_dom_file_system.h" #include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_directory_entry.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_entry.h" @@ -41,7 +42,6 @@ #include "third_party/blink/renderer/modules/filesystem/directory_entry.h" #include "third_party/blink/renderer/modules/filesystem/dom_file_system.h" #include "third_party/blink/renderer/modules/filesystem/file_entry.h" -#include "third_party/blink/renderer/platform/bindings/to_v8.h" #include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h" #include "v8/include/v8.h" @@ -117,7 +117,13 @@ v8::Local<v8::Value> WebDOMFileSystem::ToV8Value(v8::Isolate* isolate) { if (!private_.Get()) return v8::Local<v8::Value>(); - return ToV8(private_.Get(), isolate->GetCurrentContext()->Global(), isolate); + v8::Local<v8::Value> value; + if (!ToV8Traits<DOMFileSystem>::ToV8( + ScriptState::From(isolate->GetCurrentContext()), private_.Get()) + .ToLocal(&value)) { + return v8::Local<v8::Value>(); + } + return value; } v8::Local<v8::Value> WebDOMFileSystem::CreateV8Entry( @@ -126,13 +132,26 @@ v8::Isolate* isolate) { if (!private_.Get()) return v8::Local<v8::Value>(); - if (entry_type == kEntryTypeDirectory) { - return ToV8(MakeGarbageCollected<DirectoryEntry>(private_.Get(), path), - isolate->GetCurrentContext()->Global(), isolate); + v8::Local<v8::Value> value; + switch (entry_type) { + case kEntryTypeDirectory: + if (!ToV8Traits<DirectoryEntry>::ToV8( + ScriptState::From(isolate->GetCurrentContext()), + MakeGarbageCollected<DirectoryEntry>(private_.Get(), path)) + .ToLocal(&value)) { + return v8::Local<v8::Value>(); + } + break; + case kEntryTypeFile: + if (!ToV8Traits<FileEntry>::ToV8( + ScriptState::From(isolate->GetCurrentContext()), + MakeGarbageCollected<FileEntry>(private_.Get(), path)) + .ToLocal(&value)) { + return v8::Local<v8::Value>(); + } + break; } - DCHECK_EQ(entry_type, kEntryTypeFile); - return ToV8(MakeGarbageCollected<FileEntry>(private_.Get(), path), - isolate->GetCurrentContext()->Global(), isolate); + return value; } WebDOMFileSystem::WebDOMFileSystem(DOMFileSystem* dom_file_system)
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc b/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc index e450fffc..45e024ae 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
@@ -29,6 +29,7 @@ #include <memory> #include <utility> +#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h" #include "third_party/blink/renderer/bindings/modules/v8/to_v8_for_modules.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_idb_request.h" @@ -87,7 +88,9 @@ if (!wrapper.IsEmpty()) { static const V8PrivateProperty::SymbolKey kPrivatePropertyRequest; V8PrivateProperty::GetSymbol(isolate, kPrivatePropertyRequest) - .Set(wrapper, ToV8(request_.Get(), wrapper, isolate)); + .Set(wrapper, + ToV8Traits<IDBRequest>::ToV8(isolate, request_.Get(), wrapper) + .ToLocalChecked()); } return wrapper; }
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc index 2e69c189..06bdc973b 100644 --- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc +++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
@@ -35,6 +35,7 @@ #include "third_party/blink/public/platform/web_encrypted_media_request.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/bindings/core/v8/to_v8_traits.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_configuration.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_key_system_track_configuration.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_capabilities_decoding_info.h" @@ -60,7 +61,6 @@ #include "third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" -#include "third_party/blink/renderer/platform/bindings/to_v8.h" #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -186,7 +186,10 @@ MediaCapabilitiesDecodingInfo* info = CreateDecodingInfoWith(value); media_capabilities_identifiability_metrics::ReportDecodingInfoResult( ExecutionContext::From(script_state), config, info); - return ScriptPromise::Cast(script_state, ToV8(info, script_state)); + return ScriptPromise::Cast( + script_state, + ToV8Traits<MediaCapabilitiesDecodingInfo>::ToV8(script_state, info) + .ToLocalChecked()); } MediaCapabilitiesDecodingInfo* CreateEncryptedDecodingInfoWith( @@ -953,7 +956,10 @@ CreateEncryptedDecodingInfoWith(false, nullptr); media_capabilities_identifiability_metrics::ReportDecodingInfoResult( ExecutionContext::From(script_state), config, info); - return ScriptPromise::Cast(script_state, ToV8(info, script_state)); + return ScriptPromise::Cast( + script_state, + ToV8Traits<MediaCapabilitiesDecodingInfo>::ToV8(script_state, info) + .ToLocalChecked()); } }
diff --git a/third_party/blink/renderer/modules/mediasource/track_default.cc b/third_party/blink/renderer/modules/mediasource/track_default.cc index d9ab6654..c0d3ec8 100644 --- a/third_party/blink/renderer/modules/mediasource/track_default.cc +++ b/third_party/blink/renderer/modules/mediasource/track_default.cc
@@ -26,7 +26,9 @@ } ScriptValue TrackDefault::kinds(ScriptState* script_state) const { - return ScriptValue(script_state->GetIsolate(), ToV8(kinds_, script_state)); + return ScriptValue( + script_state->GetIsolate(), + ToV8Traits<IDLSequence<IDLString>>::ToV8(script_state, kinds_)); } TrackDefault* TrackDefault::Create(const AtomicString& type,
diff --git a/third_party/blink/renderer/modules/permissions/permission_utils.cc b/third_party/blink/renderer/modules/permissions/permission_utils.cc index 218942b3..b4332f9 100644 --- a/third_party/blink/renderer/modules/permissions/permission_utils.cc +++ b/third_party/blink/renderer/modules/permissions/permission_utils.cc
@@ -325,15 +325,10 @@ return CreatePermissionDescriptor(PermissionName::NFC); } if (name == V8PermissionName::Enum::kStorageAccess) { - if (!RuntimeEnabledFeatures::StorageAccessAPIEnabled()) { - exception_state.ThrowTypeError("The Storage Access API is not enabled."); - return nullptr; - } return CreatePermissionDescriptor(PermissionName::STORAGE_ACCESS); } if (name == V8PermissionName::Enum::kTopLevelStorageAccess) { - if (!RuntimeEnabledFeatures::StorageAccessAPIEnabled() || - !RuntimeEnabledFeatures::StorageAccessAPIForOriginExtensionEnabled()) { + if (!RuntimeEnabledFeatures::StorageAccessAPIForOriginExtensionEnabled()) { exception_state.ThrowTypeError( "The requestStorageAccessFor API is not enabled."); return nullptr;
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_error.cc b/third_party/blink/renderer/modules/service_worker/service_worker_error.cc index 513ff37..8041bd41 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_error.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_error.cc
@@ -152,9 +152,9 @@ return V8ThrowException::CreateTypeError(script_state->GetIsolate(), web_error.message); default: - return ToV8(ServiceWorkerError::Take(resolver, web_error), - script_state->GetContext()->Global(), - script_state->GetIsolate()); + return ToV8Traits<DOMException>::ToV8( + script_state, ServiceWorkerError::Take(resolver, web_error)) + .ToLocalChecked(); } }
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 347d711..5aa432e1 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
@@ -50,6 +50,7 @@ #include "third_party/blink/public/mojom/gpu/gpu.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" +#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h" #include "third_party/blink/renderer/bindings/core/v8/v8_union_htmlcanvaselement_offscreencanvas.h" #include "third_party/blink/renderer/bindings/modules/v8/webgl_any.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" @@ -3432,12 +3433,9 @@ } WebGLExtension* extension = EnableExtensionIfSupported(name); - - v8::Local<v8::Value> wrapped_extension = - ToV8(extension, script_state->GetContext()->Global(), - script_state->GetIsolate()); - - return ScriptValue(script_state->GetIsolate(), wrapped_extension); + return ScriptValue( + script_state->GetIsolate(), + ToV8Traits<IDLNullable<WebGLExtension>>::ToV8(script_state, extension)); } ScriptValue WebGLRenderingContextBase::getFramebufferAttachmentParameter(
diff --git a/third_party/blink/renderer/modules/webtransport/web_transport.cc b/third_party/blink/renderer/modules/webtransport/web_transport.cc index 4f20e572..4422494 100644 --- a/third_party/blink/renderer/modules/webtransport/web_transport.cc +++ b/third_party/blink/renderer/modules/webtransport/web_transport.cc
@@ -1040,13 +1040,14 @@ ScriptState::Scope scope(script_state_); v8::Isolate* isolate = script_state_->GetIsolate(); - v8::Local<v8::Value> reason; WebTransportCloseInfo idl_close_info; if (close_info) { idl_close_info.setCloseCode(close_info->code); idl_close_info.setReason(close_info->reason); } - reason = ToV8(&idl_close_info, script_state_); + v8::Local<v8::Value> reason = + ToV8Traits<WebTransportCloseInfo>::ToV8(script_state_, &idl_close_info) + .ToLocalChecked(); v8::Local<v8::Value> error = WebTransportError::Create( isolate, /*stream_error_code=*/absl::nullopt, "The session is closed.",
diff --git a/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc b/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc index cd5b8b83..de4a661 100644 --- a/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc +++ b/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
@@ -121,7 +121,7 @@ } void WebRtcAudioSink::OnSetFormat(const media::AudioParameters& params) { - DCHECK(params.IsValid()); + CHECK(params.IsValid()); SendLogMessage(base::StringPrintf("OnSetFormat([label=%s] {params=[%s]})", adapter_->label().c_str(), params.AsHumanReadableString().c_str()));
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 9c4e0fe9..4bcd50ad 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -794,6 +794,10 @@ base_feature: "none", }, { + name: "CounterStyleChangeShouleCollectInlines", + status: "stable", + }, + { name: "CrossFramePerformanceTimeline", status: "experimental", }, @@ -2485,6 +2489,12 @@ name: "MonitorTypeSurfaces", status: "stable", }, + // crbug.com/269917: Make mouse event targets agnostic to mousedown event + // cancellation when the pointer is dragged out of an iframe. + { + name: "MouseDragFromIframeOnCancelledMouseDown", + status: "experimental", + }, // crbug.com/346473: Allow mouse-drag text selection even when mousemove // event is cancelled. { @@ -3161,6 +3171,11 @@ base_feature: "none", }, { + // See https://github.com/w3c/csswg-drafts/issues/9398 + name: "RemoveZoomAdjustmentOfBoundingBox", + status: "test", + }, + { name: "RenderBlockingStatus", status: "stable", base_feature: "none", @@ -3640,13 +3655,6 @@ base_feature: "none", }, { - // Enabled when blink::features::kStorageAccessAPI or - // permissions::features::kPermissionStorageAccessAPI is enabled. - name: "StorageAccessAPI", - public: true, - status: "stable", - }, - { name: "StorageAccessAPIBeyondCookies", status: "experimental", base_feature: "none", @@ -3656,7 +3664,6 @@ name: "StorageAccessAPIForOriginExtension", public: true, status: "stable", - depends_on: ["StorageAccessAPI"], }, { name: "StorageBuckets",
diff --git a/third_party/blink/renderer/platform/text/text_break_iterator.cc b/third_party/blink/renderer/platform/text/text_break_iterator.cc index 55bcf81f..99693a5 100644 --- a/third_party/blink/renderer/platform/text/text_break_iterator.cc +++ b/third_party/blink/renderer/platform/text/text_break_iterator.cc
@@ -293,6 +293,53 @@ return ch > kAsciiLineBreakTableLastChar && ch != kNoBreakSpaceCharacter; } +template <typename CharacterType> +struct LazyLineBreakIterator::Context { + STACK_ALLOCATED(); + + public: + struct ContextChar { + STACK_ALLOCATED(); + + public: + ContextChar() = default; + explicit ContextChar(UChar ch) : ch(ch), is_space(IsBreakableSpace(ch)) {} + + UChar ch = 0; + bool is_space = false; + }; + + Context(const CharacterType* str, int len, unsigned start_offset, int index) { + CHECK_GE(index, 0); + DCHECK_GE(static_cast<unsigned>(index), start_offset); + CHECK_LE(index, len); + if (index > 0) { + last = ContextChar(str[index - 1]); + if (index > 1) { + last_last_ch = str[index - 2]; + } + } + } + + bool Fetch(const CharacterType* str, int len, int index) { + if (UNLIKELY(index >= len)) { + return false; + } + current = ContextChar(str[index]); + return true; + } + + void Advance(int& index) { + ++index; + last_last_ch = last.ch; + last = current; + } + + ContextChar current; + ContextChar last; + CharacterType last_last_ch = 0; +}; + template <typename CharacterType, LineBreakType lineBreakType, BreakSpaceType break_space> @@ -300,57 +347,60 @@ int pos, const CharacterType* str, int len) const { - CHECK_GE(pos, 0); - DCHECK_GE(static_cast<unsigned>(pos), start_offset_); - CHECK_LE(pos, len); + Context<CharacterType> context(str, len, start_offset_, pos); int next_break = -1; - UChar last_last_ch = pos > 1 ? str[pos - 2] : 0; - UChar last_ch = pos > 0 ? str[pos - 1] : 0; - bool is_last_space = IsBreakableSpace(last_ch); ULineBreak last_line_break; - if (lineBreakType == LineBreakType::kBreakAll) - last_line_break = LineBreakPropertyValue(last_last_ch, last_ch); - CharacterType ch; - bool is_space; - for (int i = pos; i < len; - i++, last_last_ch = last_ch, last_ch = ch, is_last_space = is_space) { - ch = str[i]; - - is_space = IsBreakableSpace(ch); + if (lineBreakType == LineBreakType::kBreakAll) { + last_line_break = + LineBreakPropertyValue(context.last_last_ch, context.last.ch); + } + for (int i = pos; context.Fetch(str, len, i); context.Advance(i)) { switch (break_space) { case BreakSpaceType::kAfterSpaceRun: - if (is_space) + if (context.current.is_space) { continue; - if (is_last_space) + } + if (context.last.is_space) { return i; + } break; case BreakSpaceType::kAfterEverySpace: - if (is_last_space || IsOtherSpaceSeparator<CharacterType>(last_ch)) + if (context.last.is_space || + IsOtherSpaceSeparator<CharacterType>(context.last.ch)) { return i; - if ((is_space || IsOtherSpaceSeparator<CharacterType>(ch)) && - i + 1 < len) + } + if ((context.current.is_space || + IsOtherSpaceSeparator<CharacterType>(context.current.ch)) && + i + 1 < len) { return i + 1; + } break; } - if (ShouldBreakAfter(last_last_ch, last_ch, ch)) + if (ShouldBreakAfter(context.last_last_ch, context.last.ch, + context.current.ch)) { return i; + } - if (lineBreakType == LineBreakType::kBreakAll && !U16_IS_LEAD(ch)) { - ULineBreak line_break = LineBreakPropertyValue(last_ch, ch); + if (lineBreakType == LineBreakType::kBreakAll && + !U16_IS_LEAD(context.current.ch)) { + ULineBreak line_break = + LineBreakPropertyValue(context.last.ch, context.current.ch); if (ShouldBreakAfterBreakAll(last_line_break, line_break)) - return i > pos && U16_IS_TRAIL(ch) ? i - 1 : i; + return i > pos && U16_IS_TRAIL(context.current.ch) ? i - 1 : i; if (line_break != U_LB_COMBINING_MARK) last_line_break = line_break; } if (lineBreakType == LineBreakType::kKeepAll && - ShouldKeepAfterKeepAll(last_last_ch, last_ch, ch)) { + ShouldKeepAfterKeepAll(context.last_last_ch, context.last.ch, + context.current.ch)) { // word-break:keep-all prevents breaks between East Asian ideographic. continue; } - if (NeedsLineBreakIterator(ch) || NeedsLineBreakIterator(last_ch)) { + if (NeedsLineBreakIterator(context.current.ch) || + NeedsLineBreakIterator(context.last.ch)) { if (next_break < i) { // Don't break if positioned at start of primary context. if (i) { @@ -376,8 +426,9 @@ } } } - if (i == next_break && !is_last_space) + if (i == next_break && !context.last.is_space) { return i; + } } }
diff --git a/third_party/blink/renderer/platform/text/text_break_iterator.h b/third_party/blink/renderer/platform/text/text_break_iterator.h index bb00bdb..d10dfa4 100644 --- a/third_party/blink/renderer/platform/text/text_break_iterator.h +++ b/third_party/blink/renderer/platform/text/text_break_iterator.h
@@ -227,6 +227,9 @@ private: FRIEND_TEST_ALL_PREFIXES(TextBreakIteratorTest, Strictness); + template <typename CharacterType> + struct Context; + const AtomicString& LocaleWithKeyword() const; void InvalidateLocaleWithKeyword();
diff --git a/third_party/blink/web_tests/ChromeTestExpectations b/third_party/blink/web_tests/ChromeTestExpectations index b7a646cf..0496fd2 100644 --- a/third_party/blink/web_tests/ChromeTestExpectations +++ b/third_party/blink/web_tests/ChromeTestExpectations
@@ -66,6 +66,7 @@ crbug.com/1499775 external/wpt/credential-management/fedcm-auto-reauthn-without-approved-clients.https.html [ Crash Pass Timeout ] crbug.com/1499775 external/wpt/credential-management/fedcm-returning-account-auto-reauthn.https.html [ Crash Pass Timeout ] crbug.com/1499775 external/wpt/credential-management/fedcm-pending-disconnect.https.html [ Crash Pass Timeout ] +crbug.com/1499775 external/wpt/credential-management/fedcm-too-many-disconnect-calls.https.html [ Crash Pass Timeout ] crbug.com/1499775 external/wpt/credential-management/fedcm-pending-userinfo.https.html [ Crash Pass Timeout ] crbug.com/1499775 wpt_internal/credential-management/fedcm-mismatch-dialog.tentative.https.html [ Crash Pass Timeout ] crbug.com/1499775 external/wpt/css/css-grid/alignment/grid-item-aspect-ratio-stretch-4.html [ Failure Pass ] @@ -584,6 +585,7 @@ crbug.com/1507050 external/wpt/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-inline-classic.html [ Failure Pass ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/svg/pservers/reftests/gradient-color-interpolation.svg [ Failure ] crbug.com/626703 external/wpt/webdriver/tests/bidi/network/continue_response/invalid.py [ Timeout ] crbug.com/626703 external/wpt/webdriver/tests/bidi/network/continue_with_auth/invalid.py [ Timeout ] crbug.com/626703 external/wpt/webdriver/tests/bidi/network/fail_request/invalid.py [ Timeout ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 4fb4656b..dda38ed 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2628,6 +2628,7 @@ crbug.com/626703 external/wpt/editing/other/insertparagraph-in-editing-host-cannot-have-div.tentative.html* [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/svg/pservers/reftests/gradient-color-interpolation.svg [ Failure ] crbug.com/626703 virtual/webnn-service-enabled/external/wpt/webnn/gpu/arg_min_max.https.any.html [ Skip Timeout ] crbug.com/626703 virtual/webnn-service-enabled/external/wpt/webnn/gpu/arg_min_max.https.any.worker.html [ Crash ] crbug.com/626703 [ Mac13 ] virtual/threaded/external/wpt/long-animation-frame/tentative/loaf-source-location-redirect.html [ Skip Timeout ] @@ -5144,9 +5145,6 @@ crbug.com/1509336 http/tests/devtools/network/json-preview.js [ Failure Pass ] crbug.com/1509336 http/tests/devtools/network/network-choose-preview-view.js [ Failure Pass ] -# Interop PE 2022-2023 investigation -crbug.com/269917 external/wpt/uievents/mouse/cancel-mousedown-in-subframe.html [ Timeout ] - # Possible Interop PE 2024 investigation crbug.com/1495467 external/wpt/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative.html?buttonType=LEFT&button=0&buttons=1 [ Failure ] crbug.com/1495467 external/wpt/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative.html?buttonType=MIDDLE&button=1&buttons=4 [ Failure ] @@ -5611,6 +5609,8 @@ crbug.com/1462683 [ Mac12-arm64 ] virtual/threaded/external/wpt/long-animation-frame/tentative/loaf-iframe-self.html [ Skip Timeout ] crbug.com/1462683 [ Mac11-arm64 ] virtual/threaded/external/wpt/long-animation-frame/tentative/loaf-iframe-self.html [ Skip Timeout ] +crbug.com/1455262 virtual/view-transition/external/wpt/soft-navigation-heuristics/navigation-api-view-transition.tentative.html [ Failure Pass Crash Skip ] + # Suppress http/tests/inspector-protocol/network/navigate-iframe-in2out.js test cluster crbug.com/1413112 [ Mac10.15 ] virtual/reduce-accept-language/http/tests/inspector-protocol/network/navigate-iframe-in2out.js [ Failure ] crbug.com/1413726 [ Mac ] http/tests/inspector-protocol/network/navigate-iframe-in2out.js [ Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 4db30ac..29e9eac 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1824,7 +1824,7 @@ "--disable-headless-mode", "--disable-threaded-compositing", "--disable-threaded-animation" ], - "expires": "Jul 1, 2023" + "expires": "Dec 1, 2024" }, { @@ -2210,7 +2210,7 @@ "--disable-blink-features=PointerEventDeviceId", "--disable-threaded-compositing", "--disable-threaded-animation" ], - "expires": "Jul 1, 2023" + "expires": "Jul 1, 2024" }, { "prefix": "abort-signal-any-disabled",
diff --git a/third_party/blink/web_tests/css3/zoom-coords-expected.txt b/third_party/blink/web_tests/css3/zoom-coords-expected.txt index 8ea8440e..d0f8842b 100644 --- a/third_party/blink/web_tests/css3/zoom-coords-expected.txt +++ b/third_party/blink/web_tests/css3/zoom-coords-expected.txt
@@ -23,19 +23,19 @@ PASS div2.left is 0 -PASS div2.top is 25 -PASS div2.width is 100 -PASS div2.height is 50 -PASS div2.right is 100 -PASS div2.bottom is 75 +PASS div2.top is 50 +PASS div2.width is 200 +PASS div2.height is 100 +PASS div2.right is 200 +PASS div2.bottom is 150 PASS div3.left is 0 -PASS div3.top is 300 -PASS div3.width is 200 -PASS div3.height is 100 -PASS div3.right is 200 -PASS div3.bottom is 400 +PASS div3.top is 150 +PASS div3.width is 100 +PASS div3.height is 50 +PASS div3.right is 100 +PASS div3.bottom is 200 Checking SVG elements: @@ -64,52 +64,52 @@ PASS text1.height is within 1 of 6 -PASS svg2.left is 75 -PASS svg2.top is 100 -PASS svg2.width is 150 -PASS svg2.height is 50 -PASS svg2.right is 225 -PASS svg2.bottom is 150 -PASS rect2.left is 75 -PASS rect2.top is 100 -PASS rect2.width is 100 -PASS rect2.height is 50 -PASS rect2.right is 175 -PASS rect2.bottom is 150 -PASS image2.left is 175 -PASS image2.top is 100 -PASS image2.width is 50 -PASS image2.height is 25 -PASS image2.right is 225 -PASS image2.bottom is 125 -PASS text2.left is 175 -PASS text2.top is within 1 of 132 -PASS text2.width is within 0.02 of text1.width -PASS text2.height is within 0.02 of text1.height +PASS svg2.left is 150 +PASS svg2.top is 200 +PASS svg2.width is 300 +PASS svg2.height is 100 +PASS svg2.right is 450 +PASS svg2.bottom is 300 +PASS rect2.left is 150 +PASS rect2.top is 200 +PASS rect2.width is 200 +PASS rect2.height is 100 +PASS rect2.right is 350 +PASS rect2.bottom is 300 +PASS image2.left is 350 +PASS image2.top is 200 +PASS image2.width is 100 +PASS image2.height is 50 +PASS image2.right is 450 +PASS image2.bottom is 250 +PASS text2.left is 350 +PASS text2.top is within 1 of 265 +PASS text2.width is within 0.02 of (text1.width * 2) +PASS text2.height is within 0.02 of (text1.height * 2) -PASS svg3.left is 900 -PASS svg3.top is 500 -PASS svg3.width is 300 -PASS svg3.height is 100 -PASS svg3.right is 1200 -PASS svg3.bottom is 600 -PASS rect3.left is 900 -PASS rect3.top is 500 -PASS rect3.width is 200 -PASS rect3.height is 100 -PASS rect3.right is 1100 -PASS rect3.bottom is 600 -PASS image3.left is 1100 -PASS image3.top is 500 -PASS image3.width is 100 -PASS image3.height is 50 -PASS image3.right is 1200 -PASS image3.bottom is 550 -PASS text3.left is 1100 -PASS text3.top is within 1 of 565 -PASS text3.width is within 0.02 of (text1.width * 2) -PASS text3.height is within 0.02 of (text1.height * 2) +PASS svg3.left is 450 +PASS svg3.top is 250 +PASS svg3.width is 150 +PASS svg3.height is 50 +PASS svg3.right is 600 +PASS svg3.bottom is 300 +PASS rect3.left is 450 +PASS rect3.top is 250 +PASS rect3.width is 100 +PASS rect3.height is 50 +PASS rect3.right is 550 +PASS rect3.bottom is 300 +PASS image3.left is 550 +PASS image3.top is 250 +PASS image3.width is 50 +PASS image3.height is 25 +PASS image3.right is 600 +PASS image3.bottom is 275 +PASS text3.left is 550 +PASS text3.top is within 1 of 282 +PASS text3.width is within 0.02 of text1.width +PASS text3.height is within 0.02 of text1.height PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/css3/zoom-coords.xhtml b/third_party/blink/web_tests/css3/zoom-coords.xhtml index 32753ca4..bf8de73 100644 --- a/third_party/blink/web_tests/css3/zoom-coords.xhtml +++ b/third_party/blink/web_tests/css3/zoom-coords.xhtml
@@ -85,20 +85,20 @@ var div2 = document.getElementById("div2").getBoundingClientRect(); shouldBe('div2.left', '0'); -shouldBe('div2.top', '25'); -shouldBe('div2.width', '100'); -shouldBe('div2.height', '50'); -shouldBe('div2.right', '100'); -shouldBe('div2.bottom', '75'); +shouldBe('div2.top', '50'); +shouldBe('div2.width', '200'); +shouldBe('div2.height', '100'); +shouldBe('div2.right', '200'); +shouldBe('div2.bottom', '150'); debug(""); var div3 = document.getElementById("div3").getBoundingClientRect(); shouldBe('div3.left', '0'); -shouldBe('div3.top', '300'); -shouldBe('div3.width', '200'); -shouldBe('div3.height', '100'); -shouldBe('div3.right', '200'); -shouldBe('div3.bottom', '400'); +shouldBe('div3.top', '150'); +shouldBe('div3.width', '100'); +shouldBe('div3.height', '50'); +shouldBe('div3.right', '100'); +shouldBe('div3.bottom', '200'); debug(""); debug("Checking SVG elements:"); @@ -133,61 +133,61 @@ debug(""); var svg2 = document.getElementById("svg2").getBoundingClientRect(); -shouldBe('svg2.left', '75'); -shouldBe('svg2.top', '100'); -shouldBe('svg2.width', '150'); -shouldBe('svg2.height', '50'); -shouldBe('svg2.right', '225'); -shouldBe('svg2.bottom', '150'); +shouldBe('svg2.left', '150'); +shouldBe('svg2.top', '200'); +shouldBe('svg2.width', '300'); +shouldBe('svg2.height', '100'); +shouldBe('svg2.right', '450'); +shouldBe('svg2.bottom', '300'); var rect2 = document.getElementById("rect2").getBoundingClientRect(); -shouldBe('rect2.left', '75'); -shouldBe('rect2.top', '100'); -shouldBe('rect2.width', '100'); -shouldBe('rect2.height', '50'); -shouldBe('rect2.right', '175'); -shouldBe('rect2.bottom', '150'); +shouldBe('rect2.left', '150'); +shouldBe('rect2.top', '200'); +shouldBe('rect2.width', '200'); +shouldBe('rect2.height', '100'); +shouldBe('rect2.right', '350'); +shouldBe('rect2.bottom', '300'); var image2 = document.getElementById("image2").getBoundingClientRect(); -shouldBe('image2.left', '175'); -shouldBe('image2.top', '100'); -shouldBe('image2.width', '50'); -shouldBe('image2.height', '25'); -shouldBe('image2.right', '225'); -shouldBe('image2.bottom', '125'); +shouldBe('image2.left', '350'); +shouldBe('image2.top', '200'); +shouldBe('image2.width', '100'); +shouldBe('image2.height', '50'); +shouldBe('image2.right', '450'); +shouldBe('image2.bottom', '250'); var text2 = document.getElementById("text2").getBoundingClientRect(); -shouldBe('text2.left', '175'); +shouldBe('text2.left', '350'); msgDumpRenderTreeRequired(); -shouldBeCloseTo('text2.top', 132, 1); -shouldBeCloseTo('text2.width', 'text1.width', tolerance); -shouldBeCloseTo('text2.height', 'text1.height', tolerance); +shouldBeCloseTo('text2.top', 265, 1); +shouldBeCloseTo('text2.width', '(text1.width * 2)', tolerance); +shouldBeCloseTo('text2.height', '(text1.height * 2)', tolerance); debug(""); var svg3 = document.getElementById("svg3").getBoundingClientRect(); -shouldBe('svg3.left', '900'); -shouldBe('svg3.top', '500'); -shouldBe('svg3.width', '300'); -shouldBe('svg3.height', '100'); -shouldBe('svg3.right', '1200'); -shouldBe('svg3.bottom', '600'); +shouldBe('svg3.left', '450'); +shouldBe('svg3.top', '250'); +shouldBe('svg3.width', '150'); +shouldBe('svg3.height', '50'); +shouldBe('svg3.right', '600'); +shouldBe('svg3.bottom', '300'); var rect3 = document.getElementById("rect3").getBoundingClientRect(); -shouldBe('rect3.left', '900'); -shouldBe('rect3.top', '500'); -shouldBe('rect3.width', '200'); -shouldBe('rect3.height', '100'); -shouldBe('rect3.right', '1100'); -shouldBe('rect3.bottom', '600'); +shouldBe('rect3.left', '450'); +shouldBe('rect3.top', '250'); +shouldBe('rect3.width', '100'); +shouldBe('rect3.height', '50'); +shouldBe('rect3.right', '550'); +shouldBe('rect3.bottom', '300'); var image3 = document.getElementById("image3").getBoundingClientRect(); -shouldBe('image3.left', '1100'); -shouldBe('image3.top', '500'); -shouldBe('image3.width', '100'); -shouldBe('image3.height', '50'); -shouldBe('image3.right', '1200'); -shouldBe('image3.bottom', '550'); +shouldBe('image3.left', '550'); +shouldBe('image3.top', '250'); +shouldBe('image3.width', '50'); +shouldBe('image3.height', '25'); +shouldBe('image3.right', '600'); +shouldBe('image3.bottom', '275'); var text3 = document.getElementById("text3").getBoundingClientRect(); -shouldBe('text3.left', '1100'); +shouldBe('text3.left', '550'); msgDumpRenderTreeRequired(); -shouldBeCloseTo('text3.top', 565, 1); -shouldBeCloseTo('text3.width', '(text1.width * 2)', tolerance); -shouldBeCloseTo('text3.height', '(text1.height * 2)', tolerance); +shouldBeCloseTo('text3.top', 282, 1); +shouldBeCloseTo('text3.width', 'text1.width', tolerance); +shouldBeCloseTo('text3.height', 'text1.height', tolerance); debug(""); </script>
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 c5c421cf..f618c40 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
@@ -155415,6 +155415,19 @@ {} ] ], + "clip-path-url-reference-svg-foreignobject-zoomed.html": [ + "df8d0cc89cc2211a29245797f135b98ed49e5cdc", + [ + null, + [ + [ + "/css/css-masking/clip-path/reference/green-100x100.html", + "==" + ] + ], + {} + ] + ], "clip-path-viewBox-1a.html": [ "5b029e1ef7cfea200416bd99314c7288e44e3f60", [ @@ -158528,6 +158541,19 @@ {} ] ], + "mask-position-8.html": [ + "cb99135fa1df5d8caa7cfec928a55bf738d78b8e", + [ + null, + [ + [ + "/css/css-masking/clip-path/reference/green-100x100.html", + "==" + ] + ], + {} + ] + ], "mask-repeat-1-svg.html": [ "ba96faf18fe6d0e3f125459d5d5bfa9a3e30de23", [ @@ -259754,6 +259780,19 @@ {} ] ], + "has-style-sharing-007.html": [ + "494ff15796af6bc0e112a51ffe1f4a0e43a06ef3", + [ + null, + [ + [ + "/css/selectors/has-style-sharing-007-ref.html", + "==" + ] + ], + {} + ] + ], "has-visited.html": [ "8fe322c8b1751b2f4232e9898fa71bab5e203cde", [ @@ -284310,6 +284349,35 @@ }, "pservers": { "reftests": { + "gradient-color-interpolation.svg": [ + "f7959437734230d394197d1837be2ba6ffaa7d3c", + [ + null, + [ + [ + "/svg/pservers/reftests/reference/gradient-color-interpolation-ref.svg", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 20 + ], + [ + 0, + 29200 + ] + ] + ] + ] + } + ] + ], "meshgradient-basic-001.svg": [ "24290d40d6c37583d86aae4a098293c6cb8a6653", [ @@ -345367,6 +345435,10 @@ "4c03f2150ad15fdf08b49a2dee138d25e6e91aa1", [] ], + "has-style-sharing-007-ref.html": [ + "0f26fb2987e0dbc25573f53c5c37d8676f7db8ec", + [] + ], "has-visited-ref.html": [ "3f54e2e3914f62a81c3199bbe3d8c0339b9c2ba8", [] @@ -371346,6 +371418,12 @@ "3195b8671c55d4e8f5c7b449b73d4581028d5f40", [] ], + "case-sensitivity": { + "values.window-expected.txt": [ + "f44db709c3806decfb2088663b40686f99ffdd83", + [] + ] + }, "pseudo-classes": { "checked-indeterminate.window-expected.txt": [ "15e63a9a7ad831ff201eb05ee60f1c6b2ce189ee", @@ -372885,6 +372963,26 @@ "35449ec5bab7c3e8ac3c61fa50a8207e667eabe2", [] ], + "activation-trigger-keyboard-enter-expected.txt": [ + "07edbf06dc1093051753fc4aa343be936afa463e", + [] + ], + "activation-trigger-keyboard-escape-expected.txt": [ + "57e8ff4711e5b7755672b875ce4c51cb8e8f705d", + [] + ], + "activation-trigger-mouse-left-expected.txt": [ + "18ce0222ceedcdecd35493453f2c6aab8354e640", + [] + ], + "activation-trigger-mouse-right-expected.txt": [ + "404856b7dbeb66a4be578ed7dde49d88e0c571b6", + [] + ], + "activation-trigger-pointerevent_mouse-expected.txt": [ + "1f796f76ec179759cb192d4d9404fe1958d3fbe2", + [] + ], "propagation-sameorigin-expected.txt": [ "6e8e5d65d08e3d1f78029107de443f94a1f1befb", [] @@ -372919,7 +373017,7 @@ [] ], "utils.js": [ - "5d3302583fbd968f990c7fd58a84bdc11f31993c", + "8cca6654e7f3968ca540e04ccbe11faa60baa5cf", [] ] } @@ -390233,6 +390331,10 @@ [] ], "reference": { + "gradient-color-interpolation-ref.svg": [ + "e7e475eeb16692d7e1e6c4a84c413ada74542665", + [] + ], "green-100x100.svg": [ "120941444a4898197d6b6001f9908a6cd48b62ba", [] @@ -468413,7 +468515,7 @@ ] ], "progress-computed.tentative.html": [ - "2f564fa14e9e1ba1cb083d00fa64ae5029d9be3b", + "2ef09996d55a758f17cf33987c21ca9f26e36e7f", [ null, {} @@ -574885,6 +574987,15 @@ } }, "selectors": { + "case-sensitivity": { + "values.window.js": [ + "1973398bff89b62e8bd644fe8a1e5f35bf5c6ed7", + [ + "html/semantics/selectors/case-sensitivity/values.window.html", + {} + ] + ] + }, "pseudo-classes": { "active-disabled.html": [ "a75a157c58f57814f421bd19aa588eaf75270f73", @@ -618554,6 +618665,15 @@ null, {} ] + ], + "move-around-contenteditable-false.html": [ + "256804f17a774aa66b2da877d59e586b0648b839", + [ + null, + { + "testdriver": true + } + ] ] }, "collapse-00.html": [ @@ -653224,7 +653344,7 @@ }, "webauthn": { "conditional-mediation.https.html": [ - "0bec08ce45eddb1a336f421da4ed9a29b268453f", + "1eb2ba3b1e750b261b2ae71fbf6172c624503cb2", [ null, {
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-too-many-disconnect-calls.https.html b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-too-many-disconnect-calls.https.html new file mode 100644 index 0000000..cb5dfa6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-too-many-disconnect-calls.https.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<title>Federated Credential Management API two disconnect() at the same time.</title> +<link rel="help" href="https://fedidcg.github.io/FedCM"> +<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> + +<body> + +<script type="module"> +import {fedcm_test, + mark_signed_in, + set_fedcm_cookie, + fedcm_get_and_select_first_account, + manifest_origin, + request_options_with_mediation_required, + disconnect_options} from './support/fedcm-helper.sub.js'; + +fedcm_test(async t => { + await mark_signed_in(); + await set_fedcm_cookie(); + // Get at least one connected account that can be disconnected. + const cred = await fedcm_get_and_select_first_account(t, request_options_with_mediation_required()); + const manifest = `${manifest_origin}/\ +credential-management/support/fedcm/manifest.py`; + const options = disconnect_options("1234"); + IdentityCredential.disconnect(options); + await promise_rejects_dom(t, 'NetworkError', IdentityCredential.disconnect(options)); +}, "When disconnect is called while there is a pending one, it is rejected."); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/has-style-sharing-007-ref.html b/third_party/blink/web_tests/external/wpt/css/selectors/has-style-sharing-007-ref.html new file mode 100644 index 0000000..0f26fb2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/has-style-sharing-007-ref.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com"> +<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1869771"> +<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching."> +<style> +.cousin { + width: 1em; + height: 1em; + background: purple; +} +.special.cousin.has { + background: blue; +} +</style> +<div class="sib"> + <div class="cousin"></div> +</div> +<br> +<div class="sib"> + <div class="cousin special"></div> + <br> + <div class="cousin special has"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/has-style-sharing-007.html b/third_party/blink/web_tests/external/wpt/css/selectors/has-style-sharing-007.html new file mode 100644 index 0000000..494ff15 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/has-style-sharing-007.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com"> +<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1869771"> +<link rel="match" href="has-style-sharing-007-ref.html"> +<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching."> +<style> +.cousin { + width: 1em; + height: 1em; + background: purple; +} +.special.cousin:not(:has(span)) { + background: blue; +} +</style> +<div class="sib"> + <div class="cousin"></div> +</div> +<br> +<div class="sib"> + <div class="cousin special"> + <span></span> + </div> + <br> + <div class="cousin special"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/case-sensitivity/values.window-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/case-sensitivity/values.window-expected.txt new file mode 100644 index 0000000..f44db70 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/case-sensitivity/values.window-expected.txt
@@ -0,0 +1,96 @@ +This is a testharness.js-based test. +Found 46 FAIL, 0 TIMEOUT, 0 NOTRUN. +[FAIL] accept's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] accept-charset's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] align's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] alink's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] axis's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] bgcolor's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] charset's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] checked's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] clear's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] codetype's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] color's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] compact's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] declare's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] defer's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] dir's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] direction's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] disabled's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] enctype's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] face's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] frame's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] hreflang's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] http-equiv's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] lang's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] language's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] link's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] media's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] method's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] multiple's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] nohref's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] noresize's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] noshade's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] nowrap's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] readonly's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] rel's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] rev's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] rules's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] scope's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] scrolling's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] selected's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] shape's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] target's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] text's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] type's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] valign's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] valuetype's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +[FAIL] vlink's value is properly ASCII-case-insensitive for <:unknown> in HTML + assert_equals: ^=hey expected false but got true +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/selectors/case-sensitivity/values.window.js b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/case-sensitivity/values.window.js new file mode 100644 index 0000000..1973398 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/selectors/case-sensitivity/values.window.js
@@ -0,0 +1,91 @@ +// https://html.spec.whatwg.org/#case-sensitivity-of-selectors +[ + "accept", + "accept-charset", + "align", + "alink", + "axis", + "bgcolor", + "charset", + "checked", + "clear", + "codetype", + "color", + "compact", + "declare", + "defer", + "dir", + "direction", + "disabled", + "enctype", + "face", + "frame", + "hreflang", + "http-equiv", + "lang", + "language", + "link", + "media", + "method", + "multiple", + "nohref", + "noresize", + "noshade", + "nowrap", + "readonly", + "rel", + "rev", + "rules", + "scope", + "scrolling", + "selected", + "shape", + "target", + "text", + "type", + "valign", + "valuetype", + "vlink", +].forEach(attributeName => { + const xmlDocument = new Document(); + const htmlDocument = document; + [ + { + input: xmlDocument.createElementNS("http://www.w3.org/1999/xhtml", "a"), + expected: false, + title: "<html:a> in XML", + }, + { + input: xmlDocument.createElementNS("http://www.w3.org/1999/xhtml", "unknown"), + expected: false, + title: "<html:unknown> in XML", + }, + { + input: xmlDocument.createElementNS("", "unknown"), + expected: false, + title: "<:unknown> in XML" + }, + { + input: htmlDocument.createElementNS("http://www.w3.org/1999/xhtml", "a"), + expected: true, + title: "<html:a> in HTML", + }, + { + input: htmlDocument.createElementNS("http://www.w3.org/1999/xhtml", "unknown"), + expected: true, + title: "<html:unknown> in HTML", + }, + { + input: htmlDocument.createElementNS("", "unknown"), + expected: false, + title: "<:unknown> in HTML" + }, + ].forEach(({ input, expected, title }) => { + test(t => { + t.add_cleanup(() => input.removeAttribute(attributeName)); + input.setAttribute(attributeName, "HEYÏ"); + assert_equals(input.matches(`[${attributeName}^=hey]`), expected, `^=hey`); + assert_false(input.matches(`[${attributeName}^=heyi]`)); + }, `${attributeName}'s value is properly ASCII-case-insensitive for ${title}`); + }); +});
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-keyboard-enter-expected.txt b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-keyboard-enter-expected.txt new file mode 100644 index 0000000..07edbf0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-keyboard-enter-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] Activation through ENTER keyboard event + promise_test: Unhandled rejection with value: object "Error: User activation is not active so can't be consumed. Something is probably wrong with the test." +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-keyboard-escape-expected.txt b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-keyboard-escape-expected.txt new file mode 100644 index 0000000..57e8ff4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-keyboard-escape-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] Activation through ESCAPE keyboard event + promise_test: Unhandled rejection with value: object "Error: User activation is not active so can't be consumed. Something is probably wrong with the test." +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-mouse-left-expected.txt b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-mouse-left-expected.txt new file mode 100644 index 0000000..18ce022 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-mouse-left-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] Activation through left-click mouse event + promise_test: Unhandled rejection with value: object "Error: User activation is not active so can't be consumed. Something is probably wrong with the test." +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-mouse-right-expected.txt b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-mouse-right-expected.txt new file mode 100644 index 0000000..404856b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-mouse-right-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] Activation through right-click mouse event + promise_test: Unhandled rejection with value: object "Error: User activation is not active so can't be consumed. Something is probably wrong with the test." +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-pointerevent_mouse-expected.txt b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-pointerevent_mouse-expected.txt new file mode 100644 index 0000000..1f796f76 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-trigger-pointerevent_mouse-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] Activation through mouse pointerevent click + promise_test: Unhandled rejection with value: object "Error: User activation is not active so can't be consumed. Something is probably wrong with the test." +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/resources/utils.js b/third_party/blink/web_tests/external/wpt/html/user-activation/resources/utils.js index 5d33025..8cca6654 100644 --- a/third_party/blink/web_tests/external/wpt/html/user-activation/resources/utils.js +++ b/third_party/blink/web_tests/external/wpt/html/user-activation/resources/utils.js
@@ -1,37 +1,56 @@ +/** + * Calls the function (f) after N number of frames have passed. + * + * @param {Function} f + * @param {number} num_frames + */ function delayByFrames(f, num_frames) { function recurse(depth) { - if (depth == 0) - f(); - else - requestAnimationFrame(() => recurse(depth-1)); + if (depth == 0) f(); + else requestAnimationFrame(() => recurse(depth - 1)); } recurse(num_frames); } -// Returns a Promise which is resolved with the event object when the event is -// fired. -function getEvent(eventType) { - return new Promise(resolve => { - document.body.addEventListener(eventType, e => resolve(e), {once: true}); +/** + * @param {string} eventType + * @param {object} options EventListenerOptions + * @returns {Promise<Event>} Resolved when the event is fired. + */ +function getEvent(eventType, options = { once: true }) { + return new Promise((resolve) => { + document.body.addEventListener(eventType, resolve, options); }); } - -// Returns a Promise which is resolved with a "true" iff transient activation -// was available and successfully consumed. -// -// This function relies on Fullscreen API to check/consume user activation -// state. -async function consumeTransientActivation() { - try { - await document.body.requestFullscreen(); - await document.exitFullscreen(); - return true; - } catch(e) { - return false; +/** + * + * @param {Window} context + * @returns {Promise<Boolean>} resolved with a true if transient activation is consumed. + */ +async function consumeTransientActivation(context = window) { + if (!context.navigator.userActivation.isActive) { + throw new Error( + "User activation is not active so can't be consumed. Something is probably wrong with the test." + ); } + if (test_driver?.consume_user_activation) { + return test_driver.consume_user_activation(context); + } + // fallback to Fullscreen API. + if (!context.document.fullscreenElement) { + await context.document.documentElement.requestFullscreen(); + } + await context.document.exitFullscreen(); + return !context.navigator.userActivation.isActive; } +/** + * Waits for a message to be sent from an iframe. + * + * @param {string} type + * @returns {Promise<Object>} + */ function receiveMessage(type) { return new Promise((resolve) => { window.addEventListener("message", function listener(event) { @@ -46,3 +65,19 @@ }); }); } + +/** + * Creates an iframe and waits for it to load... + * + * @param {String} src + * @returns {Promise<HTMLIFrameElement>} + */ +async function attachIframe(src, document = window.document) { + const iframe = document.createElement("iframe"); + await new Promise((resolve) => { + iframe.addEventListener("load", resolve, { once: true }); + document.body.appendChild(iframe); + iframe.src = src; + }); + return iframe; +}
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/bounding-box.html b/third_party/blink/web_tests/external/wpt/intersection-observer/bounding-box.html index 367243d5..0206bfe 100644 --- a/third_party/blink/web_tests/external/wpt/intersection-observer/bounding-box.html +++ b/third_party/blink/web_tests/external/wpt/intersection-observer/bounding-box.html
@@ -75,8 +75,8 @@ 176 // root width including border -8 // root left border -20 // target left margin * target zoom - ) / 2; // convert to target's zoom factor. - var intersectionHeight = (216 - 8 - 20) / 2; + ) + var intersectionHeight = (216 - 8 - 20); var intersectionRect = [targetBounds[0], targetBounds[0] + intersectionWidth, targetBounds[2], targetBounds[2] + intersectionHeight]; checkLastEntry(entries, 3, targetBounds.concat(intersectionRect).concat(8, 184, 8, 224, true));
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/zoom-scaled-target.html b/third_party/blink/web_tests/external/wpt/intersection-observer/zoom-scaled-target.html new file mode 100644 index 0000000..6ad7559 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/intersection-observer/zoom-scaled-target.html
@@ -0,0 +1,62 @@ +<!DOCTYPE html> +<title>IntersectionObserver observing elements with css zoom</title> +<link rel="author" title="Yotam Hacohen" href="mailto:yotha@chromium.org"> +<link rel="author" title="Google" href="http://www.google.com/"> +<meta name="viewport" content="width=device-width,initial-scale=1"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/intersection-observer-test-utils.js"></script> + <head> + <style> + div { + width: 64px; + height: 64px; + background-color: blue + } + div.a { + zoom: 1.0; + width: 512px; + height: 512px; + } + + div.b { + zoom: 4.0; + background-color: pink; + } + </style> + </head> + <body> + <div class="a" id="ToBeRemoved"> + <div class="b" id="target"></div> + </div> + <script> + const viewportWidth = document.documentElement.clientWidth; + const viewportHeight = document.documentElement.clientHeight; + setup(() => { + window.entries = []; + window.target = document.getElementById("target"); + window.targetRect = target.getBoundingClientRect(); + }); + runTestCycle(function() { + assert_true(!!target, "target exists"); + const observer = new IntersectionObserver(function(changes) { + entries = entries.concat(changes); + }); + observer.observe(target); + entries = entries.concat(observer.takeRecords()); + assert_equals(entries.length, 0, "No initial notifications"); + runTestCycle(validateIntersectionRect, "Validate intersection rect"); + }); + function validateIntersectionRect() { + // The numbers in brackets are target client rect; intersection rect; + // and root bounds. + checkLastEntry(entries, 0, [ + // the 8 pixels comes from the html body padding. + 8, 8 + 256, 8, 8 + 256, + 8, 8 + 256, 8, 8 + 256, + 0, viewportWidth, 0, viewportHeight, + true, + ]); + } + </script> + </body>
diff --git a/third_party/blink/web_tests/external/wpt/selection/caret/move-around-contenteditable-false.html b/third_party/blink/web_tests/external/wpt/selection/caret/move-around-contenteditable-false.html new file mode 100644 index 0000000..256804f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/selection/caret/move-around-contenteditable-false.html
@@ -0,0 +1,189 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<title>Don't move caret to non-editable node from a editable node</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="/resources/testdriver-actions.js"></script> +<script> +"use strict"; + +function getRangeDescription(range) { + function getNodeDescription(node) { + if (!node) { + return "null"; + } + switch (node.nodeType) { + case Node.TEXT_NODE: + return `${node.nodeName} "${node.data}"`; + case Node.ELEMENT_NODE: + return `<${node.nodeName.toLowerCase()}>`; + default: + return `${node.nodeName}`; + } + } + if (range === null) { + return "null"; + } + if (range === undefined) { + return "undefined"; + } + return range.startContainer == range.endContainer && + range.startOffset == range.endOffset + ? `(${getNodeDescription(range.startContainer)}, ${range.startOffset})` + : `(${getNodeDescription(range.startContainer)}, ${ + range.startOffset + }) - (${getNodeDescription(range.endContainer)}, ${range.endOffset})`; +} + +function sendArrowRightKey() { + const kArrowRight = "\uE014"; + return new test_driver.Actions() + .keyDown(kArrowRight) + .keyUp(kArrowRight) + .send(); +} + +function sendArrowLeftKey() { + const kArrowLeft = "\uE012"; + return new test_driver.Actions() + .keyDown(kArrowLeft) + .keyUp(kArrowLeft) + .send(); +} + +promise_test(async () => { + await new Promise(resolve => { + addEventListener("load", resolve, {once: true}); + }); +}, "Initializing tests"); + +promise_test(async t => { + const editingHost = document.querySelector("div[contenteditable]"); + editingHost.focus(); + const p = editingHost.querySelector("p"); + getSelection().collapse(p.firstChild, "abc".length); + await sendArrowRightKey(); + test(() => { + assert_equals( + getRangeDescription(getSelection().getRangeAt(0)), + getRangeDescription({ + startContainer: p.nextSibling, + startOffset: 0, + endContainer: p.nextSibling, + endOffset: 0, + }), + ); + }, `${t.name}: first arrow-right should move caret before non-editable text`); + await sendArrowRightKey(); + test(() => { + assert_equals( + getRangeDescription(getSelection().getRangeAt(0)), + getRangeDescription({ + startContainer: p.nextSibling, + startOffset: 1, + endContainer: p.nextSibling, + endOffset: 1, + }), + ); + }, `${t.name}: second arrow-right should move caret after non-editable text`); +}, "Move caret from end of editable text node to <br> following non-editable text in next paragraph"); + +promise_test(async t => { + const editingHost = document.querySelector("div[contenteditable]"); + editingHost.focus(); + const p = editingHost.querySelector("p"); + getSelection().collapse(p.nextSibling, 1); + await sendArrowLeftKey(); + assert_false( + editingHost.querySelector("[contenteditable=false]").contains(getSelection().focusNode), + "focus node should not be the non-editable nodes" + ); + assert_false( + editingHost.querySelector("[contenteditable=false]").contains(getSelection().anchorNode), + "anchor node should not be the non-editable nodes" + ); + test(() => { + assert_equals( + getRangeDescription(getSelection().getRangeAt(0)), + getRangeDescription({ + startContainer: p.nextSibling, + startOffset: 0, + endContainer: p.nextSibling, + endOffset: 0, + }), + ); + }, `${t.name}: first arrow-left should move caret before non-editable text`); +}, "Move caret from <br> following non-editable text to end of preceding editable text in next paragraph"); + +promise_test(async t => { + const editingHost = document.querySelector("div[contenteditable] + div[contenteditable]"); + editingHost.focus(); + const p = editingHost.querySelector("p"); + getSelection().collapse(p.firstChild, 0); + await sendArrowRightKey(); + test(() => { + assert_equals( + getRangeDescription(getSelection().getRangeAt(0)), + getRangeDescription({ + startContainer: p.nextSibling, + startOffset: 0, + endContainer: p.nextSibling, + endOffset: 0, + }), + ); + }, `${t.name}: first arrow-right should move caret before non-editable text`); + await sendArrowRightKey(); + test(() => { + assert_equals( + getRangeDescription(getSelection().getRangeAt(0)), + getRangeDescription({ + startContainer: editingHost.querySelector("[contenteditable=false]").nextSibling, + startOffset: 0, + endContainer: editingHost.querySelector("[contenteditable=false]").nextSibling, + endOffset: 0, + }), + ); + }, `${t.name}: second arrow-right should move caret after non-editable text`); +}, "Move caret from empty editable paragraph to editable text following non-editable text in next paragraph"); + +promise_test(async t => { + const editingHost = document.querySelector("div[contenteditable] + div[contenteditable]"); + editingHost.focus(); + const p = editingHost.querySelector("p"); + getSelection().collapse(editingHost.querySelector("[contenteditable=false]").nextSibling, 0); + await sendArrowLeftKey(); + assert_false( + editingHost.querySelector("[contenteditable=false]").contains(getSelection().focusNode), + "focus node should not be the non-editable nodes" + ); + assert_false( + editingHost.querySelector("[contenteditable=false]").contains(getSelection().anchorNode), + "anchor node should not be the non-editable nodes" + ); + test(() => { + assert_equals( + getRangeDescription(getSelection().getRangeAt(0)), + getRangeDescription({ + startContainer: p.nextSibling, + startOffset: 0, + endContainer: p.nextSibling, + endOffset: 0, + }), + ); + }, `${t.name}: first arrow-left should move caret before non-editable text`); +}, "Move caret from start of text following non-editable text to empty preceding editable paragraph"); +</script> +</head> +<body> +<div contenteditable> +<p>abc</p><p><span contenteditable="false">def</span><br></p> +</div> +<div contenteditable> +<p><br></p><p><span contenteditable="false">abc</span>def</p> +</div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/dropped-entries.tentative.html b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/dropped-entries.tentative.html index 425f91a..d27ad45 100644 --- a/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/dropped-entries.tentative.html +++ b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/dropped-entries.tentative.html
@@ -19,7 +19,7 @@ testSoftNavigation({ addContent: async () => { - await addImageToMain(); + await addImageToMain('green-16x16.png'); }, link: link, clicks: 52, @@ -40,5 +40,3 @@ </script> </body> </html> - -
diff --git a/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/softnav-painted-area-is-reset.tentative.html b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/softnav-painted-area-is-reset.tentative.html new file mode 100644 index 0000000..0f5a1f4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/soft-navigation-heuristics/softnav-painted-area-is-reset.tentative.html
@@ -0,0 +1,123 @@ +<!DOCTYPE html> + +<head> + <meta charset="utf-8"> + <title>Soft Navigation Painted Area Should Be Reset With A New Soft Navigation.</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="resources/soft-navigation-helper.js"></script> + <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +</head> + +<body> + <p id="initial_paint"> + This is to make the initial painted area large so that the threshold for + soft navigations is large. + </p> + <a id=link1>Click</a> + <a id=link2>Click</a> + <script> + const link1 = document.getElementById("link1"); + const link2 = document.getElementById("link2"); + + const waitForElementTimingWithId = (id) => + new Promise(resolve => { + (new PerformanceObserver(list => { + if (list.getEntries().find(e => e.id.includes(id))) resolve(); + })).observe({ type: 'element' }); + }); + + + const waitForLcpWithId = async (id, includeSoftNavLcp) => { + let options = { + type: 'largest-contentful-paint', buffered: true, + } + if (includeSoftNavLcp) + options.includeSoftNavigationObservations = true; + + await new Promise(resolve => { + (new PerformanceObserver(list => { + if (list.getEntries().find(e => e.id.includes(id))) resolve(); + })).observe(options); + }); + } + + const addTextWithStateChange = (id, size, text) => { + history.pushState({}, '', `foobar_${id}.html`); + + const p = document.createElement("p"); + const textNode = document.createTextNode(text); + p.appendChild(textNode); + p.setAttribute("elementtiming", 'element_timing'); + p.id = id; + p.style = `font-size: ${size}em`; + document.body.appendChild(p); + } + + const SoftNavPromise = () => { + return new Promise(resolve => { + new PerformanceObserver(list => { + resolve(list.getEntries()); + } + ).observe({ type: 'soft-navigation' }); + }) + } + + promise_test(async t => { + // Wait for page load. + await waitForLcpWithId('initial_paint', false); + + link1.addEventListener('click', () => { + addTextWithStateChange('above_threshold', 4, + 'THIS IS A LARGE TEXT SO THAT THE SOFT NAV PAINTED AREA IS ABOVE THRESHOLD.'); + }) + + soft_nav_promise = SoftNavPromise(); + + waitForElementTimingPromise = waitForElementTimingWithId('above_threshold'); + + interact(link1); + + await waitForElementTimingPromise; + + await waitForLcpWithId('above_threshold', true); + + let soft_nav_entries = await soft_nav_promise; + + assert_equals(soft_nav_entries.length, 1, '1 soft nav entry should be emitted. '); + + assert_true(soft_nav_entries[0].name.includes('above_threshold'), + 'The soft nav entry name should include above_threshold.'); + + // Add a text that has a painted area under the threshold so that no soft + // navigaiton is emitted. + link2.addEventListener('click', () => { + addTextWithStateChange('under_threshold', 0.1, 'm'); + }) + + waitForElementTimingPromise = waitForElementTimingWithId('under_threshold'); + + interact(link2); + + await waitForElementTimingPromise; + + soft_nav_entries = await new Promise((resolve) => { + (new PerformanceObserver((list) => + resolve(list.getEntries()))).observe({ + type: 'soft-navigation', + buffered: true + }); + t.step_timeout(resolve, 1000); + }); + + assert_equals(soft_nav_entries.length, 1, 'No new soft navigation should emitted') + assert_true(soft_nav_entries[0].name.includes('above_threshold'), + 'The soft nav entry should be the one previously seen.'); + + + }, 'soft nav paitned area should be reset so that under threshold\ + soft nav painted area would not trigger a soft navigation.') + </script> +</body> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/svg/pservers/reftests/gradient-color-interpolation.svg b/third_party/blink/web_tests/external/wpt/svg/pservers/reftests/gradient-color-interpolation.svg new file mode 100644 index 0000000..f795943 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/pservers/reftests/gradient-color-interpolation.svg
@@ -0,0 +1,22 @@ +<svg width="100%" height="100%" + xmlns="http://www.w3.org/2000/svg" + xmlns:html="http://www.w3.org/1999/xhtml"> + <g id="testmeta"> + <title>Gradient with color-interpolation: linearRGB</title> + <html:link rel="help" + href="https://www.w3.org/TR/SVG2/pservers.html#LinearGradients"/> + <html:link rel="match" href="reference/gradient-color-interpolation-ref.svg" /> + <html:meta name="fuzzy" content="maxDifference=0-20;totalPixels=0-29200" /> + </g> + + <defs> + <linearGradient id="gradientLinearRGB" gradientUnits="objectBoundingBox" color-interpolation="linearRGB"> + <stop offset="0" stop-color="white"/> + <stop offset=".33" stop-color="blue"/> + <stop offset=".66" stop-color="red"/> + <stop offset="1" stop-color="yellow"/> + </linearGradient> + </defs> + + <rect x="20" y="20" width="200" height="200" style="fill:url(#gradientLinearRGB)" /> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/pservers/reftests/reference/gradient-color-interpolation-ref.svg b/third_party/blink/web_tests/external/wpt/svg/pservers/reftests/reference/gradient-color-interpolation-ref.svg new file mode 100644 index 0000000..e7e475ee --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/pservers/reftests/reference/gradient-color-interpolation-ref.svg
@@ -0,0 +1,24 @@ +<svg width="100%" height="100%" + xmlns="http://www.w3.org/2000/svg" + xmlns:html="http://www.w3.org/1999/xhtml"> + + <style> + div { + border: none; + margin: 0; + padding: 0; + }; + </style> + <defs> + <linearGradient id="gradientLinearRGB" gradientUnits="objectBoundingBox" color-interpolation="linearRGB"> + <stop offset="0" stop-color="white"/> + <stop offset=".33" stop-color="blue"/> + <stop offset=".66" stop-color="red"/> + <stop offset="1" stop-color="yellow"/> + </linearGradient> + </defs> + + <foreignObject x="20" y="20" width="200" height="200"> + <html:div style="height:100%;width:100%;background: linear-gradient(90deg in srgb-linear, white 0%, blue 33%, red 66%, yellow 100%);"/> + </foreignObject> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/webauthn/conditional-mediation.https.html b/third_party/blink/web_tests/external/wpt/webauthn/conditional-mediation.https.html index 0bec08c..1eb2ba3 100644 --- a/third_party/blink/web_tests/external/wpt/webauthn/conditional-mediation.https.html +++ b/third_party/blink/web_tests/external/wpt/webauthn/conditional-mediation.https.html
@@ -10,8 +10,7 @@ <script> "use strict"; -// Test that a configuration that must support conditional mediation reports -// supporting it. +// Test that conditional mediation is supported. virtualAuthenticatorPromiseTest(async t => { assert_own_property(window.PublicKeyCredential, "isConditionalMediationAvailable"); assert_true(await window.PublicKeyCredential.isConditionalMediationAvailable()); @@ -22,16 +21,4 @@ transport: "internal", }, "Conditional mediation supported"); -// Test that a configuration that cannot possibly support conditional mediation -// does not report supporting it. -virtualAuthenticatorPromiseTest(async t => { - assert_own_property(window.PublicKeyCredential, "isConditionalMediationAvailable"); - assert_false(await window.PublicKeyCredential.isConditionalMediationAvailable()); -}, { - protocol: "ctap2", - hasResidentKey: false, - hasUserVerification: false, - transport: "nfc", -}, "Conditional mediation not supported"); - </script>
diff --git a/third_party/blink/web_tests/fast/block/float/floats-with-margin-should-not-wrap.html b/third_party/blink/web_tests/fast/block/float/floats-with-margin-should-not-wrap.html index 187d735..8b9ae2b3 100644 --- a/third_party/blink/web_tests/fast/block/float/floats-with-margin-should-not-wrap.html +++ b/third_party/blink/web_tests/fast/block/float/floats-with-margin-should-not-wrap.html
@@ -23,7 +23,8 @@ testRunner.dumpAsText(); var rect = document.getElementById('container').getBoundingClientRect(); - var height = rect.bottom - rect.top; + // Reversing the zoom effect + var height = (rect.bottom - rect.top)*2/3; if (height == 20) str = 'PASS, the three blocks are all on the same line';
diff --git a/third_party/blink/web_tests/fast/events/mouse-drag-from-frame-expected.txt b/third_party/blink/web_tests/fast/events/mouse-drag-from-frame-expected.txt deleted file mode 100644 index c920b0a5..0000000 --- a/third_party/blink/web_tests/fast/events/mouse-drag-from-frame-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This tests that dragging from an element that returns false from its mousedown handler will not let the subsequent mousemove events be captured by the containing frame. -Drag started -Received mouse move -Received mouseup event -PASS!
diff --git a/third_party/blink/web_tests/fast/events/mouse-drag-from-frame-to-other-frame-expected.txt b/third_party/blink/web_tests/fast/events/mouse-drag-from-frame-to-other-frame-expected.txt deleted file mode 100644 index 031add6..0000000 --- a/third_party/blink/web_tests/fast/events/mouse-drag-from-frame-to-other-frame-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This tests that dragging from an element that returns false from its mousedown handler will not let the subsequent mousemove events be captured by the containing frame, and allows the mouse move to get to other subframes. - -Drag Started -received mousemove -received mouseup
diff --git a/third_party/blink/web_tests/fast/events/mouse-drag-from-frame-to-other-frame.html b/third_party/blink/web_tests/fast/events/mouse-drag-from-frame-to-other-frame.html deleted file mode 100644 index dbfe83c6..0000000 --- a/third_party/blink/web_tests/fast/events/mouse-drag-from-frame-to-other-frame.html +++ /dev/null
@@ -1,57 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script> -if (window.testRunner) { - testRunner.waitUntilDone(); - testRunner.dumpAsText(); -} - -function log(msg) { - var msgNode = document.createTextNode(msg); - var li = document.createElement("li"); - li.appendChild(msgNode); - document.getElementById("logElem").appendChild(li); -} -function dragStarted() { - log("Drag Started"); -} -window.onmouseup = function() { - log("Root frame received mouse up"); -} -window.onload = function() { - try { - if (!frames[0] || !frames[0].document || !frames[0].document.getElementById("dragSource")) { - log("Window.onload fired before subframe completed load."); - } - - if (!window.testRunner) { - log("This test needs to be run in DRT. To test manually drag from the text 'Drag Me!' out into the parent frame."); - return; - } - var dragSource = frames[0].document.getElementById("dragSource"); - var sourceFrame = document.getElementById("sourceFrame"); - var targetFrame = document.getElementById("targetFrame"); - var x = dragSource.offsetLeft + sourceFrame.offsetLeft + 10; - var y = dragSource.offsetTop + sourceFrame.offsetTop + dragSource.offsetHeight / 2; - var x1 = targetFrame.offsetLeft + 10; - var y1 = targetFrame.offsetTop + 10; - eventSender.mouseMoveTo(x,y); - eventSender.mouseDown(); - eventSender.mouseMoveTo(x1, y1); - eventSender.mouseUp(); - } finally { - if (window.testRunner) - testRunner.notifyDone(); - } -} -</script> -</head> -<body> - <div>This tests that dragging from an element that returns <emph>false</emph> from its mousedown handler will not let the subsequent mousemove events be captured by the containing frame, and allows the mouse move to get to other subframes.</div> - <iframe id="sourceFrame" style="width: 100px; height: 50px;" src="resources/mouse-drag-from-frame-subframe.html"></iframe> - <iframe id="targetFrame" style="width: 100px; height: 50px;" src="resources/mouse-drag-from-frame-target-subframe.html"></iframe> - <ul id="logElem"> - </ul> -</body> -</html>
diff --git a/third_party/blink/web_tests/fast/events/mouse-drag-from-frame.html b/third_party/blink/web_tests/fast/events/mouse-drag-from-frame.html deleted file mode 100644 index b59f3de..0000000 --- a/third_party/blink/web_tests/fast/events/mouse-drag-from-frame.html +++ /dev/null
@@ -1,78 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script> -if (window.testRunner) { - testRunner.waitUntilDone(); - testRunner.dumpAsText(); -} - -function log(msg) { - var msgNode = document.createTextNode(msg); - var li = document.createElement("li"); - li.appendChild(msgNode); - document.getElementById("log").appendChild(li); -} -var dragging = false; -var waitingForUp = false; -function dragStarted() { - if (dragging || waitingForUp) { - log("Unexpected drag start"); - return; - } - log("Drag started"); - dragging = true; -} - -window.onmousedown = function() { - log("Unexpected mousedown"); -} - -window.onmousemove = function() { - if (!dragging || waitingForUp) - return; - log("Received mouse move"); - waitingForUp = true; -} - -window.onmouseup = function() { - if (!waitingForUp) { - log("Unexpected mouseup"); - return; - } - log("Received mouseup event") - log("PASS!"); -} - -window.onload = function() { - try { - if (!frames[0] || !frames[0].document || !frames[0].document.getElementById("dragSource")) { - log("Window.onload fired before subframe completed load."); - } - - if (!window.testRunner) { - log("This test needs to be run in DRT. To test manually drag from the text 'Drag Me!' out into the parent frame."); - return; - } - var dragSource = frames[0].document.getElementById("dragSource"); - var sourceFrame = document.getElementById("sourceFrame"); - var x = dragSource.offsetLeft + sourceFrame.offsetLeft + 10; - var y = dragSource.offsetTop + sourceFrame.offsetTop + dragSource.offsetHeight / 2; - eventSender.mouseMoveTo(x,y); - eventSender.mouseDown(); - eventSender.mouseMoveTo(120, 120); - eventSender.mouseUp(); - } finally { - if (window.testRunner) - testRunner.notifyDone(); - } -} -</script> -</head> -<body> - <div>This tests that dragging from an element that returns <emph>false</emph> from its mousedown handler will not let the subsequent mousemove events be captured by the containing frame.</div> - <iframe id="sourceFrame" style="width: 100px; height: 50px;" src="resources/mouse-drag-from-frame-subframe.html"></iframe> - <ul id="log"> - </ul> -</body> -</html>
diff --git a/third_party/blink/web_tests/fast/events/resources/mouse-drag-from-frame-subframe.html b/third_party/blink/web_tests/fast/events/resources/mouse-drag-from-frame-subframe.html deleted file mode 100644 index f9f431b0..0000000 --- a/third_party/blink/web_tests/fast/events/resources/mouse-drag-from-frame-subframe.html +++ /dev/null
@@ -1 +0,0 @@ -<div id="dragSource" onmousedown="parent.dragStarted(); return false;" onmouseup="parent.log('Unexpected mouseup event')">Drag Me!</div>
diff --git a/third_party/blink/web_tests/fast/events/resources/mouse-drag-from-frame-target-subframe.html b/third_party/blink/web_tests/fast/events/resources/mouse-drag-from-frame-target-subframe.html deleted file mode 100644 index f2f4e529..0000000 --- a/third_party/blink/web_tests/fast/events/resources/mouse-drag-from-frame-target-subframe.html +++ /dev/null
@@ -1,3 +0,0 @@ -<body onmousemove="if (!this.moved){ this.moved = true; parent.log('received mousemove') }" onmouseup="parent.log('received mouseup')"> - -</body>
diff --git a/third_party/blink/web_tests/fast/forms/textarea/textarea-resize-below-min-size-zoomed.html b/third_party/blink/web_tests/fast/forms/textarea/textarea-resize-below-min-size-zoomed.html index f0998e5..bd24c13 100644 --- a/third_party/blink/web_tests/fast/forms/textarea/textarea-resize-below-min-size-zoomed.html +++ b/third_party/blink/web_tests/fast/forms/textarea/textarea-resize-below-min-size-zoomed.html
@@ -40,8 +40,8 @@ var startX = textArea.offsetLeft + 195; var startY = textArea.offsetTop + 195; drag(startX, startY, startX - 150, startY - 150, t.step_func_done(() => { - assert_equals(textArea.getBoundingClientRect().width, 100); - assert_equals(textArea.getBoundingClientRect().height, 100); + assert_equals(textArea.getBoundingClientRect().width, 200); + assert_equals(textArea.getBoundingClientRect().height, 200); })); }); </script>
diff --git a/third_party/blink/web_tests/fast/forms/textarea/textarea-resize-below-resizer-size.html b/third_party/blink/web_tests/fast/forms/textarea/textarea-resize-below-resizer-size.html index fbb8a40..3756ec57 100644 --- a/third_party/blink/web_tests/fast/forms/textarea/textarea-resize-below-resizer-size.html +++ b/third_party/blink/web_tests/fast/forms/textarea/textarea-resize-below-resizer-size.html
@@ -34,8 +34,8 @@ assert_own_property(chrome, 'gpuBenchmarking'); var textArea = document.getElementById('textInputID'); - var startX = (textArea.getBoundingClientRect().right - 1) * 3; - var startY = (textArea.getBoundingClientRect().bottom - 1) * 3; + var startX = (textArea.getBoundingClientRect().right - 1); + var startY = (textArea.getBoundingClientRect().bottom - 1); drag(startX, startY, 0, 0, t.step_func_done(() => { // The textarea should be shrunk so that there is no room for visible // content beyond the resizer itself.
diff --git a/third_party/blink/web_tests/fast/sub-pixel/layout-boxes-with-zoom-expected.html b/third_party/blink/web_tests/fast/sub-pixel/layout-boxes-with-zoom-expected.html index 000cf110..3be69f30 100644 --- a/third_party/blink/web_tests/fast/sub-pixel/layout-boxes-with-zoom-expected.html +++ b/third_party/blink/web_tests/fast/sub-pixel/layout-boxes-with-zoom-expected.html
@@ -18,7 +18,6 @@ PASS: With zoom of 100% bottom edge of last child lines up with bottom edge of container.<br> PASS: With zoom of 110% bottom edge of last child lines up with bottom edge of container.<br> PASS: With zoom of 125% bottom edge of last child lines up with bottom edge of container.<br> - PASS: With zoom of 133% bottom edge of last child lines up with bottom edge of container.<br> PASS: With zoom of 150% bottom edge of last child lines up with bottom edge of container.<br> PASS: With zoom of 166% bottom edge of last child lines up with bottom edge of container.<br> PASS: With zoom of 175% bottom edge of last child lines up with bottom edge of container.<br>
diff --git a/third_party/blink/web_tests/fast/sub-pixel/layout-boxes-with-zoom.html b/third_party/blink/web_tests/fast/sub-pixel/layout-boxes-with-zoom.html index c1ba8212..c689c44 100644 --- a/third_party/blink/web_tests/fast/sub-pixel/layout-boxes-with-zoom.html +++ b/third_party/blink/web_tests/fast/sub-pixel/layout-boxes-with-zoom.html
@@ -55,7 +55,6 @@ test(100); test(110); test(125); - test(133); test(150); test(166); test(175);
diff --git a/third_party/blink/web_tests/fast/sub-pixel/table-rows-have-stable-height.html b/third_party/blink/web_tests/fast/sub-pixel/table-rows-have-stable-height.html index f4bf19f..4235ba8 100644 --- a/third_party/blink/web_tests/fast/sub-pixel/table-rows-have-stable-height.html +++ b/third_party/blink/web_tests/fast/sub-pixel/table-rows-have-stable-height.html
@@ -67,7 +67,10 @@ for (var i = 0; i < mainTable.tBodies[0].rows.length; i++) { // Set the size to a subpixel value, the exact value isn't // important but each row should have a different height. - var height = r((20 + i) * 0.93 + i); + // However, smallest size (after zoom adjustment) has to + // be larger than 22, as this is the minimal size set by + // the font. + var height = r(26 + (20 + i) * 0.93 + i); rowElement.style.height = height + 'px'; rect = rowElement.getBoundingClientRect(); rowHeights.push(rect.bottom - rect.top); @@ -95,12 +98,13 @@ var failures = 0; for (var i = 0; i < rows.length; i++) { var rect = rows[i].getBoundingClientRect(); - if (r(rowHeights[i]) != r(rect.height)) { - testFailed('At ' + r(zoom * 100) + '% zoom getBoundingClientRect returned a height of ' + r(rect.height) + ', expected ' + r(rowHeights[i]) + '.'); + // Rounding errors cause inaccurate results, so need to equal sizes with an epsilon + if (Math.abs(r(rowHeights[i]) - r(rect.height / zoom)) > 0.11 ) { + testFailed('At ' + r(zoom * 100) + '% zoom getBoundingClientRect returned a height of ' + r(rect.height / zoom) + ', expected ' + r(rowHeights[i]) + '.'); failures++; } - if (r(rowHeights[i]) != r(rect.bottom - rect.top)) { - testFailed('At ' + r(zoom * 100) + '% zoom getBoundingClientRect returned a rect with bottom - top of ' + (rect.bottom - rect.top) + ', expected ' + rowHeights[i] + '.'); + if (Math.abs((rowHeights[i]) - r((rect.bottom - rect.top) / zoom)) > 0.11) { + testFailed('At ' + r(zoom * 100) + '% zoom getBoundingClientRect returned a rect with bottom - top of ' + r((rect.bottom - rect.top) / zoom) + ', expected ' + rowHeights[i] + '.'); failures++; } }
diff --git a/third_party/blink/web_tests/media/video-controls-zoomed.html b/third_party/blink/web_tests/media/video-controls-zoomed.html index 04b9cc1..a1f80bd 100644 --- a/third_party/blink/web_tests/media/video-controls-zoomed.html +++ b/third_party/blink/web_tests/media/video-controls-zoomed.html
@@ -24,7 +24,7 @@ // Find the play button and click the middle of its bounding box. var playCoords = elementCoordinates(enabledPlayButton(video)); - eventSender.mouseMoveTo(playCoords[0] * 1.5, playCoords[1] * 1.5); + eventSender.mouseMoveTo(playCoords[0], playCoords[1]); eventSender.mouseDown(); eventSender.mouseUp(); }, 50);
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/semantics/forms/the-selectlist-element/selectlist-popover-position-with-zoom.tentative-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/semantics/forms/the-selectlist-element/selectlist-popover-position-with-zoom.tentative-expected.txt new file mode 100644 index 0000000..cc5725f2 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/semantics/forms/the-selectlist-element/selectlist-popover-position-with-zoom.tentative-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +[FAIL] The popover should be top left positioned + assert_equals: expected 0 but got 568 +[FAIL] The popover should be top right positioned + assert_equals: expected 0 but got 257 +Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-keyboard-enter-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-keyboard-enter-expected.txt new file mode 100644 index 0000000..5b37deb --- /dev/null +++ b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-keyboard-enter-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +All subtests passed and are omitted for brevity. +See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/writing_web_tests.md#Text-Test-Baselines for details. +Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-mouse-left-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-mouse-left-expected.txt new file mode 100644 index 0000000..5b37deb --- /dev/null +++ b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-mouse-left-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +All subtests passed and are omitted for brevity. +See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/writing_web_tests.md#Text-Test-Baselines for details. +Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-mouse-right-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-mouse-right-expected.txt new file mode 100644 index 0000000..5b37deb --- /dev/null +++ b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-mouse-right-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +All subtests passed and are omitted for brevity. +See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/writing_web_tests.md#Text-Test-Baselines for details. +Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-pointerevent_mouse-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-pointerevent_mouse-expected.txt new file mode 100644 index 0000000..5b37deb --- /dev/null +++ b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/html/user-activation/activation-trigger-pointerevent_mouse-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +All subtests passed and are omitted for brevity. +See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/writing_web_tests.md#Text-Test-Baselines for details. +Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-zoom-coords-expected.txt b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-zoom-coords-expected.txt index 0d9dd21..c884a6f3 100644 --- a/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-zoom-coords-expected.txt +++ b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-zoom-coords-expected.txt
@@ -23,19 +23,19 @@ PASS div2.left is 0.00 -PASS div2.top is 25.00 -PASS div2.width is 100.00 -PASS div2.height is 50.00 -PASS div2.right is 100.00 -PASS div2.bottom is 75.00 +PASS div2.top is 50.00 +PASS div2.width is 200.00 +PASS div2.height is 100.00 +PASS div2.right is 200.00 +PASS div2.bottom is 150.00 PASS div3.left is 0.00 -PASS div3.top is 300.00 -PASS div3.width is 200.00 -PASS div3.height is 100.00 -PASS div3.right is 200.00 -PASS div3.bottom is 400.00 +PASS div3.top is 150.00 +PASS div3.width is 100.00 +PASS div3.height is 50.00 +PASS div3.right is 100.00 +PASS div3.bottom is 200.00 Checking SVG elements: @@ -67,56 +67,56 @@ PASS text1.bottom is 288.82 -PASS svg2.left is 75.00 -PASS svg2.top is 100.00 -PASS svg2.width is 150.00 -PASS svg2.height is 50.00 -PASS svg2.right is 225.00 -PASS svg2.bottom is 150.00 -PASS rect2.left is 75.00 -PASS rect2.top is 100.00 -PASS rect2.width is 100.00 -PASS rect2.height is 50.00 -PASS rect2.right is 175.00 -PASS rect2.bottom is 150.00 -PASS image2.left is 175.00 -PASS image2.top is 100.00 -PASS image2.width is 50.00 -PASS image2.height is 25.00 -PASS image2.right is 225.00 -PASS image2.bottom is 125.00 -PASS text2.left is 175.00 -PASS text2.top is 132.66 -FAIL text2.width should be 47.98. Was 47.87336730957031. -FAIL text2.height should be 6.02. Was 5.929279327392578. -FAIL text2.right should be 222.98. Was 222.8733673095703. -FAIL text2.bottom should be 138.7. Was 138.5980110168457. +PASS svg2.left is 150.00 +PASS svg2.top is 200.00 +PASS svg2.width is 300.00 +PASS svg2.height is 100.00 +PASS svg2.right is 450.00 +PASS svg2.bottom is 300.00 +PASS rect2.left is 150.00 +PASS rect2.top is 200.00 +PASS rect2.width is 200.00 +PASS rect2.height is 100.00 +PASS rect2.right is 350.00 +PASS rect2.bottom is 300.00 +PASS image2.left is 350.00 +PASS image2.top is 200.00 +PASS image2.width is 100.00 +PASS image2.height is 50.00 +PASS image2.right is 450.00 +PASS image2.bottom is 250.00 +PASS text2.left is 350.00 +PASS text2.top is 265.33 +PASS text2.width is 95.74 +PASS text2.height is 11.85 +PASS text2.right is 445.74 +PASS text2.bottom is 277.19 -PASS svg3.left is 900.00 -PASS svg3.top is 500.00 -PASS svg3.width is 300.00 -PASS svg3.height is 100.00 -PASS svg3.right is 1200.00 -PASS svg3.bottom is 600.00 -PASS rect3.left is 900.00 -PASS rect3.top is 500.00 -PASS rect3.width is 200.00 -PASS rect3.height is 100.00 -PASS rect3.right is 1100.00 -PASS rect3.bottom is 600.00 -PASS image3.left is 1100.00 -PASS image3.top is 500.00 -PASS image3.width is 100.00 -PASS image3.height is 50.00 -PASS image3.right is 1200.00 -PASS image3.bottom is 550.00 -PASS text3.left is 1100.00 -PASS text3.top is 565.33 -FAIL text3.width should be 95.97. Was 98.38197326660156. -PASS text3.height is 12.31 -FAIL text3.right should be 1195.97. Was 1198.3819732666016. -PASS text3.bottom is 577.64 +PASS svg3.left is 450.00 +PASS svg3.top is 250.00 +PASS svg3.width is 150.00 +PASS svg3.height is 50.00 +PASS svg3.right is 600.00 +PASS svg3.bottom is 300.00 +PASS rect3.left is 450.00 +PASS rect3.top is 250.00 +PASS rect3.width is 100.00 +PASS rect3.height is 50.00 +PASS rect3.right is 550.00 +PASS rect3.bottom is 300.00 +PASS image3.left is 550.00 +PASS image3.top is 250.00 +PASS image3.width is 50.00 +PASS image3.height is 25.00 +PASS image3.right is 600.00 +PASS image3.bottom is 275.00 +PASS text3.left is 550.00 +PASS text3.top is 282.66 +PASS text3.width is 49.19 +PASS text3.height is 6.15 +PASS text3.right is 599.19 +PASS text3.bottom is 288.82 PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/html/semantics/forms/the-selectlist-element/selectlist-popover-position-with-zoom.tentative-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/html/semantics/forms/the-selectlist-element/selectlist-popover-position-with-zoom.tentative-expected.txt new file mode 100644 index 0000000..d37ca173 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/external/wpt/html/semantics/forms/the-selectlist-element/selectlist-popover-position-with-zoom.tentative-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +[FAIL] The popover should be top left positioned + assert_equals: expected 0 but got 568 +[FAIL] The popover should be top right positioned + assert_equals: expected 0 but got 257 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-zoom-coords-expected.txt b/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-zoom-coords-expected.txt index 056c226..573da91 100644 --- a/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-zoom-coords-expected.txt +++ b/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-zoom-coords-expected.txt
@@ -23,19 +23,19 @@ PASS div2.left is 0.00 -PASS div2.top is 25.00 -PASS div2.width is 100.00 -PASS div2.height is 50.00 -PASS div2.right is 100.00 -PASS div2.bottom is 75.00 +PASS div2.top is 50.00 +PASS div2.width is 200.00 +PASS div2.height is 100.00 +PASS div2.right is 200.00 +PASS div2.bottom is 150.00 PASS div3.left is 0.00 -PASS div3.top is 300.00 -PASS div3.width is 200.00 -PASS div3.height is 100.00 -PASS div3.right is 200.00 -PASS div3.bottom is 400.00 +PASS div3.top is 150.00 +PASS div3.width is 100.00 +PASS div3.height is 50.00 +PASS div3.right is 100.00 +PASS div3.bottom is 200.00 Checking SVG elements: @@ -67,56 +67,56 @@ PASS text1.bottom is 288.82 -PASS svg2.left is 75.00 -PASS svg2.top is 100.00 -PASS svg2.width is 150.00 -PASS svg2.height is 50.00 -PASS svg2.right is 225.00 -PASS svg2.bottom is 150.00 -PASS rect2.left is 75.00 -PASS rect2.top is 100.00 -PASS rect2.width is 100.00 -PASS rect2.height is 50.00 -PASS rect2.right is 175.00 -PASS rect2.bottom is 150.00 -PASS image2.left is 175.00 -PASS image2.top is 100.00 -PASS image2.width is 50.00 -PASS image2.height is 25.00 -PASS image2.right is 225.00 -PASS image2.bottom is 125.00 -PASS text2.left is 175.00 -PASS text2.top is 132.66 -PASS text2.width is 47.98 -PASS text2.height is 6.02 -PASS text2.right is 222.98 -PASS text2.bottom is 138.70 +PASS svg2.left is 150.00 +PASS svg2.top is 200.00 +PASS svg2.width is 300.00 +PASS svg2.height is 100.00 +PASS svg2.right is 450.00 +PASS svg2.bottom is 300.00 +PASS rect2.left is 150.00 +PASS rect2.top is 200.00 +PASS rect2.width is 200.00 +PASS rect2.height is 100.00 +PASS rect2.right is 350.00 +PASS rect2.bottom is 300.00 +PASS image2.left is 350.00 +PASS image2.top is 200.00 +PASS image2.width is 100.00 +PASS image2.height is 50.00 +PASS image2.right is 450.00 +PASS image2.bottom is 250.00 +PASS text2.left is 350.00 +PASS text2.top is 265.33 +FAIL text2.width should be 95.74. Was 95.99380493164062. +FAIL text2.height should be 11.85. Was 12.062347412109375. +FAIL text2.right should be 445.74. Was 445.9938049316406. +FAIL text2.bottom should be 277.19. Was 277.3998107910156. -PASS svg3.left is 900.00 -PASS svg3.top is 500.00 -PASS svg3.width is 300.00 -PASS svg3.height is 100.00 -PASS svg3.right is 1200.00 -PASS svg3.bottom is 600.00 -PASS rect3.left is 900.00 -PASS rect3.top is 500.00 -PASS rect3.width is 200.00 -PASS rect3.height is 100.00 -PASS rect3.right is 1100.00 -PASS rect3.bottom is 600.00 -PASS image3.left is 1100.00 -PASS image3.top is 500.00 -PASS image3.width is 100.00 -PASS image3.height is 50.00 -PASS image3.right is 1200.00 -PASS image3.bottom is 550.00 -PASS text3.left is 1100.00 -PASS text3.top is 565.33 -FAIL text3.width should be 95.97. Was 95.99380493164062. -PASS text3.height is 12.31 -FAIL text3.right should be 1195.97. Was 1195.9938049316406. -PASS text3.bottom is 577.64 +PASS svg3.left is 450.00 +PASS svg3.top is 250.00 +PASS svg3.width is 150.00 +PASS svg3.height is 50.00 +PASS svg3.right is 600.00 +PASS svg3.bottom is 300.00 +PASS rect3.left is 450.00 +PASS rect3.top is 250.00 +PASS rect3.width is 100.00 +PASS rect3.height is 50.00 +PASS rect3.right is 550.00 +PASS rect3.bottom is 300.00 +PASS image3.left is 550.00 +PASS image3.top is 250.00 +PASS image3.width is 50.00 +PASS image3.height is 25.00 +PASS image3.right is 600.00 +PASS image3.bottom is 275.00 +PASS text3.left is 550.00 +PASS text3.top is 282.66 +FAIL text3.width should be 49.19. Was 47.99690246582031. +PASS text3.height is 6.15 +FAIL text3.right should be 599.19. Was 597.9969024658203. +PASS text3.bottom is 288.82 PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/html/semantics/forms/the-selectlist-element/selectlist-popover-position-with-zoom.tentative-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/html/semantics/forms/the-selectlist-element/selectlist-popover-position-with-zoom.tentative-expected.txt new file mode 100644 index 0000000..01eb7b1 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/external/wpt/html/semantics/forms/the-selectlist-element/selectlist-popover-position-with-zoom.tentative-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +[FAIL] The popover should be top left positioned + assert_equals: expected 0 but got 567 +[FAIL] The popover should be top right positioned + assert_equals: expected 0 but got 257 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-zoom-coords-expected.txt b/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-zoom-coords-expected.txt index 4413b0f..cf9b529 100644 --- a/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-zoom-coords-expected.txt +++ b/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-zoom-coords-expected.txt
@@ -23,19 +23,19 @@ PASS div2.left is 0.00 -PASS div2.top is 25.00 -PASS div2.width is 100.00 -PASS div2.height is 50.00 -PASS div2.right is 100.00 -PASS div2.bottom is 75.00 +PASS div2.top is 50.00 +PASS div2.width is 200.00 +PASS div2.height is 100.00 +PASS div2.right is 200.00 +PASS div2.bottom is 150.00 PASS div3.left is 0.00 -PASS div3.top is 300.00 -PASS div3.width is 200.00 -PASS div3.height is 100.00 -PASS div3.right is 200.00 -PASS div3.bottom is 400.00 +PASS div3.top is 150.00 +PASS div3.width is 100.00 +PASS div3.height is 50.00 +PASS div3.right is 100.00 +PASS div3.bottom is 200.00 Checking SVG elements: @@ -67,56 +67,56 @@ PASS text1.bottom is 288.82 -PASS svg2.left is 75.00 -PASS svg2.top is 100.00 -PASS svg2.width is 150.00 -PASS svg2.height is 50.00 -PASS svg2.right is 225.00 -PASS svg2.bottom is 150.00 -PASS rect2.left is 75.00 -PASS rect2.top is 100.00 -PASS rect2.width is 100.00 -PASS rect2.height is 50.00 -PASS rect2.right is 175.00 -PASS rect2.bottom is 150.00 -PASS image2.left is 175.00 -PASS image2.top is 100.00 -PASS image2.width is 50.00 -PASS image2.height is 25.00 -PASS image2.right is 225.00 -PASS image2.bottom is 125.00 -PASS text2.left is 175.00 -PASS text2.top is 132.66 -FAIL text2.width should be 47.98. Was 47.43418884277344. -FAIL text2.height should be 6.02. Was 5.929279327392578. -FAIL text2.right should be 222.98. Was 222.43418884277344. -FAIL text2.bottom should be 138.7. Was 138.5980110168457. +PASS svg2.left is 150.00 +PASS svg2.top is 200.00 +PASS svg2.width is 300.00 +PASS svg2.height is 100.00 +PASS svg2.right is 450.00 +PASS svg2.bottom is 300.00 +PASS rect2.left is 150.00 +PASS rect2.top is 200.00 +PASS rect2.width is 200.00 +PASS rect2.height is 100.00 +PASS rect2.right is 350.00 +PASS rect2.bottom is 300.00 +PASS image2.left is 350.00 +PASS image2.top is 200.00 +PASS image2.width is 100.00 +PASS image2.height is 50.00 +PASS image2.right is 450.00 +PASS image2.bottom is 250.00 +PASS text2.left is 350.00 +PASS text2.top is 265.33 +FAIL text2.width should be 95.74. Was 94.86837768554688. +PASS text2.height is 11.85 +FAIL text2.right should be 445.74. Was 444.8683776855469. +PASS text2.bottom is 277.19 -PASS svg3.left is 900.00 -PASS svg3.top is 500.00 -PASS svg3.width is 300.00 -PASS svg3.height is 100.00 -PASS svg3.right is 1200.00 -PASS svg3.bottom is 600.00 -PASS rect3.left is 900.00 -PASS rect3.top is 500.00 -PASS rect3.width is 200.00 -PASS rect3.height is 100.00 -PASS rect3.right is 1100.00 -PASS rect3.bottom is 600.00 -PASS image3.left is 1100.00 -PASS image3.top is 500.00 -PASS image3.width is 100.00 -PASS image3.height is 50.00 -PASS image3.right is 1200.00 -PASS image3.bottom is 550.00 -PASS text3.left is 1100.00 -PASS text3.top is 565.33 -FAIL text3.width should be 95.97. Was 98.38197326660156. -PASS text3.height is 12.31 -FAIL text3.right should be 1195.97. Was 1198.3819732666016. -PASS text3.bottom is 577.64 +PASS svg3.left is 450.00 +PASS svg3.top is 250.00 +PASS svg3.width is 150.00 +PASS svg3.height is 50.00 +PASS svg3.right is 600.00 +PASS svg3.bottom is 300.00 +PASS rect3.left is 450.00 +PASS rect3.top is 250.00 +PASS rect3.width is 100.00 +PASS rect3.height is 50.00 +PASS rect3.right is 550.00 +PASS rect3.bottom is 300.00 +PASS image3.left is 550.00 +PASS image3.top is 250.00 +PASS image3.width is 50.00 +PASS image3.height is 25.00 +PASS image3.right is 600.00 +PASS image3.bottom is 275.00 +PASS text3.left is 550.00 +PASS text3.top is 282.66 +PASS text3.width is 49.19 +PASS text3.height is 6.15 +PASS text3.right is 599.19 +PASS text3.bottom is 288.82 PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/svg/as-list-image/svg-list-image-intrinsic-size-zoom.html b/third_party/blink/web_tests/svg/as-list-image/svg-list-image-intrinsic-size-zoom.html index 67c687a..448ac61 100644 --- a/third_party/blink/web_tests/svg/as-list-image/svg-list-image-intrinsic-size-zoom.html +++ b/third_party/blink/web_tests/svg/as-list-image/svg-list-image-intrinsic-size-zoom.html
@@ -23,7 +23,7 @@ [ 2, 3, 4, 5, 0.5, 0.2, 1].forEach(function(zoom) { test(function() { document.body.style.zoom = zoom; - assert_approx_equals(ul.getBoundingClientRect().height, 500, 0.5); + assert_approx_equals(ul.getBoundingClientRect().height / zoom, 500, 0.5); }, 'Zoom to ' + zoom + " and list height should be equal to line-height"); }); </script>
diff --git a/third_party/blink/web_tests/svg/zoom/page/zoom-zoom-coords.xhtml b/third_party/blink/web_tests/svg/zoom/page/zoom-zoom-coords.xhtml index 305cd2f..4476f5e 100644 --- a/third_party/blink/web_tests/svg/zoom/page/zoom-zoom-coords.xhtml +++ b/third_party/blink/web_tests/svg/zoom/page/zoom-zoom-coords.xhtml
@@ -77,20 +77,20 @@ div2 = document.getElementById("div2").getBoundingClientRect(); shouldBe('div2.left', '0.00', false, tolerance); - shouldBe('div2.top', '25.00', false, tolerance); - shouldBe('div2.width', '100.00', false, tolerance); - shouldBe('div2.height', '50.00', false, tolerance); - shouldBe('div2.right', '100.00', false, tolerance); - shouldBe('div2.bottom', '75.00', false, tolerance); + shouldBe('div2.top', '50.00', false, tolerance); + shouldBe('div2.width', '200.00', false, tolerance); + shouldBe('div2.height', '100.00', false, tolerance); + shouldBe('div2.right', '200.00', false, tolerance); + shouldBe('div2.bottom', '150.00', false, tolerance); debug(""); div3 = document.getElementById("div3").getBoundingClientRect(); shouldBe('div3.left', '0.00', false, tolerance); - shouldBe('div3.top', '300.00', false, tolerance); - shouldBe('div3.width', '200.00', false, tolerance); - shouldBe('div3.height', '100.00', false, tolerance); - shouldBe('div3.right', '200.00', false, tolerance); - shouldBe('div3.bottom', '400.00', false, tolerance); + shouldBe('div3.top', '150.00', false, tolerance); + shouldBe('div3.width', '100.00', false, tolerance); + shouldBe('div3.height', '50.00', false, tolerance); + shouldBe('div3.right', '100.00', false, tolerance); + shouldBe('div3.bottom', '200.00', false, tolerance); debug(""); debug("Checking SVG elements:"); @@ -127,63 +127,63 @@ debug(""); svg2 = document.getElementById("svg2").getBoundingClientRect(); - shouldBe('svg2.left', '75.00', false, tolerance); - shouldBe('svg2.top', '100.00', false, tolerance); - shouldBe('svg2.width', '150.00', false, tolerance); - shouldBe('svg2.height', '50.00', false, tolerance); - shouldBe('svg2.right', '225.00', false, tolerance); - shouldBe('svg2.bottom', '150.00', false, tolerance); + shouldBe('svg2.left', '150.00', false, tolerance); + shouldBe('svg2.top', '200.00', false, tolerance); + shouldBe('svg2.width', '300.00', false, tolerance); + shouldBe('svg2.height', '100.00', false, tolerance); + shouldBe('svg2.right', '450.00', false, tolerance); + shouldBe('svg2.bottom', '300.00', false, tolerance); rect2 = document.getElementById("rect2").getBoundingClientRect(); - shouldBe('rect2.left', '75.00', false, tolerance); - shouldBe('rect2.top', '100.00', false, tolerance); - shouldBe('rect2.width', '100.00', false, tolerance); - shouldBe('rect2.height', '50.00', false, tolerance); - shouldBe('rect2.right', '175.00', false, tolerance); - shouldBe('rect2.bottom', '150.00', false, tolerance); + shouldBe('rect2.left', '150.00', false, tolerance); + shouldBe('rect2.top', '200.00', false, tolerance); + shouldBe('rect2.width', '200.00', false, tolerance); + shouldBe('rect2.height', '100.00', false, tolerance); + shouldBe('rect2.right', '350.00', false, tolerance); + shouldBe('rect2.bottom', '300.00', false, tolerance); image2 = document.getElementById("image2").getBoundingClientRect(); - shouldBe('image2.left', '175.00', false, tolerance); - shouldBe('image2.top', '100.00', false, tolerance); - shouldBe('image2.width', '50.00', false, tolerance); - shouldBe('image2.height', '25.00', false, tolerance); - shouldBe('image2.right', '225.00', false, tolerance); - shouldBe('image2.bottom', '125.00', false, tolerance); + shouldBe('image2.left', '350.00', false, tolerance); + shouldBe('image2.top', '200.00', false, tolerance); + shouldBe('image2.width', '100.00', false, tolerance); + shouldBe('image2.height', '50.00', false, tolerance); + shouldBe('image2.right', '450.00', false, tolerance); + shouldBe('image2.bottom', '250.00', false, tolerance); text2 = document.getElementById("text2").getBoundingClientRect(); - shouldBe('text2.left', '175.00', false, tolerance); - shouldBe('text2.top', '132.66', false, tolerance); - shouldBe('text2.width', '47.98', false, tolerance); - shouldBe('text2.height', '6.02', false, tolerance); - shouldBe('text2.right', '222.98', false, tolerance); - shouldBe('text2.bottom', '138.70', false, tolerance); + shouldBe('text2.left', '350.00', false, tolerance); + shouldBe('text2.top', '265.33', false, tolerance); + shouldBe('text2.width', '95.74', false, tolerance); + shouldBe('text2.height', '11.85', false, tolerance); + shouldBe('text2.right', '445.74', false, tolerance); + shouldBe('text2.bottom', '277.19', false, tolerance); debug(""); svg3 = document.getElementById("svg3").getBoundingClientRect(); - shouldBe('svg3.left', '900.00', false, tolerance); - shouldBe('svg3.top', '500.00', false, tolerance); - shouldBe('svg3.width', '300.00', false, tolerance); - shouldBe('svg3.height', '100.00', false, tolerance); - shouldBe('svg3.right', '1200.00', false, tolerance); - shouldBe('svg3.bottom', '600.00', false, tolerance); + shouldBe('svg3.left', '450.00', false, tolerance); + shouldBe('svg3.top', '250.00', false, tolerance); + shouldBe('svg3.width', '150.00', false, tolerance); + shouldBe('svg3.height', '50.00', false, tolerance); + shouldBe('svg3.right', '600.00', false, tolerance); + shouldBe('svg3.bottom', '300.00', false, tolerance); rect3 = document.getElementById("rect3").getBoundingClientRect(); - shouldBe('rect3.left', '900.00', false, tolerance); - shouldBe('rect3.top', '500.00', false, tolerance); - shouldBe('rect3.width', '200.00', false, tolerance); - shouldBe('rect3.height', '100.00', false, tolerance); - shouldBe('rect3.right', '1100.00', false, tolerance); - shouldBe('rect3.bottom', '600.00', false, tolerance); + shouldBe('rect3.left', '450.00', false, tolerance); + shouldBe('rect3.top', '250.00', false, tolerance); + shouldBe('rect3.width', '100.00', false, tolerance); + shouldBe('rect3.height', '50.00', false, tolerance); + shouldBe('rect3.right', '550.00', false, tolerance); + shouldBe('rect3.bottom', '300.00', false, tolerance); image3 = document.getElementById("image3").getBoundingClientRect(); - shouldBe('image3.left', '1100.00', false, tolerance); - shouldBe('image3.top', '500.00', false, tolerance); - shouldBe('image3.width', '100.00', false, tolerance); - shouldBe('image3.height', '50.00', false, tolerance); - shouldBe('image3.right', '1200.00', false, tolerance); - shouldBe('image3.bottom', '550.00', false, tolerance); + shouldBe('image3.left', '550.00', false, tolerance); + shouldBe('image3.top', '250.00', false, tolerance); + shouldBe('image3.width', '50.00', false, tolerance); + shouldBe('image3.height', '25.00', false, tolerance); + shouldBe('image3.right', '600.00', false, tolerance); + shouldBe('image3.bottom', '275.00', false, tolerance); text3 = document.getElementById("text3").getBoundingClientRect(); - shouldBe('text3.left', '1100.00', false, tolerance); - shouldBe('text3.top', '565.33', false, tolerance); - shouldBe('text3.width', '95.97', false, tolerance); - shouldBe('text3.height', '12.31', false, tolerance); - shouldBe('text3.right', '1195.97', false, tolerance); - shouldBe('text3.bottom', '577.64', false, tolerance); + shouldBe('text3.left', '550.00', false, tolerance); + shouldBe('text3.top', '282.66', false, tolerance); + shouldBe('text3.width', '49.19', false, tolerance); + shouldBe('text3.height', '6.15', false, tolerance); + shouldBe('text3.right', '599.19', false, tolerance); + shouldBe('text3.bottom', '288.82', false, tolerance); debug(""); } </script>
diff --git a/third_party/blink/web_tests/transforms/bounding-rect-zoom.html b/third_party/blink/web_tests/transforms/bounding-rect-zoom.html index 56e6696..432f987 100644 --- a/third_party/blink/web_tests/transforms/bounding-rect-zoom.html +++ b/third_party/blink/web_tests/transforms/bounding-rect-zoom.html
@@ -16,16 +16,16 @@ outputElt.innerHTML = '<span style="color:green;"><b>PASS</b></span>'; } -function testGetClientBoundingRect() +function testGetClientBoundingRect(zoom) { var baseline = document.getElementById("baseline1"); var moveme = document.getElementById("moveme1"); var bounds = baseline.getBoundingClientRect(); - moveme.style.left = bounds.left; - moveme.style.top = bounds.top; - moveme.style.width = bounds.right - bounds.left; - moveme.style.height = bounds.bottom - bounds.top; + moveme.style.left = bounds.left / zoom; + moveme.style.top = bounds.top / zoom; + moveme.style.width = (bounds.right - bounds.left) / zoom; + moveme.style.height = (bounds.bottom - bounds.top) / zoom; var newBounds = moveme.getBoundingClientRect(); rectsShouldBeEqual(bounds, newBounds, document.getElementById("results1")); @@ -49,7 +49,7 @@ function runTest() { document.body.style.zoom = "0.9"; - testGetClientBoundingRect(); + testGetClientBoundingRect(0.9); testGetClientRects(); } </script>
diff --git a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png index 0b51866..f97e03c3 100644 --- a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/fast/forms/color-scheme/scrollbar/dynamic-color-scheme-change-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/fast/forms/color-scheme/scrollbar/horizontal-scrollbar-basic-expected.png b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/fast/forms/color-scheme/scrollbar/horizontal-scrollbar-basic-expected.png index 25187918..19cd2f45 100644 --- a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/fast/forms/color-scheme/scrollbar/horizontal-scrollbar-basic-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/fast/forms/color-scheme/scrollbar/horizontal-scrollbar-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png index 70b1e1b0..3b227a8 100644 --- a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dark-mode/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dsf-150/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dsf-150/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png index d5e06e3..2f492c0 100644 --- a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dsf-150/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dsf-150/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dsf-200/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dsf-200/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png index aee20560..22cd2e8 100644 --- a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dsf-200/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-dsf-200/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png index 43a764f..a04c81e 100644 --- a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/composited/basic-scrollbar-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png index 48ef571..d5f6cdb 100644 --- a/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-non-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar-dark-mode/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png b/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar-dark-mode/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png index 5d7820c7..5d265b9c 100644 --- a/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar-dark-mode/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar-dark-mode/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png b/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png index 4a68b3b0..5ae7797 100644 --- a/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar-hc/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png b/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png index c140fa3..3159c6cc 100644 --- a/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/visual/hover-over-main-thread-expected.png b/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/visual/hover-over-main-thread-expected.png index 8f30a60..03e5b45 100644 --- a/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/visual/hover-over-main-thread-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/visual/hover-over-main-thread-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/visual/scrollbar-show-tickmarks-expected.png b/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/visual/scrollbar-show-tickmarks-expected.png index 4cbf43e6..5619c21 100644 --- a/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/visual/scrollbar-show-tickmarks-expected.png +++ b/third_party/blink/web_tests/virtual/fluent-overlay-scrollbar/visual/scrollbar-show-tickmarks-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/gpu/arg_min_max.https.any.worker-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/gpu/arg_min_max.https.any.worker-expected.txt new file mode 100644 index 0000000..e6509e87b --- /dev/null +++ b/third_party/blink/web_tests/virtual/webnn-service-enabled/external/wpt/webnn/gpu/arg_min_max.https.any.worker-expected.txt
@@ -0,0 +1,84 @@ +This is a testharness.js-based test. +Found 40 FAIL, 0 TIMEOUT, 0 NOTRUN. +[FAIL] argMin float32 1D tensor default options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 2D tensor default options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 3D tensor default options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor default options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 5D tensor default options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.axes=[2] / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.axes=[] / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.keepDimensions=true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.keepDimensions=false / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.selectLastIndex=true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.selectLastIndex=false / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.axes=[0, 2] options.keepDimensions=false / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.axes=[3, 0, 1] options.keepDimensions=true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.axes=[0, 2] options.selectLastIndex=false / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.axes=[0, 2] options.selectLastIndex=true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.axes=[3, 0, 1] options.selectLastIndex=false / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor options.axes=[3, 0, 1] options.selectLastIndex=true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 4D tensor all options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 0D scalar options.axes=[] / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMin float32 0D scalar options.axes=[] no effect by both keepDimensions and selectLastIndex being true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 1D tensor default options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 2D tensor default options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 3D tensor default options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor default options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 5D tensor default options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.axes=[2] / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.axes=[] / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.keepDimensions=true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.keepDimensions=false / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.selectLastIndex=true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.selectLastIndex=false / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.axes=[0, 2] options.keepDimensions=false / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.axes=[3, 0, 1] options.keepDimensions=true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.axes=[0, 2] options.selectLastIndex=false / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.axes=[0, 2] options.selectLastIndex=true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.axes=[3, 0, 1] options.selectLastIndex=false / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor options.axes=[3, 0, 1] options.selectLastIndex=true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 4D tensor all options / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 0D scalar options.axes=[] / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +[FAIL] argMax float32 0D scalar options.axes=[] no effect by both keepDimensions and selectLastIndex being true / async + promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal index 9405c73..2a585a1 160000 --- a/third_party/devtools-frontend-internal +++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@ -Subproject commit 9405c73532966c47623ae2c6389b7b065aa6414f +Subproject commit 2a585a1bc1c2ae0d74870e33dd0f66b9aecce629
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 393a4b1..884d920 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 393a4b1223f616d755c9fe7e125ac92b47196acc +Subproject commit 884d920106c5a692e7f55b415cbc2f351650456f
diff --git a/third_party/libaom/README.chromium b/third_party/libaom/README.chromium index 8ae037f..a409524 100644 --- a/third_party/libaom/README.chromium +++ b/third_party/libaom/README.chromium
@@ -2,7 +2,7 @@ Short Name: libaom URL: https://aomedia.googlesource.com/aom/ Version: N/A -Revision: ce0ee71ca6aa97e2f564a05a8045699d29c18834 +Revision: ebe946034afb793a69d71fc864b561e691e403de CPEPrefix: cpe:/a:aomedia:aomedia:3.6.1 License: BSD License File: source/libaom/LICENSE
diff --git a/third_party/libaom/libaom_srcs.gni b/third_party/libaom/libaom_srcs.gni index 03138e5..c6e6d42d 100644 --- a/third_party/libaom/libaom_srcs.gni +++ b/third_party/libaom/libaom_srcs.gni
@@ -262,6 +262,10 @@ "//third_party/libaom/source/libaom/av1/encoder/x86/reconinter_enc_ssse3.c", ] +aom_av1_encoder_intrin_sve = [ + "//third_party/libaom/source/libaom/av1/encoder/arm/neon/av1_error_sve.c", +] + aom_av1_encoder_sources = [ "//third_party/libaom/source/libaom/av1/av1_cx_iface.c", "//third_party/libaom/source/libaom/av1/av1_cx_iface.h",
diff --git a/third_party/libaom/source/config/config/aom_version.h b/third_party/libaom/source/config/config/aom_version.h index ef34a32..638e0cd6 100644 --- a/third_party/libaom/source/config/config/aom_version.h +++ b/third_party/libaom/source/config/config/aom_version.h
@@ -12,8 +12,8 @@ #define VERSION_MAJOR 3 #define VERSION_MINOR 8 #define VERSION_PATCH 0 -#define VERSION_EXTRA "140-gce0ee71ca6" +#define VERSION_EXTRA "152-gebe946034a" #define VERSION_PACKED \ ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH)) -#define VERSION_STRING_NOSP "3.8.0-140-gce0ee71ca6" -#define VERSION_STRING " 3.8.0-140-gce0ee71ca6" +#define VERSION_STRING_NOSP "3.8.0-152-gebe946034a" +#define VERSION_STRING " 3.8.0-152-gebe946034a"
diff --git a/third_party/libaom/source/libaom b/third_party/libaom/source/libaom index ce0ee71..ebe9460 160000 --- a/third_party/libaom/source/libaom +++ b/third_party/libaom/source/libaom
@@ -1 +1 @@ -Subproject commit ce0ee71ca6aa97e2f564a05a8045699d29c18834 +Subproject commit ebe946034afb793a69d71fc864b561e691e403de
diff --git a/third_party/nearby/README.chromium b/third_party/nearby/README.chromium index 8ca9fde..da26d20 100644 --- a/third_party/nearby/README.chromium +++ b/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@ Name: Nearby Connections Library Short Name: Nearby URL: https://github.com/google/nearby -Version: 63e744e1338412c5ad17094f22445c6dfe71de6e +Version: 850c3e2788015668572249d205d91d6af78c5739 License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/third_party/nearby/src b/third_party/nearby/src index 63e744e..850c3e2 160000 --- a/third_party/nearby/src +++ b/third_party/nearby/src
@@ -1 +1 @@ -Subproject commit 63e744e1338412c5ad17094f22445c6dfe71de6e +Subproject commit 850c3e2788015668572249d205d91d6af78c5739
diff --git a/third_party/perfetto b/third_party/perfetto index 1072e37..fa384c4 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit 1072e37cbb64611f0b911427c6c2e497d4925881 +Subproject commit fa384c4660e10ae4390efd2dbeaa67b0fad58044
diff --git a/third_party/webrtc b/third_party/webrtc index 70ad987..8f4df7b 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit 70ad987c64d6c8467d33ad2acf658ce3a6691d0b +Subproject commit 8f4df7bec911f867059fdc3102242a4c45b0f70b
diff --git a/tools/accessibility/rebase_dump_accessibility_tree_test.py b/tools/accessibility/rebase_dump_accessibility_tree_test.py index 436491c..422054f7 100755 --- a/tools/accessibility/rebase_dump_accessibility_tree_test.py +++ b/tools/accessibility/rebase_dump_accessibility_tree_test.py
@@ -144,16 +144,16 @@ name.startswith('content_browsertests')) and '(with patch)' in name: s_name = name - bb_command = [ - 'bb', - 'log', - builder['id'], - '\"%s\"' % s_name, - ] - bb_command_expanded = ' '.join(bb_command) - # print((BRIGHT_COLOR + '=> %s' + NORMAL_COLOR) % bb_command_expanded) - output = os.popen(bb_command_expanded).readlines() - ParseLog('\n'.join(output)) + bb_command = [ + 'bb', + 'log', + builder['id'], + '\"%s\"' % s_name, + ] + bb_command_expanded = ' '.join(bb_command) + # print((BRIGHT_COLOR + '=> %s' + NORMAL_COLOR) % bb_command_expanded) + output = os.popen(bb_command_expanded).readlines() + ParseLog('\n'.join(output)) if not output: print('No content_browsertests (with patch) step found') continue
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 1d5d0ff..b4f27018 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -6294,6 +6294,11 @@ label="Predicted direction was not the same as real trajectory"/> </enum> +<enum name="BooleanEligible"> + <int value="0" label="Not elibible"/> + <int value="1" label="Eligible"/> +</enum> + <enum name="BooleanEmpty"> <int value="0" label="Not Empty"/> <int value="1" label="Empty"/> @@ -25868,6 +25873,7 @@ <int value="41" label="Lens Camera Search"/> <int value="42" label="Save Image in Google Photos"/> <int value="43" label="Close Other Tabs"/> + <int value="44" label="Add Tab to New Group"/> </enum> <enum name="IOSMenuScenario">
diff --git a/tools/metrics/histograms/histograms_index.txt b/tools/metrics/histograms/histograms_index.txt index 2ace3d8..c81ea7b 100644 --- a/tools/metrics/histograms/histograms_index.txt +++ b/tools/metrics/histograms/histograms_index.txt
@@ -164,6 +164,7 @@ tools/metrics/histograms/metadata/quickstart/enums.xml tools/metrics/histograms/metadata/quickstart/histograms.xml tools/metrics/histograms/metadata/quota/histograms.xml +tools/metrics/histograms/metadata/readaloud/enums.xml tools/metrics/histograms/metadata/readaloud/histograms.xml tools/metrics/histograms/metadata/renderer/histograms.xml tools/metrics/histograms/metadata/renderer4/histograms.xml
diff --git a/tools/metrics/histograms/metadata/enterprise/enums.xml b/tools/metrics/histograms/metadata/enterprise/enums.xml index e3d13fa9..18e4bdcf 100644 --- a/tools/metrics/histograms/metadata/enterprise/enums.xml +++ b/tools/metrics/histograms/metadata/enterprise/enums.xml
@@ -2000,6 +2000,7 @@ <int value="1189" label="ListenToThisPageEnabled"/> <int value="1190" label="AlwaysOnVpnPreConnectUrlAllowlist"/> <int value="1191" label="CACertificates"/> + <int value="1192" label="CADistrustedCertificates"/> </enum> <enum name="EnterprisePoliciesSources">
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml index 24a34405..fb88969 100644 --- a/tools/metrics/histograms/metadata/gpu/histograms.xml +++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -411,7 +411,7 @@ </summary> </histogram> -<histogram name="GPU.BlocklistFeatureTestResults" +<histogram name="GPU.BlocklistFeatureTestResults.{GPUBlocklistPerFeature}" enum="GPUBlocklistFeatureTestResults" expires_after="2024-04-28"> <owner>vmiura@chromium.org</owner> <owner>graphics-dev@chromium.org</owner> @@ -419,6 +419,14 @@ Counts number of browser invocations for which a GPU feature is allowed/blocklisted/disabled. </summary> + <token key="GPUBlocklistPerFeature"> + <variant name="Accelerated2dCanvas" summary="Accelerated2dCanvas"/> + <variant name="GpuCompositing" summary="GpuCompositing"/> + <variant name="GpuRasterization" summary="GpuRasterization"/> + <variant name="Webgl" summary="Webgl"/> + <variant name="Webgl2" summary="Webgl2"/> + <variant name="Webgpu" summary="Webgpu"/> + </token> </histogram> <histogram name="GPU.BlocklistTestResultsPerEntry"
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml index 2f7947d..f4b33402 100644 --- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -1413,16 +1413,6 @@ name="GPU.DirectComposition.SwapChainCreationResult3.SoftwareProtected"/> </histogram_suffixes> -<histogram_suffixes name="GPUBlocklistPerFeature" separator="."> - <suffix name="Accelerated2dCanvas" label="Accelerated2dCanvas"/> - <suffix name="GpuCompositing" label="GpuCompositing"/> - <suffix name="GpuRasterization" label="GpuRasterization"/> - <suffix name="Webgl" label="Webgl"/> - <suffix name="Webgl2" label="Webgl2"/> - <suffix name="Webgpu" label="Webgpu"/> - <affected-histogram name="GPU.BlocklistFeatureTestResults"/> -</histogram_suffixes> - <histogram_suffixes name="GridTabSwitcherAnimationType" separator="."> <suffix name="Expand" label="Grid to Tab"/> <suffix name="Shrink" label="Tab to Grid"/>
diff --git a/tools/metrics/histograms/metadata/ios/enums.xml b/tools/metrics/histograms/metadata/ios/enums.xml index b18939b..47dc9233 100644 --- a/tools/metrics/histograms/metadata/ios/enums.xml +++ b/tools/metrics/histograms/metadata/ios/enums.xml
@@ -26,11 +26,6 @@ <enums> -<enum name="BooleanEligible"> - <int value="0" label="Not elibible"/> - <int value="1" label="Eligible"/> -</enum> - <enum name="CaptivePortalStatus"> <int value="0" label="UNKNOWN"/> <int value="1" label="OFFLINE"/>
diff --git a/tools/metrics/histograms/metadata/optimization/enums.xml b/tools/metrics/histograms/metadata/optimization/enums.xml index 3838dd2..475cda5 100644 --- a/tools/metrics/histograms/metadata/optimization/enums.xml +++ b/tools/metrics/histograms/metadata/optimization/enums.xml
@@ -606,6 +606,8 @@ <int value="44" label="CAPITAL_ONE_CREDIT_CARD_GROCERY_BENEFITS"/> <int value="45" label="CAPITAL_ONE_CREDIT_CARD_ENTERTAINMENT_BENEFITS"/> <int value="46" label="CAPITAL_ONE_CREDIT_CARD_STREAMING_BENEFITS"/> + <int value="47" label="AMERICAN_EXPRESS_CREDIT_CARD_FLIGHT_BENEFITS"/> + <int value="48" label="AMERICAN_EXPRESS_CREDIT_CARD_SUBSCRIPTION_BENEFITS"/> </enum> </enums>
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml index 288c781..4460b16 100644 --- a/tools/metrics/histograms/metadata/optimization/histograms.xml +++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -99,6 +99,16 @@ <variants name="OptimizationType"> <variant name="AboutThisSite" summary="Provides 'About this site' data about the site being visited"/> + <variant name="AmericanExpressCreditCardFlightBenefits" + summary="This optimization provides information about whether a + merchant url is eligible for flight credit card benefits. + Applies to only American Express credit cards that support + benefits on Chrome."/> + <variant name="AmericanExpressCreditCardSubscriptionBenefits" + summary="This optimization provides information about whether a + merchant url is eligible for subscription credit card + benefits. Applies to only American Express credit cards that + support benefits on Chrome."/> <variant name="AutofillSamplingRate" summary="This optimization provides information about a sampling rate of Autofill UKM metrics per origin based on origin popularity."/>
diff --git a/tools/metrics/histograms/metadata/readaloud/enums.xml b/tools/metrics/histograms/metadata/readaloud/enums.xml new file mode 100644 index 0000000..ad13fef --- /dev/null +++ b/tools/metrics/histograms/metadata/readaloud/enums.xml
@@ -0,0 +1,40 @@ +<!-- +Copyright 2023 The Chromium Authors +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> + +<!-- + +This file describes the enumerations referenced by entries in histograms.xml for +this directory. Some enums may instead be listed in the central enums.xml file +at src/tools/metrics/histograms/enums.xml when multiple files use them. + +For best practices on writing enumerations descriptions, see +https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#Enum-Histograms + +Please follow the instructions in the OWNERS file in this directory to find a +reviewer. If no OWNERS file exists, please consider signing up at +go/reviewing-metrics (Googlers only), as all subdirectories are expected to +have an OWNERS file. As a last resort you can send the CL to +chromium-metrics-reviews@google.com. +--> + +<histogram-configuration> + +<!-- Enum types --> + +<enums> + +<enum name="ReadAloudIneligibilityReason"> + <int value="0" label="Unknown"/> + <int value="1" label="Feature flag disabled"/> + <int value="2" label="Incognito mode"/> + <int value="3" label="MSBB disabled"/> + <int value="4" label="Policy disabled"/> + <int value="5" label="Default search engine is not Google"/> +</enum> + +</enums> + +</histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/readaloud/histograms.xml b/tools/metrics/histograms/metadata/readaloud/histograms.xml index 3a9dd43..022d902 100644 --- a/tools/metrics/histograms/metadata/readaloud/histograms.xml +++ b/tools/metrics/histograms/metadata/readaloud/histograms.xml
@@ -22,11 +22,34 @@ <histograms> +<histogram name="ReadAloud.Eligibility.IneligiblityReason" + enum="ReadAloudIneligibilityReason" expires_after="2024-06-02"> + <owner>andreaxg@google.com</owner> + <owner>basiaz@google.com</owner> + <owner>iwells@chromium.org</owner> + <summary> + Histogram for recording why a user is not eligible for the ReadAloud + feature. Emitted when the user profile is available and the user is + ineligible. Conditions are checked in ReadAloudFeatures. + </summary> +</histogram> + +<histogram name="ReadAloud.Eligibility.IsUserEligible" enum="BooleanEligible" + expires_after="2024-06-02"> + <owner>andreaxg@google.com</owner> + <owner>basiaz@google.com</owner> + <owner>iwells@chromium.org</owner> + <summary> + Histogram for recording if a user is eligible for ReadAloud. Emitted when + the user profile is available. + </summary> +</histogram> + <histogram name="ReadAloud.IsPageReadable" enum="BooleanSuccess" expires_after="2024-06-02"> <owner>andreaxg@google.com</owner> <owner>basiaz@google.com</owner> - <owner>iwells@google.com</owner> + <owner>iwells@chromium.org</owner> <summary> Histogram for recording if a page readability check comes back successful or not. The readability check is run on each page load for Android clients who
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml index 104515dd..e9452e9 100644 --- a/tools/metrics/histograms/metadata/sync/histograms.xml +++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -484,7 +484,9 @@ NOTE: This does NOT include OS datatypes. Use Sync.CustomOSSync for those. See also "Sync.SelectedTypesInTransportMode" which is the - corresponding histogram for Sync-transport users. + corresponding histogram for Sync-transport users, and + "Sync.SyncEverything2" which is the histogram for whether the user + has selected the "Sync Everything" option. </summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/web_rtc/histograms.xml b/tools/metrics/histograms/metadata/web_rtc/histograms.xml index 242860e2..dfe137d 100644 --- a/tools/metrics/histograms/metadata/web_rtc/histograms.xml +++ b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
@@ -1423,15 +1423,6 @@ </summary> </histogram> -<histogram name="WebRTC.PeerConnection.Simulcast.NumberOfSendEncodings" - units="units" expires_after="2020-08-30"> - <owner>amithi@chromium.org</owner> - <summary> - Counts the number of send encodings given to PeerConnection::AddTransceiver. - This histogram will be used to understand if and how the API is used. - </summary> -</histogram> - <histogram name="WebRTC.PeerConnection.SpeedLimit" units="%" expires_after="2024-04-28"> <owner>handellm@google.com</owner>
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py index 4a953e6..66f16bd 100644 --- a/tools/perf/core/bot_platforms.py +++ b/tools/perf/core/bot_platforms.py
@@ -488,6 +488,16 @@ _GetBenchmarkConfig('octane'), _GetBenchmarkConfig('speedometer2'), ]) +_WIN_11_BENCHMARK_CONFIGS = PerfSuite(OFFICIAL_BENCHMARK_CONFIGS).Remove([ + 'blink_perf.display_locking', + 'v8.runtime_stats.top_25', +]) +_WIN_11_EXECUTABLE_CONFIGS = frozenset([ + _base_perftests(200), + _components_perftests(125), + _dawn_perf_tests(600), + _views_perftests(), +]) _ANDROID_GO_BENCHMARK_CONFIGS = PerfSuite([ _GetBenchmarkConfig('system_health.memory_mobile'), _GetBenchmarkConfig('system_health.common_mobile'), @@ -704,6 +714,19 @@ 3, 'win', pinpoint_only=True) +WIN_11 = PerfPlatform('win-11-perf', + 'Windows Dell PowerEdge R350', + _WIN_11_BENCHMARK_CONFIGS, + 20, + 'win', + executables=_WIN_11_EXECUTABLE_CONFIGS) +WIN_11_PGO = PerfPlatform('win-11-perf-pgo', + 'Windows Dell PowerEdge R350', + _WIN_11_BENCHMARK_CONFIGS, + 26, + 'win', + executables=_WIN_11_EXECUTABLE_CONFIGS, + pinpoint_only=True) # Android ANDROID_GO = PerfPlatform('android-go-perf', 'Android O (gobo)',
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index f6bb998..a243288a 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -104,6 +104,7 @@ 'linux-perf', 'win-10-perf', 'win-10_laptop_low_end-perf', + 'win-11-perf', 'mac-laptop_high_end-perf', 'mac-laptop_low_end-perf', ] @@ -956,6 +957,54 @@ 'synthetic_product_name': 'OMEN by HP Laptop 16-c0xxx [ ] (HP)', }, }, + 'win-11-perf': { + 'tests': [ + { + 'isolate': 'performance_test_suite', + 'extra_args': [ + '--assert-gpu-compositing', + ], + }, + ], + 'platform': + 'win', + 'target_bits': + 64, + 'dimension': { + 'pool': 'chrome.tests.perf', + # Explicitly set GPU driver version and Windows OS version such + # that we can be informed if this + # version ever changes or becomes inconsistent. It is important + # that bots are homogeneous. See crbug.com/988045 for history. + 'os': 'Windows-11-22631.2428', + 'gpu': '102b:0536-4.5.0.5', + 'synthetic_product_name': 'PowerEdge R350 (Dell Inc.)' + }, + }, + 'win-11-perf-pgo': { + 'tests': [ + { + 'isolate': 'performance_test_suite', + 'extra_args': [ + '--assert-gpu-compositing', + ], + }, + ], + 'platform': + 'win', + 'target_bits': + 64, + 'dimension': { + 'pool': 'chrome.tests.perf', + # Explicitly set GPU driver version and Windows OS version such + # that we can be informed if this + # version ever changes or becomes inconsistent. It is important + # that bots are homogeneous. See crbug.com/988045 for history. + 'os': 'Windows-11-22631.2428', + 'gpu': '102b:0536-4.5.0.5', + 'synthetic_product_name': 'PowerEdge R350 (Dell Inc.)' + }, + }, 'mac-laptop_low_end-perf': { 'tests': [ { @@ -1202,6 +1251,10 @@ 'platform': 'linux', 'perf_processor': True, }, + 'win-11-processor-perf': { + 'platform': 'linux', + 'perf_processor': True, + }, 'mac-laptop_low_end-processor-perf': { 'platform': 'linux', 'perf_processor': True,
diff --git a/tools/perf/core/perf_json_config_validator.py b/tools/perf/core/perf_json_config_validator.py index e0f6c0a..365778e2 100644 --- a/tools/perf/core/perf_json_config_validator.py +++ b/tools/perf/core/perf_json_config_validator.py
@@ -137,6 +137,7 @@ raise ValueError("%s must use 'lacros-chrome' browser type" % builder_name) elif builder_name in ('win-10-perf', 'win-10-perf-pgo', + 'win-11-perf', 'win-11-perf-pgo', 'Win 7 Nvidia GPU Perf', 'win-10_laptop_low_end-perf_HP-Candidate', 'win-10_laptop_low_end-perf',
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 1e787e0..51b98e68 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@ }, "win": { "hash": "d8bdf3585476c6999118803e3caacc79d5551f85", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/819068d7e83a09200ee0b3a43fe44d90465cca5e/trace_processor_shell.exe" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/1072e37cbb64611f0b911427c6c2e497d4925881/trace_processor_shell.exe" }, "linux_arm": { "hash": "8aa911491cd365131216862ae495e18424ebe1b2",
diff --git a/tools/perf/core/shard_maps/timing_data/win-11-perf-pgo_timing.json b/tools/perf/core/shard_maps/timing_data/win-11-perf-pgo_timing.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/tools/perf/core/shard_maps/timing_data/win-11-perf-pgo_timing.json
@@ -0,0 +1 @@ +[] \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/timing_data/win-11-perf_timing.json b/tools/perf/core/shard_maps/timing_data/win-11-perf_timing.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/tools/perf/core/shard_maps/timing_data/win-11-perf_timing.json
@@ -0,0 +1 @@ +[] \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/win-11-perf-pgo_map.json b/tools/perf/core/shard_maps/win-11-perf-pgo_map.json new file mode 100644 index 0000000..428a3ed --- /dev/null +++ b/tools/perf/core/shard_maps/win-11-perf-pgo_map.json
@@ -0,0 +1,416 @@ +{ + "0": { + "benchmarks": { + "ad_frames.fencedframe": { + "abridged": false + }, + "blink_perf.accessibility": { + "abridged": false + }, + "blink_perf.bindings": { + "end": 6, + "abridged": false + } + }, + "executables": { + "base_perftests": { + "arguments": [ + "--test-launcher-jobs=1", + "--test-launcher-retry-limit=0" + ], + "path": "base_perftests" + } + } + }, + "1": { + "benchmarks": { + "blink_perf.bindings": { + "begin": 6, + "abridged": false + }, + "blink_perf.css": { + "end": 5, + "abridged": false + } + } + }, + "2": { + "benchmarks": { + "blink_perf.css": { + "begin": 5, + "end": 55, + "abridged": false + } + } + }, + "3": { + "benchmarks": { + "blink_perf.css": { + "begin": 55, + "abridged": false + }, + "blink_perf.dom": { + "abridged": false + }, + "blink_perf.events": { + "abridged": false + }, + "blink_perf.image_decoder": { + "abridged": false + }, + "blink_perf.layout": { + "end": 19, + "abridged": false + } + } + }, + "4": { + "benchmarks": { + "blink_perf.layout": { + "begin": 19, + "end": 69, + "abridged": false + } + } + }, + "5": { + "benchmarks": { + "blink_perf.layout": { + "begin": 69, + "abridged": false + }, + "blink_perf.owp_storage": { + "abridged": false + }, + "blink_perf.paint": { + "end": 7, + "abridged": false + } + } + }, + "6": { + "benchmarks": { + "blink_perf.paint": { + "begin": 7, + "abridged": false + }, + "blink_perf.parser": { + "abridged": false + }, + "blink_perf.shadow_dom": { + "end": 10, + "abridged": false + } + } + }, + "7": { + "benchmarks": { + "blink_perf.shadow_dom": { + "begin": 10, + "abridged": false + }, + "blink_perf.svg": { + "end": 21, + "abridged": false + } + } + }, + "8": { + "benchmarks": { + "blink_perf.svg": { + "begin": 21, + "abridged": false + }, + "blink_perf.webaudio": { + "abridged": false + }, + "blink_perf.webcodecs": { + "abridged": false + }, + "blink_perf.webgl": { + "abridged": false + }, + "blink_perf.webgl_fast_call": { + "abridged": false + }, + "blink_perf.webgpu": { + "abridged": false + }, + "blink_perf.webgpu_fast_call": { + "abridged": false + } + }, + "executables": { + "components_perftests": { + "arguments": [ + "--xvfb" + ], + "path": "components_perftests" + } + } + }, + "9": { + "executables": { + "dawn_perf_tests": { + "arguments": [ + "--test-launcher-jobs=1", + "--test-launcher-retry-limit=0" + ], + "path": "dawn_perf_tests" + } + }, + "benchmarks": {} + }, + "10": { + "benchmarks": { + "desktop_ui": { + "abridged": false + }, + "dummy_benchmark.noisy_benchmark_1": { + "abridged": false + }, + "dummy_benchmark.stable_benchmark_1": { + "abridged": false + }, + "jetstream": { + "abridged": false + }, + "jetstream2": { + "abridged": false + }, + "kraken": { + "abridged": false + }, + "loading.desktop": { + "end": 18, + "abridged": false + } + } + }, + "11": { + "benchmarks": { + "loading.desktop": { + "begin": 18, + "end": 68, + "abridged": false + } + } + }, + "12": { + "benchmarks": { + "loading.desktop": { + "begin": 68, + "abridged": false + }, + "media.desktop": { + "end": 14, + "abridged": false + } + } + }, + "13": { + "benchmarks": { + "media.desktop": { + "begin": 14, + "abridged": false + }, + "memory.desktop": { + "abridged": false + }, + "octane": { + "abridged": false + }, + "power.desktop": { + "abridged": false + }, + "rasterize_and_record_micro.top_25": { + "end": 14, + "abridged": false + } + } + }, + "14": { + "benchmarks": { + "rasterize_and_record_micro.top_25": { + "begin": 14, + "abridged": false + }, + "rendering.desktop": { + "end": 39, + "abridged": false + } + } + }, + "15": { + "benchmarks": { + "rendering.desktop": { + "begin": 39, + "end": 89, + "abridged": false + } + } + }, + "16": { + "benchmarks": { + "rendering.desktop": { + "begin": 89, + "end": 138, + "abridged": false + } + } + }, + "17": { + "benchmarks": { + "rendering.desktop": { + "begin": 138, + "end": 188, + "abridged": false + } + } + }, + "18": { + "benchmarks": { + "rendering.desktop": { + "begin": 188, + "end": 237, + "abridged": false + } + } + }, + "19": { + "benchmarks": { + "rendering.desktop": { + "begin": 237, + "end": 287, + "abridged": false + } + } + }, + "20": { + "benchmarks": { + "rendering.desktop": { + "begin": 287, + "abridged": false + }, + "rendering.desktop.notracing": { + "abridged": false + }, + "speedometer": { + "abridged": false + }, + "speedometer-future": { + "abridged": false + }, + "speedometer2": { + "abridged": false + }, + "speedometer2-future": { + "abridged": false + }, + "system_health.common_desktop": { + "end": 1, + "abridged": false + } + } + }, + "21": { + "benchmarks": { + "system_health.common_desktop": { + "begin": 1, + "end": 51, + "abridged": false + } + } + }, + "22": { + "benchmarks": { + "system_health.common_desktop": { + "begin": 51, + "abridged": false + }, + "system_health.memory_desktop": { + "end": 19, + "abridged": false + } + } + }, + "23": { + "benchmarks": { + "system_health.memory_desktop": { + "begin": 19, + "end": 69, + "abridged": false + } + } + }, + "24": { + "benchmarks": { + "system_health.memory_desktop": { + "begin": 69, + "abridged": false + }, + "v8.browsing_desktop": { + "end": 26, + "abridged": false + } + } + }, + "25": { + "benchmarks": { + "v8.browsing_desktop": { + "begin": 26, + "abridged": false + }, + "v8.browsing_desktop-future": { + "abridged": false + }, + "wasmpspdfkit": { + "abridged": false + }, + "webrtc": { + "abridged": false + } + }, + "executables": { + "views_perftests": { + "arguments": [ + "--xvfb" + ], + "path": "views_perftests" + } + } + }, + "extra_infos": { + "num_stories": 1210, + "predicted_min_shard_time": 445.0, + "predicted_min_shard_index": 8, + "predicted_max_shard_time": 600.0, + "predicted_max_shard_index": 9, + "shard #0": 500.0, + "shard #1": 500, + "shard #2": 500, + "shard #3": 500, + "shard #4": 500, + "shard #5": 500, + "shard #6": 500, + "shard #7": 500, + "shard #8": 445.0, + "shard #9": 600.0, + "shard #10": 500, + "shard #11": 500, + "shard #12": 500, + "shard #13": 500, + "shard #14": 500, + "shard #15": 500, + "shard #16": 490, + "shard #17": 500, + "shard #18": 490, + "shard #19": 500, + "shard #20": 490, + "shard #21": 500, + "shard #22": 490, + "shard #23": 500, + "shard #24": 490, + "shard #25": 497.0 + } +}
diff --git a/tools/perf/core/shard_maps/win-11-perf_map.json b/tools/perf/core/shard_maps/win-11-perf_map.json new file mode 100644 index 0000000..51010a7 --- /dev/null +++ b/tools/perf/core/shard_maps/win-11-perf_map.json
@@ -0,0 +1,547 @@ +{ + "0": { + "benchmarks": { + "ad_frames.fencedframe": { + "abridged": false + }, + "blink_perf.accessibility": { + "abridged": false + }, + "blink_perf.bindings": { + "end": 28, + "abridged": false + }, + "jetstream2": { + "abridged": false + }, + "system_health.common_desktop": { + "sections": [ + { + "begin": 43, + "end": 44 + }, + { + "begin": 72, + "end": 74 + } + ], + "abridged": false + }, + "speedometer2": { + "abridged": false + } + }, + "executables": { + "base_perftests": { + "arguments": [ + "--test-launcher-jobs=1", + "--test-launcher-retry-limit=0" + ], + "path": "base_perftests" + } + } + }, + "1": { + "benchmarks": { + "blink_perf.bindings": { + "begin": 28, + "abridged": false + }, + "blink_perf.css": { + "abridged": false + }, + "blink_perf.dom": { + "end": 18, + "abridged": false + }, + "jetstream2": { + "abridged": false + }, + "system_health.common_desktop": { + "sections": [ + { + "begin": 43, + "end": 44 + }, + { + "begin": 72, + "end": 74 + } + ], + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "2": { + "benchmarks": { + "blink_perf.dom": { + "begin": 18, + "abridged": false + }, + "blink_perf.events": { + "abridged": false + }, + "blink_perf.image_decoder": { + "abridged": false + }, + "blink_perf.layout": { + "end": 109, + "abridged": false + }, + "jetstream2": { + "abridged": false + }, + "system_health.common_desktop": { + "sections": [ + { + "begin": 43, + "end": 44 + }, + { + "begin": 72, + "end": 74 + } + ], + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "3": { + "benchmarks": { + "blink_perf.layout": { + "begin": 109, + "abridged": false + }, + "blink_perf.owp_storage": { + "abridged": false + }, + "blink_perf.parser": { + "abridged": false + }, + "blink_perf.shadow_dom": { + "abridged": false + }, + "blink_perf.webaudio": { + "abridged": false + }, + "blink_perf.webcodecs": { + "abridged": false + }, + "blink_perf.webgl": { + "abridged": false + }, + "jetstream2": { + "abridged": false + }, + "system_health.common_desktop": { + "sections": [ + { + "begin": 43, + "end": 44 + }, + { + "begin": 72, + "end": 74 + } + ], + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "4": { + "benchmarks": { + "blink_perf.webgl_fast_call": { + "abridged": false + }, + "blink_perf.webgpu": { + "abridged": false + }, + "blink_perf.webgpu_fast_call": { + "abridged": false + }, + "desktop_ui": { + "end": 6, + "abridged": false + }, + "jetstream2": { + "abridged": false + }, + "system_health.common_desktop": { + "sections": [ + { + "begin": 43, + "end": 44 + }, + { + "begin": 72, + "end": 74 + } + ], + "abridged": false + }, + "speedometer2": { + "abridged": false + } + }, + "executables": { + "components_perftests": { + "arguments": [ + "--xvfb" + ], + "path": "components_perftests" + }, + "dawn_perf_tests": { + "arguments": [ + "--test-launcher-jobs=1", + "--test-launcher-retry-limit=0" + ], + "path": "dawn_perf_tests" + } + } + }, + "5": { + "benchmarks": { + "desktop_ui": { + "begin": 6, + "abridged": false + }, + "dummy_benchmark.noisy_benchmark_1": { + "abridged": false + }, + "dummy_benchmark.stable_benchmark_1": { + "abridged": false + }, + "jetstream2": { + "abridged": false + }, + "media.desktop": { + "end": 12, + "abridged": false + }, + "system_health.common_desktop": { + "sections": [ + { + "begin": 43, + "end": 44 + }, + { + "begin": 72, + "end": 74 + } + ], + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "6": { + "benchmarks": { + "media.desktop": { + "begin": 12, + "abridged": false + }, + "memory.desktop": { + "end": 7, + "abridged": false + }, + "system_health.common_desktop": { + "sections": [ + { + "begin": 43, + "end": 44 + }, + { + "begin": 72, + "end": 74 + } + ], + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "7": { + "benchmarks": { + "memory.desktop": { + "begin": 7, + "abridged": false + }, + "octane": { + "abridged": false + }, + "power.desktop": { + "abridged": false + }, + "rasterize_and_record_micro.top_25": { + "abridged": false + }, + "rendering.desktop": { + "end": 7, + "abridged": false + }, + "system_health.common_desktop": { + "sections": [ + { + "begin": 43, + "end": 44 + }, + { + "begin": 72, + "end": 74 + } + ], + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "8": { + "benchmarks": { + "rendering.desktop": { + "begin": 7, + "end": 84, + "abridged": false + }, + "system_health.common_desktop": { + "sections": [ + { + "begin": 43, + "end": 44 + }, + { + "begin": 72, + "end": 74 + } + ], + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "9": { + "benchmarks": { + "rendering.desktop": { + "begin": 84, + "end": 161, + "abridged": false + }, + "system_health.common_desktop": { + "sections": [ + { + "begin": 43, + "end": 44 + }, + { + "begin": 72, + "end": 74 + } + ], + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "10": { + "benchmarks": { + "rendering.desktop": { + "begin": 161, + "end": 238, + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "11": { + "benchmarks": { + "rendering.desktop": { + "begin": 238, + "end": 302, + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "12": { + "benchmarks": { + "rendering.desktop": { + "begin": 302, + "abridged": false + }, + "rendering.desktop.notracing": { + "abridged": false + }, + "speedometer": { + "abridged": false + }, + "speedometer-future": { + "abridged": false + }, + "speedometer2": { + "abridged": false + }, + "speedometer2-future": { + "abridged": false + }, + "system_health.common_desktop": { + "end": 17, + "abridged": false + } + } + }, + "13": { + "benchmarks": { + "system_health.common_desktop": { + "begin": 17, + "end": 77, + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "14": { + "benchmarks": { + "system_health.common_desktop": { + "begin": 77, + "abridged": false + }, + "system_health.memory_desktop": { + "end": 22, + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "15": { + "benchmarks": { + "system_health.memory_desktop": { + "begin": 22, + "end": 42, + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "16": { + "benchmarks": { + "system_health.memory_desktop": { + "begin": 42, + "end": 62, + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "17": { + "benchmarks": { + "system_health.memory_desktop": { + "begin": 62, + "end": 73, + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "18": { + "benchmarks": { + "system_health.memory_desktop": { + "begin": 73, + "abridged": false + }, + "v8.browsing_desktop": { + "end": 25, + "abridged": false + }, + "speedometer2": { + "abridged": false + } + } + }, + "19": { + "benchmarks": { + "v8.browsing_desktop": { + "begin": 25, + "abridged": false + }, + "v8.browsing_desktop-future": { + "abridged": false + }, + "wasmpspdfkit": { + "abridged": false + }, + "webrtc": { + "abridged": false + }, + "speedometer2": { + "abridged": false + } + }, + "executables": { + "views_perftests": { + "arguments": [ + "--xvfb" + ], + "path": "views_perftests" + } + } + }, + "extra_infos": { + "num_stories": 1130, + "predicted_min_shard_time": 1706.0, + "predicted_min_shard_index": 14, + "predicted_max_shard_time": 2093.0, + "predicted_max_shard_index": 19, + "shard #0": 1784.0, + "shard #1": 1781.0, + "shard #2": 1780.0, + "shard #3": 1776.0, + "shard #4": 1871.0, + "shard #5": 1782.0, + "shard #6": 1717.0, + "shard #7": 1776.0, + "shard #8": 1779.0, + "shard #9": 1785.0, + "shard #10": 1773.0, + "shard #11": 1785.0, + "shard #12": 1775.0, + "shard #13": 1775.0, + "shard #14": 1706.0, + "shard #15": 1751.0, + "shard #16": 1784.0, + "shard #17": 1832.0, + "shard #18": 1770.0, + "shard #19": 2093.0 + } +} \ No newline at end of file
diff --git a/tools/perf/cross_device_test_config.py b/tools/perf/cross_device_test_config.py index e97b9580..6e929b15 100644 --- a/tools/perf/cross_device_test_config.py +++ b/tools/perf/cross_device_test_config.py
@@ -129,6 +129,20 @@ 'Speedometer2': 20, }, }, + 'win-11-perf': { + 'jetstream2': { + 'JetStream2': 5, + }, + 'system_health.common_desktop': { + # cputimeToFirstContentfulPaint + 'browse:media:tumblr:2018': 10, + 'browse:social:tumblr_infinite_scroll:2018': 10, + 'load:search:google:2018': 10, + }, + 'speedometer2': { + 'Speedometer2': 20, + }, + }, 'linux-perf-calibration': { 'jetstream2': { 'JetStream2': 10,
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc index 874d0194..71f9c95 100644 --- a/ui/android/delegated_frame_host_android.cc +++ b/ui/android/delegated_frame_host_android.cc
@@ -212,10 +212,7 @@ std::vector<viz::SurfaceId> DelegatedFrameHostAndroid::CollectSurfaceIdsForEviction() const { - if (base::FeatureList::IsEnabled(features::kEvictSubtree)) { - return client_->CollectSurfaceIdsForEviction(); - } - return std::vector<viz::SurfaceId>(); + return client_->CollectSurfaceIdsForEviction(); } viz::SurfaceId DelegatedFrameHostAndroid::GetCurrentSurfaceId() const {
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.cc b/ui/shell_dialogs/select_file_dialog_linux_portal.cc index eef069a2..0e0a58b 100644 --- a/ui/shell_dialogs/select_file_dialog_linux_portal.cc +++ b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
@@ -101,9 +101,9 @@ option_writer.OpenVariant("ay", &value_writer); value_writer.AppendArrayOfBytes( - reinterpret_cast<const std::uint8_t*>(value.c_str()), - // size + 1 will include the null terminator. - value.size() + 1); + base::make_span(reinterpret_cast<const std::uint8_t*>(value.c_str()), + // size + 1 will include the null terminator. + value.size() + 1)); option_writer.CloseContainer(&value_writer); writer->CloseContainer(&option_writer);
diff --git a/ui/views/controls/button/button.cc b/ui/views/controls/button/button.cc index c994b37..07336e02 100644 --- a/ui/views/controls/button/button.cc +++ b/ui/views/controls/button/button.cc
@@ -210,7 +210,7 @@ OnPropertyChanged(&tooltip_text_, kPropertyEffectsNone); } -std::u16string Button::GetTooltipText() const { +const std::u16string& Button::GetTooltipText() const { return tooltip_text_; }
diff --git a/ui/views/controls/button/button.h b/ui/views/controls/button/button.h index ef3b06a..8fe5b79 100644 --- a/ui/views/controls/button/button.h +++ b/ui/views/controls/button/button.h
@@ -155,7 +155,7 @@ static ButtonState GetButtonStateFrom(ui::NativeTheme::State state); void SetTooltipText(const std::u16string& tooltip_text); - std::u16string GetTooltipText() const; + const std::u16string& GetTooltipText() const; // Tag is now a property. These accessors are deprecated. Use GetTag() and // SetTag() below or even better, use SetID()/GetID() from the ancestor.
diff --git a/ui/views/layout/flex_layout.cc b/ui/views/layout/flex_layout.cc index de73697a..9bb5ad2 100644 --- a/ui/views/layout/flex_layout.cc +++ b/ui/views/layout/flex_layout.cc
@@ -839,6 +839,10 @@ const size_t view_index, SizeBound size) const { FlexChildData& flex_child = data.child_data[view_index]; + if (size.value() <= flex_child.miniumize_size.main()) { + return flex_child.miniumize_size; + } + ChildLayout& child_layout = data.layout.child_layouts[view_index]; // See how much space the child view wants within the reduced space @@ -904,6 +908,10 @@ ChildIndices& child_list, FlexLayoutData& data, ChildViewSpacing& child_spacing) const { + if (!bounds.main().is_bounded()) { + return SizeBound(); + } + SizeBound remaining = std::max<SizeBound>(0, bounds.main() - data.total_size.main());
diff --git a/v8 b/v8 index b14b07f..fa0dfe29 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit b14b07f77468cf45e4bdca467c187090c9a7dbd3 +Subproject commit fa0dfe29a7bcc29e36b243add34a83844ce8b21a