diff --git a/DEPS b/DEPS index b381a79..4d14d27 100644 --- a/DEPS +++ b/DEPS
@@ -234,11 +234,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '688cb15faa641680346f7510bbf6e5d77053bc0e', + 'skia_revision': '0774db13d24ce59ae9560701d7c19772669f9ac4', # 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': '99489318d40626fb10047f33c4f7fd893fd89bc9', + 'v8_revision': '0e0109edceda7c23a76aa7657f3c70f9b79dc8df', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -246,7 +246,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '7737c2bcff2e7f0c3ad7dc769c615c0d0c94df79', + 'swiftshader_revision': '4c687cc2f8ea9d096a66ad43c08805d36a559ede', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -301,7 +301,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'f61cb71c3cd559d3ccce35544ea626f32b9de3c6', + 'catapult_revision': 'e6e1eb6895e71193452e361388240498955c51eb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -309,7 +309,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': '93c0859f32546392eb58e3463d349499dbcec8b8', + 'devtools_frontend_revision': '80e47cf285206fb6c6fa101005949b2c6bfd1c14', # 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. @@ -349,7 +349,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '4b7ba255c3a62edb99182f17a3de7c77720313fd', + 'dawn_revision': '7260fe69b7251ff7c673308dc8bdebda344147f8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -791,7 +791,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'KaJVIPBjh2qbCob6hsVzLk1brSl4iuZVYNpUH0sgg20C', + 'version': 'B7B3qXoWKXASrnI5M2ySp9skL0Ozjnw8ViPqwmmTlfEC', }, ], 'condition': 'checkout_android', @@ -890,7 +890,7 @@ }, { 'package': 'chromium/third_party/android_sdk/public/cmdline-tools', - 'version': 'AuYa11pULKT8AI14_owabJrkZoRGuovL-nvwmiONlYEC', + 'version': 'Ez2NWws2SJYCF6qw2O-mSCqK6424l3ZdSTpppLyVR_cC', }, ], 'condition': 'checkout_android_native_support', @@ -1030,7 +1030,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '176a9e8764598a6da911e6be2fd12e46def8d6f5', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1c7dec337d646d7b842d52355576729992382f0f', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1413,7 +1413,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f32b6ac45880108dee6eaa9e585aa8c6217607cb', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '19fb767c32d05d75314d376933b98be246e0b723', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1457,8 +1457,8 @@ 'src/third_party/qemu-linux-x64': { 'packages': [ { - 'package': 'fuchsia/qemu/linux-amd64', - 'version': '9cc486c5b18a0be515c39a280ca9a309c54cf994' + 'package': 'fuchsia/third_party/qemu/linux-amd64', + 'version': 'FFZaD9tecL-z0lq2XP_7UqiAaMgRGwXTyvcmkv7XCQcC' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1468,8 +1468,8 @@ 'src/third_party/qemu-mac-x64': { 'packages': [ { - 'package': 'fuchsia/qemu/mac-amd64', - 'version': '2d3358ae9a569b2d4a474f498b32b202a152134f' + 'package': 'fuchsia/third_party/qemu/mac-amd64', + 'version': '79L6B9YhuL7uIg_CxwlQcZqLOixVtS2Cctn7dmVg0q4C' }, ], 'condition': 'host_os == "mac" and checkout_fuchsia', @@ -1692,7 +1692,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@8e7e2748ffff032f17357340acccfa37a8f10364', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b375548ba1b2c4e463e6e536cd41d2775ee72ef6', 'condition': 'checkout_src_internal', }, @@ -1733,7 +1733,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': '83She84pH_XiIJLWleSamUFIRmsfU4x6Vb5Fq2dFDbAC', + 'version': 'dA9xqxm4XUSyXF3ehqpywnp7uJvD4o10mEj3qLkSMEsC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/browser/metrics/visibility_metrics_logger_unittest.cc b/android_webview/browser/metrics/visibility_metrics_logger_unittest.cc index 58298f1..66050aca 100644 --- a/android_webview/browser/metrics/visibility_metrics_logger_unittest.cc +++ b/android_webview/browser/metrics/visibility_metrics_logger_unittest.cc
@@ -4,7 +4,9 @@ #include "android_webview/browser/metrics/visibility_metrics_logger.h" +#include "android_webview/common/aw_features.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/time/clock.h" #include "content/public/test/browser_task_environment.h" @@ -351,4 +353,86 @@ 170); } +TEST_F(VisibilityMetricsLoggerTest, TestScreenPortion) { + // t=0: client created + // t=10: client visible, navigates to web content, screen percentage 0% + // t=30: 7% screen percentage + // t=35: 42% screen percentage + // t=45: 100% screen percentage + // t=60: client invisible + // t=70: client visible + // t=95: client navigates away from web content + // t=100: client deleted + + // Time with no visible client: 10 + 10 = 20 + // Time with client visible: 20 + 5 + 10 + 15 + 25 + 5 = 80 + // Time with client displaying web content: 20 + 5 + 10 + 15 + 25 = 75 + // Time displaying web content with portion kExactlyZeroPercent: 20 + // Time displaying web content with portion kZeroPercent: 5 + // Time displaying web content with portion kFortyPercent: 10 + // Time displaying web content with portion kOneHundredPercent: 15 + 25 = 40 + + base::HistogramTester histogram_tester; + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + android_webview::features::kWebViewMeasureScreenCoverage); + std::unique_ptr<TestClient> client = std::make_unique<TestClient>(logger()); + + task_environment().FastForwardBy(base::Seconds(10)); + client->SetViewVisible(true); + client->SetViewAttached(true); + client->SetWindowVisible(true); + client->SetSchemeHttpOrHttps(true); + // If pixels is 0 then time spent is logged under kExactlyZeroPercent, + // otherwise the screen portion is calculated as percentage / 10. + logger()->UpdateOpenWebScreenArea(/*pixels=*/0, /*percentage=*/0); + + task_environment().FastForwardBy(base::Seconds(20)); + logger()->UpdateOpenWebScreenArea(/*pixels=*/14, /*percentage=*/7); + + task_environment().FastForwardBy(base::Seconds(5)); + logger()->UpdateOpenWebScreenArea(/*pixels=*/84, /*percentage=*/42); + + task_environment().FastForwardBy(base::Seconds(10)); + logger()->UpdateOpenWebScreenArea(/*pixels=*/200, /*percentage=*/100); + + task_environment().FastForwardBy(base::Seconds(15)); + client->SetViewVisible(false); + + task_environment().FastForwardBy(base::Seconds(10)); + client->SetViewVisible(true); + + task_environment().FastForwardBy(base::Seconds(25)); + client->SetSchemeHttpOrHttps(false); + + task_environment().FastForwardBy(base::Seconds(5)); + logger()->RecordMetrics(); + client.reset(); + + histogram_tester.ExpectBucketCount( + "Android.WebView.Visibility.Global", + VisibilityMetricsLogger::Visibility::kNotVisible, 20); + histogram_tester.ExpectBucketCount( + "Android.WebView.Visibility.Global", + VisibilityMetricsLogger::Visibility::kVisible, 80); + histogram_tester.ExpectBucketCount( + "Android.WebView.WebViewOpenWebVisible.Global", + VisibilityMetricsLogger::WebViewOpenWebVisibility::kDisplayOpenWebContent, + 75); + histogram_tester.ExpectBucketCount( + "Android.WebView.WebViewOpenWebVisible.ScreenPortion2", + VisibilityMetricsLogger::WebViewOpenWebScreenPortion::kExactlyZeroPercent, + 20); + histogram_tester.ExpectBucketCount( + "Android.WebView.WebViewOpenWebVisible.ScreenPortion2", + VisibilityMetricsLogger::WebViewOpenWebScreenPortion::kZeroPercent, 5); + histogram_tester.ExpectBucketCount( + "Android.WebView.WebViewOpenWebVisible.ScreenPortion2", + VisibilityMetricsLogger::WebViewOpenWebScreenPortion::kFortyPercent, 10); + histogram_tester.ExpectBucketCount( + "Android.WebView.WebViewOpenWebVisible.ScreenPortion2", + VisibilityMetricsLogger::WebViewOpenWebScreenPortion::kOneHundredPercent, + 40); +} + } // namespace android_webview
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 7b2e5528..7ebda1cd 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -571,6 +571,11 @@ const base::Feature kFilesBannerFramework{"FilesBannerFramework", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enable the simple archive extraction. +// https://crbug.com/953256 +const base::Feature kFilesExtractArchive{"FilesExtractArchive", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables the System Web App (SWA) version of file manager. const base::Feature kFilesSWA{"FilesSWA", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -582,9 +587,6 @@ const base::Feature kFilesTrash{"FilesTrash", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kFilesZipUnpack{"FilesZipUnpack", - base::FEATURE_DISABLED_BY_DEFAULT}; - // Enables filters in Files app Recents view. const base::Feature kFiltersInRecents{"FiltersInRecents", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 1c370def..7e7f399 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -221,11 +221,11 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesArchivemount2; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesBannerFramework; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesExtractArchive; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesSWA; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesSinglePartitionFormat; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesTrash; -COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesZipUnpack; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFiltersInRecents; COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFirmwareUpdaterApp; COMPONENT_EXPORT(ASH_CONSTANTS)
diff --git a/ash/public/cpp/holding_space/holding_space_prefs.cc b/ash/public/cpp/holding_space/holding_space_prefs.cc index 4657a178..1c9b475 100644 --- a/ash/public/cpp/holding_space/holding_space_prefs.cc +++ b/ash/public/cpp/holding_space/holding_space_prefs.cc
@@ -51,11 +51,25 @@ registry->RegisterTimePref(kTimeOfFirstPin, unix_epoch); } +void ResetProfilePrefsForTesting(PrefService* prefs) { + prefs->ClearPref(kPreviewsEnabled); + prefs->ClearPref(kTimeOfFirstAdd); + prefs->ClearPref(kTimeOfFirstAvailability); + prefs->ClearPref(kTimeOfFirstEntry); + prefs->ClearPref(kTimeOfFirstFilesAppChipPress); + prefs->ClearPref(kTimeOfFirstPin); +} + void AddPreviewsEnabledChangedCallback(PrefChangeRegistrar* registrar, base::RepeatingClosure callback) { registrar->Add(kPreviewsEnabled, std::move(callback)); } +void AddTimeOfFirstAddChangedCallback(PrefChangeRegistrar* registrar, + base::RepeatingClosure callback) { + registrar->Add(kTimeOfFirstAdd, std::move(callback)); +} + bool IsPreviewsEnabled(PrefService* prefs) { return prefs->GetBoolean(kPreviewsEnabled); }
diff --git a/ash/public/cpp/holding_space/holding_space_prefs.h b/ash/public/cpp/holding_space/holding_space_prefs.h index 7c7494e..cae6d5b 100644 --- a/ash/public/cpp/holding_space/holding_space_prefs.h +++ b/ash/public/cpp/holding_space/holding_space_prefs.h
@@ -23,11 +23,19 @@ // Registers holding space profile preferences to `registry`. ASH_PUBLIC_EXPORT void RegisterProfilePrefs(PrefRegistrySimple* registry); +// Resets all preferences to their default values. +ASH_PUBLIC_EXPORT void ResetProfilePrefsForTesting(PrefService* prefs); + // Adds `callback` to `registrar` to be invoked on changes to previews enabled. ASH_PUBLIC_EXPORT void AddPreviewsEnabledChangedCallback( PrefChangeRegistrar* registrar, base::RepeatingClosure callback); +// Adds `callback` to `registrar` to be invoked on changes to time of first add. +ASH_PUBLIC_EXPORT void AddTimeOfFirstAddChangedCallback( + PrefChangeRegistrar* registrar, + base::RepeatingClosure callback); + // Returns whether previews are enabled. ASH_PUBLIC_EXPORT bool IsPreviewsEnabled(PrefService* prefs);
diff --git a/ash/system/holding_space/holding_space_tray.cc b/ash/system/holding_space/holding_space_tray.cc index 7f0f394..29ea29f 100644 --- a/ash/system/holding_space/holding_space_tray.cc +++ b/ash/system/holding_space/holding_space_tray.cc
@@ -641,12 +641,20 @@ pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>(); pref_change_registrar_->Init(prefs); - // NOTE: The callback being bound is scoped to `pref_change_registrar_` which - // is owned by `this` so it is safe to bind with an unretained raw pointer. + // NOTE: The binding of these callbacks is scoped to `pref_change_registrar_` + // which is owned by `this` so it is safe to bind with an unretained raw + // pointer. holding_space_prefs::AddPreviewsEnabledChangedCallback( pref_change_registrar_.get(), base::BindRepeating(&HoldingSpaceTray::UpdatePreviewsState, base::Unretained(this))); + holding_space_prefs::AddTimeOfFirstAddChangedCallback( + pref_change_registrar_.get(), base::BindRepeating( + [](HoldingSpaceTray* tray) { + tray->SetShouldAnimate(true); + tray->UpdateVisibility(); + }, + base::Unretained(this))); } void HoldingSpaceTray::UpdatePreviewsState() {
diff --git a/ash/system/model/system_tray_model.h b/ash/system/model/system_tray_model.h index a354cf6..9adaba0 100644 --- a/ash/system/model/system_tray_model.h +++ b/ash/system/model/system_tray_model.h
@@ -88,9 +88,6 @@ std::unique_ptr<TrayNetworkStateModel> network_state_model_; std::unique_ptr<ActiveNetworkIcon> active_network_icon_; - // TODO(tetsui): Add following as a sub-model of SystemTrayModel: - // * BluetoothModel - // Client interface in chrome browser. May be null in tests. SystemTrayClient* client_ = nullptr; };
diff --git a/ash/webui/camera_app_ui/resources/utils/dev/images/camera_app_icons_128.png b/ash/webui/camera_app_ui/resources/utils/dev/images/camera_app_icons_128.png deleted file mode 100644 index 97557c6..0000000 --- a/ash/webui/camera_app_ui/resources/utils/dev/images/camera_app_icons_128.png +++ /dev/null Binary files differ
diff --git a/ash/webui/camera_app_ui/resources/utils/dev/images/camera_app_icons_48.png b/ash/webui/camera_app_ui/resources/utils/dev/images/camera_app_icons_48.png deleted file mode 100644 index 04d1dcfb..0000000 --- a/ash/webui/camera_app_ui/resources/utils/dev/images/camera_app_icons_48.png +++ /dev/null Binary files differ
diff --git a/ash/webui/firmware_update_ui/BUILD.gn b/ash/webui/firmware_update_ui/BUILD.gn index 8452739..4599bf8 100644 --- a/ash/webui/firmware_update_ui/BUILD.gn +++ b/ash/webui/firmware_update_ui/BUILD.gn
@@ -16,6 +16,7 @@ deps = [ "//ash/webui/resources:firmware_update_app_resources", + "//chromeos/strings/", "//content/public/browser", "//ui/resources:webui_generated_resources_grd_grit", "//ui/resources:webui_resources_grd_grit",
diff --git a/ash/webui/firmware_update_ui/firmware_update_app_ui.cc b/ash/webui/firmware_update_ui/firmware_update_app_ui.cc index 4e7f470..301a326c 100644 --- a/ash/webui/firmware_update_ui/firmware_update_app_ui.cc +++ b/ash/webui/firmware_update_ui/firmware_update_app_ui.cc
@@ -7,6 +7,7 @@ #include "ash/grit/ash_firmware_update_app_resources.h" #include "ash/grit/ash_firmware_update_app_resources_map.h" #include "ash/webui/firmware_update_ui/url_constants.h" +#include "chromeos/strings/grit/chromeos_strings.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" @@ -30,6 +31,26 @@ IDR_WEBUI_JS_TEST_LOADER_UTIL_JS); } +void AddFirmwareUpdateAppStrings(content::WebUIDataSource* source) { + static constexpr webui::LocalizedString kLocalizedStrings[] = { + {"appTitle", IDS_FIRMWARE_TITLE_TEXT}, + {"criticalUpdate", IDS_FIRMWARE_CRITICAL_UPDATE_TEXT}, + {"prepareDevice", IDS_FIRMWARE_PREPARE_DEVICE_TEXT}, + {"nextButton", IDS_FIRMWARE_NEXT_BUTTON_TEXT}, + {"cancelButton", IDS_FIRMWARE_CANCEL_BUTTON_TEXT}, + {"doneButton", IDS_FIRMWARE_DONE_BUTTON_TEXT}, + {"updateButton", IDS_FIRMWARE_UPDATE_BUTTON_TEXT}, + {"updating", IDS_FIRMWARE_UPDATING_TEXT}, + {"deviceUpToDate", IDS_FIRMWARE_DEVICE_UP_TO_DATE_TEXT}, + {"hasBeenUpdated", IDS_FIRMWARE_HAS_BEEN_UPDATED_TEXT}, + {"updatingInfo", IDS_FIRMWARE_UPDATING_INFO_TEXT}, + {"installing", IDS_FIRMWARE_INSTALLING_TEXT}, + {"upToDate", IDS_FIRMWARE_UP_TO_DATE_TEXT}}; + + source->AddLocalizedStrings(kLocalizedStrings); + source->UseStringsJs(); +} + } // namespace FirmwareUpdateAppUI::FirmwareUpdateAppUI(content::WebUI* web_ui) @@ -46,6 +67,8 @@ SetUpWebUIDataSource(source.get(), resources, IDR_ASH_FIRMWARE_UPDATE_APP_INDEX_HTML); + AddFirmwareUpdateAppStrings(source.get()); + auto* browser_context = web_ui->GetWebContents()->GetBrowserContext(); content::WebUIDataSource::Add(browser_context, source.release()); }
diff --git a/ash/webui/firmware_update_ui/resources/BUILD.gn b/ash/webui/firmware_update_ui/resources/BUILD.gn index c462de7..5e7223f 100644 --- a/ash/webui/firmware_update_ui/resources/BUILD.gn +++ b/ash/webui/firmware_update_ui/resources/BUILD.gn
@@ -75,6 +75,7 @@ ":firmware_update_dialog", ":peripheral_updates_list", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", ] } @@ -82,6 +83,7 @@ deps = [ ":firmware_update_types", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", ] } @@ -111,6 +113,7 @@ deps = [ ":firmware_update_types", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", ] }
diff --git a/ash/webui/firmware_update_ui/resources/firmware_update_app.html b/ash/webui/firmware_update_ui/resources/firmware_update_app.html index dcfd4be..cf8b6493c 100644 --- a/ash/webui/firmware_update_ui/resources/firmware_update_app.html +++ b/ash/webui/firmware_update_ui/resources/firmware_update_app.html
@@ -7,8 +7,7 @@ </style> <div id="container" class="firmware-default-font"> <h1 id="header" class="firmware-header-font"> - <!-- TODO(michaelcheco): i18n string --> - Firmware updates + [[i18n('appTitle')]] </h1> <peripheral-updates-list></peripheral-updates-list> <firmware-update-dialog></firmware-update-dialog>
diff --git a/ash/webui/firmware_update_ui/resources/firmware_update_app.js b/ash/webui/firmware_update_ui/resources/firmware_update_app.js index 7063b1f..5250c4f 100644 --- a/ash/webui/firmware_update_ui/resources/firmware_update_app.js +++ b/ash/webui/firmware_update_ui/resources/firmware_update_app.js
@@ -7,14 +7,27 @@ import './firmware_update_dialog.js'; import './peripheral_updates_list.js'; -import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import './strings.m.js'; + +import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js'; +import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; /** * @fileoverview * 'firmware-update-app' is the main landing page for the firmware * update app. */ -export class FirmwareUpdateAppElement extends PolymerElement { + +/** + * @constructor + * @extends {PolymerElement} + * @implements {I18nBehaviorInterface} + */ +const FirmwareUpdateAppElementBase = + mixinBehaviors([I18nBehavior], PolymerElement); + +/** @polymer */ +export class FirmwareUpdateAppElement extends FirmwareUpdateAppElementBase { static get is() { return 'firmware-update-app'; }
diff --git a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html index 217043ac1..988ba12 100644 --- a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html +++ b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.html
@@ -50,8 +50,7 @@ <cr-dialog id="devicePrepDialog" show-on-attach on-close="closeDialog_"> <div slot="title"> - <!-- TODO(michaelcheco): i18n string --> - Prepare your device + [[i18n('prepareDevice')]] </div> <div slot="body"> <div id="updateInstructions" hidden$="[[!update.updateModeInstructions]]"> @@ -60,14 +59,12 @@ </div> <div slot="button-container"> <cr-button id="cancelButton" on-click="closeDialog_"> - <!-- TODO(michaelcheco): i18n string --> - Cancel + [[i18n('cancelButton')]] </cr-button> <cr-button class="action-button" id="nextButton" on-click="startUpdate_"> - <!-- TODO(michaelcheco): i18n string --> - Next + [[i18n('nextButton')]] </cr-button> </div> </cr-dialog> @@ -80,7 +77,6 @@ </div> <div slot="body"> <div> - <!-- TODO(michaelcheco): i18n string --> [[computeUpdateDialogBodyText_(dialogState)]] </div> </div> @@ -98,8 +94,7 @@ <cr-button class="action-button" on-click="closeDialog_" id="updateDoneButton"> - <!-- TODO(michaelcheco): i18n string --> - Done + [[i18n('doneButton')]] </cr-button> </div> </cr-dialog>
diff --git a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js index 6cd9c0fb..fc69c97f 100644 --- a/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js +++ b/ash/webui/firmware_update_ui/resources/firmware_update_dialog.js
@@ -4,10 +4,12 @@ import './firmware_shared_css.js'; import './firmware_shared_fonts.js'; +import './strings.m.js'; import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; import 'chrome://resources/polymer/v3_0/paper-progress/paper-progress.js'; -import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js'; +import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {FirmwareUpdate, InstallationProgress, UpdateControllerInterface} from './firmware_update_types.js'; import {getUpdateController} from './mojo_interface_provider.js'; @@ -23,7 +25,18 @@ * @fileoverview * 'firmware-update-dialog' displays information related to a firmware update. */ -export class FirmwareUpdateDialogElement extends PolymerElement { + +/** + * @constructor + * @extends {PolymerElement} + * @implements {I18nBehaviorInterface} + */ +const FirmwareUpdateDialogElementBase = + mixinBehaviors([I18nBehavior], PolymerElement); + +/** @polymer */ +export class FirmwareUpdateDialogElement extends + FirmwareUpdateDialogElementBase { static get is() { return 'firmware-update-dialog'; } @@ -156,8 +169,8 @@ */ computeUpdateDialogTitle_() { return this.isUpdateInProgress_() ? - `Updating ${this.update.deviceName}` : - `Your ${this.update.deviceName} is up to date`; + this.i18n('updating', this.update.deviceName) : + this.i18n('deviceUpToDate', this.update.deviceName); } /** @@ -166,9 +179,8 @@ */ computeProgressText_() { if (this.installationProgress && this.installationProgress.percentage) { - return `Installing (${this.computePercentageValue_()})%`; + return this.i18n('installing', this.computePercentageValue_()); } - // TODO(michaelcheco): i18n string. return ''; } @@ -178,14 +190,9 @@ */ computeUpdateDialogBodyText_() { const {deviceName, version} = this.update; - // TODO(michaelcheco): i18n string. return this.dialogState === DialogState.UPDATE_DONE ? - `Firmware ${deviceName} has been updated to version ${version}` : - ` - While updating, you can minimize window but do not unplug your - device. This may take a few minutes and your device might not work - during this update. - `; + this.i18n('hasBeenUpdated', deviceName, version) : + this.i18n('updatingInfo'); } }
diff --git a/ash/webui/firmware_update_ui/resources/update_card.html b/ash/webui/firmware_update_ui/resources/update_card.html index 77e5898a..f4e78d6 100644 --- a/ash/webui/firmware_update_ui/resources/update_card.html +++ b/ash/webui/firmware_update_ui/resources/update_card.html
@@ -26,14 +26,12 @@ <span>[[update.version]]</span> <span id ="priorityText" hidden$="[[!isCriticalUpdate_(update.priority)]]"> - <!-- TODO(michaelcheco): i18n string --> - Critical update + [[i18n('criticalUpdate')]] </span> </div> <div id="description">[[update.description]]</div> </div> <cr-button id="updateButton" on-click="onUpdateButtonClicked_"> - <!-- TODO(michaelcheco): i18n string --> - Update + [[i18n('updateButton')]] </cr-button> </div>
diff --git a/ash/webui/firmware_update_ui/resources/update_card.js b/ash/webui/firmware_update_ui/resources/update_card.js index b16e485b..2340efc 100644 --- a/ash/webui/firmware_update_ui/resources/update_card.js +++ b/ash/webui/firmware_update_ui/resources/update_card.js
@@ -5,15 +5,26 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import './firmware_shared_css.js'; import './firmware_shared_fonts.js'; +import './strings.m.js'; -import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js'; +import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {FirmwareUpdate, UpdatePriority} from './firmware_update_types.js'; /** * @fileoverview * 'update-card' displays information about a peripheral update. */ -export class UpdateCardElement extends PolymerElement { + +/** + * @constructor + * @extends {PolymerElement} + * @implements {I18nBehaviorInterface} + */ +const UpdateCardElementBase = mixinBehaviors([I18nBehavior], PolymerElement); + +/** @polymer */ +export class UpdateCardElement extends UpdateCardElementBase { static get is() { return 'update-card'; }
diff --git a/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.cc b/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.cc index d282b57b..30bc737 100644 --- a/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.cc +++ b/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.cc
@@ -19,6 +19,8 @@ #include "chromeos/dbus/cros_healthd/cros_healthd_client.h" #include "chromeos/dbus/cros_healthd/fake_cros_healthd_client.h" +namespace ash { + namespace { // Folder containing the resources for JS browser tests. @@ -40,8 +42,8 @@ } // namespace TelemetryExtensionUiBrowserTest::TelemetryExtensionUiBrowserTest() - : SandboxedWebUiAppTestBase(ash::kChromeUITelemetryExtensionURL, - ash::kChromeUIUntrustedTelemetryExtensionURL, + : SandboxedWebUiAppTestBase(kChromeUITelemetryExtensionURL, + kChromeUIUntrustedTelemetryExtensionURL, {base::FilePath(kUntrustedTestHandlers), base::FilePath(kUntrustedTestUtils), base::FilePath(kUntrustedTestCases)}) {} @@ -528,3 +530,5 @@ system_events_weak_ptr_factory_.GetWeakPtr(), callback), base::Seconds(1)); } + +} // namespace ash
diff --git a/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.h b/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.h index e8de57a..0a1f048f 100644 --- a/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.h +++ b/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.h
@@ -10,6 +10,8 @@ #include "base/command_line.h" #include "base/memory/weak_ptr.h" +namespace ash { + class TelemetryExtensionUiBrowserTest : public SandboxedWebUiAppTestBase { public: TelemetryExtensionUiBrowserTest(); @@ -52,4 +54,6 @@ system_events_weak_ptr_factory_{this}; }; +} // namespace ash + #endif // ASH_WEBUI_TELEMETRY_EXTENSION_UI_TEST_TELEMETRY_EXTENSION_UI_BROWSERTEST_H_
diff --git a/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.js b/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.js index 4df75691..95aecedd 100644 --- a/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.js +++ b/ash/webui/telemetry_extension_ui/test/telemetry_extension_ui_browsertest.js
@@ -29,12 +29,12 @@ /** @override */ get featureList() { - return {enabled: ['chromeos::features::kTelemetryExtension']}; + return {enabled: ['ash::features::kTelemetryExtension']}; } /** @override */ get typedefCppFixture() { - return 'TelemetryExtensionUiBrowserTest'; + return 'ash::TelemetryExtensionUiBrowserTest'; } /** @override */
diff --git a/base/allocator/partition_allocator/starscan/pcscan_internal.cc b/base/allocator/partition_allocator/starscan/pcscan_internal.cc index da00b6f..045e26f 100644 --- a/base/allocator/partition_allocator/starscan/pcscan_internal.cc +++ b/base/allocator/partition_allocator/starscan/pcscan_internal.cc
@@ -51,6 +51,16 @@ #include "base/time/time.h" #include "build/build_config.h" +// TODO(bikineev): Temporarily disable inlining in *Scan to get clearer +// stacktraces. +#define PA_STARSCAN_NOINLINE_SCAN_FUNCTIONS + +#if defined(PA_STARSCAN_NOINLINE_SCAN_FUNCTIONS) +#define PA_SCAN_INLINE NOINLINE +#else +#define PA_SCAN_INLINE ALWAYS_INLINE +#endif + namespace base { namespace internal { @@ -181,7 +191,7 @@ // // |maybe_inner_ptr| must be within a normal-bucket super page and can also // point to guard pages or slot-span metadata. -ALWAYS_INLINE GetSlotStartResult +PA_SCAN_INLINE GetSlotStartResult GetSlotStartInSuperPage(uintptr_t maybe_inner_ptr) { char* maybe_inner_ptr_as_char_ptr = reinterpret_cast<char*>(maybe_inner_ptr); PA_SCAN_DCHECK(IsManagedByNormalBuckets(maybe_inner_ptr_as_char_ptr)); @@ -536,12 +546,12 @@ friend class base::RefCountedThreadSafe<PCScanTask>; ~PCScanTask() = default; - ALWAYS_INLINE AllocationStateMap* TryFindScannerBitmapForPointer( + PA_SCAN_INLINE AllocationStateMap* TryFindScannerBitmapForPointer( uintptr_t maybe_ptr) const; // Lookup and marking functions. Return size of the object if marked or zero // otherwise. - ALWAYS_INLINE size_t TryMarkObjectInNormalBuckets(uintptr_t maybe_ptr) const; + PA_SCAN_INLINE size_t TryMarkObjectInNormalBuckets(uintptr_t maybe_ptr) const; // Scans stack, only called from safepoints. void ScanStack(); @@ -588,7 +598,7 @@ PCScan& pcscan_; }; -ALWAYS_INLINE AllocationStateMap* PCScanTask::TryFindScannerBitmapForPointer( +PA_SCAN_INLINE AllocationStateMap* PCScanTask::TryFindScannerBitmapForPointer( uintptr_t maybe_ptr) const { PA_SCAN_DCHECK( IsManagedByPartitionAllocRegularPool(reinterpret_cast<void*>(maybe_ptr))); @@ -632,7 +642,7 @@ // TryMarkObjectInNormalBuckets() marks it again in the bitmap and clears // from the scanner bitmap. This way, when scanning is done, all uncleared // entries in the scanner bitmap correspond to unreachable objects. -ALWAYS_INLINE size_t +PA_SCAN_INLINE size_t PCScanTask::TryMarkObjectInNormalBuckets(uintptr_t maybe_ptr) const { // Check if |maybe_ptr| points somewhere to the heap. auto* state_map = TryFindScannerBitmapForPointer(maybe_ptr); @@ -760,7 +770,7 @@ #endif } - ALWAYS_INLINE void CheckPointer(uintptr_t maybe_ptr) { + PA_SCAN_INLINE void CheckPointer(uintptr_t maybe_ptr) { quarantine_size_ += task_.TryMarkObjectInNormalBuckets(memory::UnmaskPtr(maybe_ptr)); }
diff --git a/base/android/reached_addresses_bitset.cc b/base/android/reached_addresses_bitset.cc index 295635b..789ccda 100644 --- a/base/android/reached_addresses_bitset.cc +++ b/base/android/reached_addresses_bitset.cc
@@ -14,18 +14,35 @@ namespace { constexpr size_t kBitsPerElement = sizeof(uint32_t) * 8; -#if BUILDFLAG(SUPPORTS_CODE_ORDERING) +// Below an array of uint32_t in BSS is introduced and then casted to an array +// of std::atomic<uint32_t>. In C++20 constructing an std::atomic is not +// 'trivial'. See https://github.com/microsoft/STL/issues/661 for reasons of +// this change in the standard. +// +// Assert that both types have the same size. The sizes do not have to match +// according to a note in [atomics.types.generic] in C++17. With this assertion +// in place it is unlikely that the constructor produces the value other than +// (uint32_t)0. +static_assert(sizeof(uint32_t) == sizeof(std::atomic<uint32_t>), ""); + +// Keep the array in BSS only for non-official builds to avoid potential harm to +// data locality and unspecified behavior from the reinterpret_cast below. In +// order to start new experiments with base::Feature(ReachedCodeProfiler) on +// Canary/Dev this array will need to be reintroduced to official builds. +#if BUILDFLAG(SUPPORTS_CODE_ORDERING) && !defined(OFFICIAL_BUILD) // Enough for 1 << 29 bytes of code, 512MB. constexpr size_t kTextBitfieldSize = 1 << 20; -std::atomic<uint32_t> g_text_bitfield[kTextBitfieldSize]; +uint32_t g_text_bitfield[kTextBitfieldSize]; #endif } // namespace // static ReachedAddressesBitset* ReachedAddressesBitset::GetTextBitset() { -#if BUILDFLAG(SUPPORTS_CODE_ORDERING) - static ReachedAddressesBitset text_bitset(kStartOfText, kEndOfText, - g_text_bitfield, kTextBitfieldSize); +#if BUILDFLAG(SUPPORTS_CODE_ORDERING) && !defined(OFFICIAL_BUILD) + static ReachedAddressesBitset text_bitset( + kStartOfText, kEndOfText, + reinterpret_cast<std::atomic<uint32_t>*>(g_text_bitfield), + kTextBitfieldSize); return &text_bitset; #else return nullptr;
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 846c419..76b9c19 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -7.20211117.2.1 +7.20211117.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 846c419..76b9c19 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -7.20211117.2.1 +7.20211117.3.1
diff --git a/chrome/VERSION b/chrome/VERSION index ffcff76d..1840b97a 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=98 MINOR=0 -BUILD=4712 +BUILD=4713 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java b/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java index 9fcc220..3a43e56f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.init; import android.content.Intent; +import android.os.SystemClock; import android.text.TextUtils; import androidx.annotation.VisibleForTesting; @@ -39,7 +40,8 @@ * This class attempts to preload the tab if the url is known from the intent when the profile * is created. This is done to improve startup latency. */ -public class StartupTabPreloader implements ProfileManager.Observer, DestroyObserver { +public class StartupTabPreloader implements ProfileManager.Observer, DestroyObserver, + ActivityTabStartupMetricsTracker.Observer { public static final String EXTRA_DISABLE_STARTUP_TAB_PRELOADER = "org.chromium.chrome.browser.init.DISABLE_STARTUP_TAB_PRELOADER"; private static boolean sFailNextTabMatchForTesting; @@ -54,6 +56,12 @@ private StartupTabObserver mObserver; private ActivityTabStartupMetricsTracker mStartupMetricsTracker; + // The time at which the tab preload decision was made. Recorded only for non-incognito + // startups. + private long mLoadDecisionMs; + // Records whether a preload was triggered. + boolean mTriggerPreload; + public static void failNextTabMatchForTesting() { sFailNextTabMatchForTesting = true; } @@ -71,6 +79,7 @@ mActivityLifecycleDispatcher.register(this); ProfileManager.addObserver(this); + ActivityTabStartupMetricsTracker.addObserver(this); } @Override @@ -79,9 +88,23 @@ mTab = null; ProfileManager.removeObserver(this); + ActivityTabStartupMetricsTracker.removeObserver(this); mActivityLifecycleDispatcher.unregister(this); } + @Override + public void onFirstNavigationStart() { + if (mLoadDecisionMs == 0) return; + + long currentTimeMs = SystemClock.uptimeMillis(); + long triggerpointToFirstNavigationStartMs = currentTimeMs - mLoadDecisionMs; + + String suffix = mTriggerPreload ? ".Load" : ".NoLoad"; + RecordHistogram.recordMediumTimesHistogram( + "Android.StartupTabPreloader.LoadDecisionToFirstNavigationStart" + suffix, + triggerpointToFirstNavigationStartMs); + } + /** * Returns the Tab if loadUrlParams and type match, otherwise the Tab is discarded. * @@ -145,10 +168,11 @@ if (profile.isOffTheRecord()) return; ProfileManager.removeObserver(this); - boolean shouldLoad = shouldLoadTab(); - if (shouldLoad) loadTab(); + mTriggerPreload = shouldLoadTab(); + mLoadDecisionMs = SystemClock.uptimeMillis(); + if (mTriggerPreload) loadTab(); RecordHistogram.recordBooleanHistogram( - "Startup.Android.StartupTabPreloader.TabLoaded", shouldLoad); + "Startup.Android.StartupTabPreloader.TabLoaded", mTriggerPreload); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java index 18cc0713..4631a400 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java
@@ -6,6 +6,8 @@ import android.os.SystemClock; +import org.chromium.base.ObserverList; +import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.browser.paint_preview.StartupPaintPreviewHelper; @@ -25,11 +27,37 @@ public class ActivityTabStartupMetricsTracker { private static final String UMA_HISTOGRAM_TABBED_SUFFIX = ".Tabbed"; + /** Observer for startup metrics. */ + public interface Observer { + /** + * Called when the initial navigation upon startup is started. This will be fired at most + * once. + */ + void onFirstNavigationStart(); + } + + private static ObserverList<Observer> sObservers; + + /** Adds an observer. */ + public static boolean addObserver(Observer observer) { + ThreadUtils.assertOnUiThread(); + if (sObservers == null) sObservers = new ObserverList<>(); + return sObservers.addObserver(observer); + } + + /** Removes an observer. */ + public static boolean removeObserver(Observer observer) { + ThreadUtils.assertOnUiThread(); + if (sObservers == null) return false; + return sObservers.removeObserver(observer); + } + private class PageLoadMetricsObserverImpl implements PageLoadMetrics.Observer { private static final long NO_NAVIGATION_ID = -1; private long mNavigationId = NO_NAVIGATION_ID; private boolean mShouldRecordHistograms; + private boolean mInvokedOnFirstNavigationStart; @Override public void onNewNavigation(WebContents webContents, long navigationId, @@ -38,6 +66,13 @@ mNavigationId = navigationId; mShouldRecordHistograms = mShouldTrackStartupMetrics; + + if (!mInvokedOnFirstNavigationStart) { + for (Observer observer : sObservers) { + observer.onFirstNavigationStart(); + } + mInvokedOnFirstNavigationStart = true; + } } @Override @@ -48,7 +83,9 @@ recordFirstContentfulPaint(navigationStartTick / 1000 + firstContentfulPaintMs); } - void reset() { + void resetMetricsRecordingStateForInitialNavigation() { + // NOTE: |mInvokedOnFirstNavigationStart| is intentionally not reset to avoid duplicate + // observer notifications. mNavigationId = NO_NAVIGATION_ID; mShouldRecordHistograms = false; } @@ -128,7 +165,7 @@ // Note that observers are not created in all contexts (e.g., CCT). if (mPageLoadMetricsObserver == null) return; - mPageLoadMetricsObserver.reset(); + mPageLoadMetricsObserver.resetMetricsRecordingStateForInitialNavigation(); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivitySigninAndSyncTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivitySigninAndSyncTest.java index 6e92cc0..8c4a6bb 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivitySigninAndSyncTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivitySigninAndSyncTest.java
@@ -31,6 +31,7 @@ import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; @@ -70,6 +71,9 @@ new DisableAnimationsTestRule(); @Rule + public final TestRule mCommandLindFlagRule = CommandLineFlags.getTestRule(); + + @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Rule
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 e6bf5ee4..f35c7e4 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
@@ -112,6 +112,9 @@ @Rule public JniMocker mJniMocker = new JniMocker(); + @Rule + public TestRule mCommandLineFlagsRule = CommandLineFlags.getTestRule(); + @Mock public FirstRunAppRestrictionInfo mMockAppRestrictionInfo; @Mock
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java index 32470417..833e5ac 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java
@@ -31,6 +31,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; @@ -109,6 +110,8 @@ .setRevision(RENDER_TEST_REVISION) .setDescription(RENDER_TEST_REVISION_DESCRIPTION) .build(); + @Rule + public TestRule mCommandLineFlagsRule = CommandLineFlags.getTestRule(); @Mock public FirstRunAppRestrictionInfo mMockAppRestrictionInfo;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java index 13fd5d7c..99bac902 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java
@@ -52,6 +52,10 @@ "Startup.Android.Cold.TimeToFirstVisibleContent"; private static final String VISIBLE_CONTENT_HISTOGRAM = "Startup.Android.Cold.TimeToVisibleContent"; + private static final String PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_PRELOAD = + "Android.StartupTabPreloader.LoadDecisionToFirstNavigationStart.Load"; + private static final String PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_NO_PRELOAD = + "Android.StartupTabPreloader.LoadDecisionToFirstNavigationStart.NoLoad"; @Rule public ChromeTabbedActivityTestRule mActivityRule = new ChromeTabbedActivityTestRule(); @@ -105,6 +109,14 @@ RecordHistogram.getHistogramTotalCountForTesting(FIRST_VISIBLE_CONTENT_HISTOGRAM)); Assert.assertEquals( 1, RecordHistogram.getHistogramTotalCountForTesting(VISIBLE_CONTENT_HISTOGRAM)); + + // Startup tab preload-specific startup metrics should also have been recorded. + Assert.assertEquals(1, + RecordHistogram.getHistogramTotalCountForTesting( + PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_PRELOAD)); + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_NO_PRELOAD)); } @Test @@ -140,6 +152,54 @@ RecordHistogram.getHistogramTotalCountForTesting(FIRST_VISIBLE_CONTENT_HISTOGRAM)); Assert.assertEquals( 1, RecordHistogram.getHistogramTotalCountForTesting(VISIBLE_CONTENT_HISTOGRAM)); + + // Startup tab preload-specific startup metrics should also have been recorded. + Assert.assertEquals(1, + RecordHistogram.getHistogramTotalCountForTesting( + PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_PRELOAD)); + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_NO_PRELOAD)); + } + + @Test + @LargeTest + @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP) + public void testStartupTabPreloaderStartupLoadingMetricsRecordedWhenTabNotPreloaded() + throws Exception { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + intent.putExtra(StartupTabPreloader.EXTRA_DISABLE_STARTUP_TAB_PRELOADER, true); + mActivityRule.startMainActivityFromIntent( + intent, mServerRule.getServer().getURL(TEST_PAGE)); + + // The StartupTabPreloader should not have loaded a url. + Assert.assertEquals( + 0, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1)); + Assert.assertEquals( + 0, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1)); + + // First contentful paint should be recorded. + CriteriaHelper.pollUiThread(() + -> RecordHistogram.getHistogramTotalCountForTesting( + FIRST_CONTENTFUL_PAINT_HISTOGRAM) + == 1); + // First contentful paint is the last startup metric to be recorded, so the other startup + // metrics should also have been recorded at this point. + Assert.assertEquals( + 1, RecordHistogram.getHistogramTotalCountForTesting(FIRST_COMMIT_HISTOGRAM)); + Assert.assertEquals(1, + RecordHistogram.getHistogramTotalCountForTesting(FIRST_VISIBLE_CONTENT_HISTOGRAM)); + Assert.assertEquals( + 1, RecordHistogram.getHistogramTotalCountForTesting(VISIBLE_CONTENT_HISTOGRAM)); + + // Startup tab preload-specific startup metrics should also have been recorded. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_PRELOAD)); + Assert.assertEquals(1, + RecordHistogram.getHistogramTotalCountForTesting( + PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_NO_PRELOAD)); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java index 6ac908a..876be01 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java
@@ -16,6 +16,7 @@ import org.junit.runner.RunWith; import org.chromium.base.Callback; +import org.chromium.base.ThreadUtils; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.IntentHandler; @@ -176,6 +177,10 @@ private StartupTabPreloader createStartupTabPreloader( Intent intent, TabCreatorManager tabCreatorManager) { + // StartupTabPreloader calls into code that asserts that it is on the UI thread, which + // doesn't exist in this unittesting context. + ThreadUtils.setThreadAssertsDisabledForTesting(true); + return new StartupTabPreloader( new Supplier<Intent>() { @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java index 898ae503..99a85711 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java
@@ -39,6 +39,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; @@ -111,6 +112,9 @@ } @Rule + public final TestRule mCommandLindFlagRule = CommandLineFlags.getTestRule(); + + @Rule public final DisableAnimationsTestRule mNoAnimationsRule = new DisableAnimationsTestRule(); @Rule
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 069b3fb..c4f1980f 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -4055,12 +4055,6 @@ <message name="IDS_LACROS_DATA_MIGRATION_SCREEN_SUBTITLE" desc="Shows the % of progress."> <ph name="PERCENT">$1<ex>100</ex></ph>% completed </message> - <message name="IDS_LACROS_DATA_MIGRATION_SCREEN_SKIP_BUTTON" desc="Skip button for data migration."> - Skip - </message> - <message name="IDS_LACROS_DATA_MIGRATION_SCREEN_SKIP_SUGGESTION" desc="Message shown when skip button is visible."> - This is taking longer than expected, you can skip or wait until it's done. - </message> <!-- Print Job Notification --> <message name="IDS_PRINT_JOB_NOTIFICATION_DISPLAY_SOURCE" desc="The context title of printing notification.">
diff --git a/chrome/app/chromeos_strings_grdp/IDS_LACROS_DATA_MIGRATION_SCREEN_SKIP_BUTTON.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_LACROS_DATA_MIGRATION_SCREEN_SKIP_BUTTON.png.sha1 deleted file mode 100644 index ab72be9..0000000 --- a/chrome/app/chromeos_strings_grdp/IDS_LACROS_DATA_MIGRATION_SCREEN_SKIP_BUTTON.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -362e221fcf529324e0e6fa25e2790fc5e6b70f26 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_LACROS_DATA_MIGRATION_SCREEN_SKIP_SUGGESTION.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_LACROS_DATA_MIGRATION_SCREEN_SKIP_SUGGESTION.png.sha1 deleted file mode 100644 index ab72be9..0000000 --- a/chrome/app/chromeos_strings_grdp/IDS_LACROS_DATA_MIGRATION_SCREEN_SKIP_SUGGESTION.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -362e221fcf529324e0e6fa25e2790fc5e6b70f26 \ No newline at end of file
diff --git a/chrome/app/os_settings_search_tag_strings.grdp b/chrome/app/os_settings_search_tag_strings.grdp index 603123c..66a04d8 100644 --- a/chrome/app/os_settings_search_tag_strings.grdp +++ b/chrome/app/os_settings_search_tag_strings.grdp
@@ -1054,6 +1054,18 @@ <message name="IDS_OS_SETTINGS_TAG_PRIVACY_PERIPHERAL_DATA_ACCESS_PROTECTION_ALT5" desc="Text for search result item which, when clicked, navigates the user to privacy settings, with a toggle to enable/disable peripheral data access protection. Alternate phrase for: 'Data access protection for peripherals', 'PCIe', 'Thunderbolt', 'USB', 'USB4'"> USB-C </message> + <message name="IDS_OS_SETTINGS_TAG_SMART_PRIVACY" desc="Text for search result item which, when clicked, navigates the user to the smart privacy subpage." translateable="false"> + Smart privacy protections + </message> + <message name="IDS_OS_SETTINGS_TAG_SMART_PRIVACY_SNOOPING" desc="Text for search result item which, when clicked, navigates the user to the smart privacy subpage with a toggle to enable/disable snooping protection. Alternate phrase for: 'Shoulder surfing', 'Peeking'" translateable="false"> + Snooping protection + </message> + <message name="IDS_OS_SETTINGS_TAG_SMART_PRIVACY_SNOOPING_ALT1" desc="Text for search result item which, when clicked, navigates the user to the smart privacy subpage with a toggle to enable/disable snooping protection. Alternate phrase for: 'Snooping protection', 'Peeking'" translateable="false"> + Shoulder surfing + </message> + <message name="IDS_OS_SETTINGS_TAG_SMART_PRIVACY_SNOOPING_ALT2" desc="Text for search result item which, when clicked, navigates the user to the smart privacy subpage with a toggle to enable/disable snooping protection. Alternate phrase for: 'Snooping protection', 'Shoulder surfing'" translateable="false"> + Peeking + </message> <!-- Languages and Input section. --> <message name="IDS_OS_SETTINGS_TAG_LANGUAGES" desc="Text for search result item which, when clicked, navigates the user to languages settings."> @@ -1342,6 +1354,9 @@ <message name="IDS_OS_SETTINGS_TAG_ABOUT_DIAGNOSTICS_ALT4" desc="Text for search result item which, when clicked, navigates the user to 'Diagnostics' settings, with a link which opens the Diagnostics App. Alternate phrase for 'Diagnostics', 'Troubleshooting', 'Battery Health', 'CPU Usage'"> Memory Usage </message> + <message name="IDS_OS_SETTINGS_TAG_ABOUT_FIRMWARE_UPDATES" desc="Text for search result item which, when clicked, navigates the user to 'Firmware updates' settings, with a link which opens the 'Firmware updates' app."> + Firmware updates + </message> <!-- On Startup section. --> <message name="IDS_OS_SETTINGS_TAG_ON_STARTUP" desc="Text for search result item which, when clicked, navigates the user to On Startup settings, with a radio group to configure the restore apps and pages options">
diff --git a/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_ABOUT_FIRMWARE_UPDATES.png.sha1 b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_ABOUT_FIRMWARE_UPDATES.png.sha1 new file mode 100644 index 0000000..4b52655 --- /dev/null +++ b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_ABOUT_FIRMWARE_UPDATES.png.sha1
@@ -0,0 +1 @@ +6ff1935e71886889be4b509739bc14c0762c0913 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 16a66656..ce609aa0 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -222,6 +222,9 @@ <message name="IDS_SETTINGS_ABOUT_PAGE_DIAGNOSTICS" desc="Text of the button which allows the user to diagnose their device."> Diagnostics </message> + <message name="IDS_SETTINGS_ABOUT_PAGE_FIRMWARE_UPDATES" desc="Text of the button for the surface which allows users to update all their peripheral firmwares in one place."> + Firmware updates + </message> <!-- People (OS settings) --> <message name="IDS_OS_SETTINGS_PROFILE_NAME" desc="Label with device account first name, showing which user is currently signed in.">
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_FIRMWARE_UPDATES.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_FIRMWARE_UPDATES.png.sha1 new file mode 100644 index 0000000..4f7cf3e --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_FIRMWARE_UPDATES.png.sha1
@@ -0,0 +1 @@ +ed4b095a8d3ce79314a8e45bc31b025bfb7595cd \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 62e39820..5b95192 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3621,6 +3621,7 @@ "apps/app_service/extension_uninstaller.h", "apps/app_service/intent_util.cc", "apps/app_service/intent_util.h", + "apps/app_service/launch_result_type.h", "apps/app_service/launch_utils.cc", "apps/app_service/launch_utils.h", "apps/app_service/metrics/app_service_metrics.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index ea6e7d7..87f512a3 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4425,6 +4425,9 @@ {"files-banner-framework", flag_descriptions::kFilesBannerFrameworkName, flag_descriptions::kFilesBannerFrameworkDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kFilesBannerFramework)}, + {"files-extract-archive", flag_descriptions::kFilesExtractArchiveName, + flag_descriptions::kFilesExtractArchiveDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kFilesExtractArchive)}, {"files-filters-in-recents", flag_descriptions::kFiltersInRecentsName, flag_descriptions::kFiltersInRecentsDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kFiltersInRecents)}, @@ -4438,9 +4441,6 @@ {"files-trash", flag_descriptions::kFilesTrashName, flag_descriptions::kFilesTrashDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kFilesTrash)}, - {"files-zip-unpack", flag_descriptions::kFilesZipUnpackName, - flag_descriptions::kFilesZipUnpackDescription, kOsCrOS, - FEATURE_VALUE_TYPE(chromeos::features::kFilesZipUnpack)}, {"force-spectre-v2-mitigation", flag_descriptions::kForceSpectreVariant2MitigationName, flag_descriptions::kForceSpectreVariant2MitigationDescription, kOsCrOS, @@ -5290,10 +5290,6 @@ FEATURE_VALUE_TYPE(commerce::kShoppingList)}, #endif // OS_ANDROID - {"enable-layout-ng", flag_descriptions::kEnableLayoutNGName, - flag_descriptions::kEnableLayoutNGDescription, kOsAll, - FEATURE_VALUE_TYPE(blink::features::kLayoutNG)}, - {"enable-lazy-image-loading", flag_descriptions::kEnableLazyImageLoadingName, flag_descriptions::kEnableLazyImageLoadingDescription, kOsAll,
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.cc b/chrome/browser/apps/app_service/app_service_proxy_base.cc index 2a30bf2..c148e2f 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_base.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_base.cc
@@ -15,6 +15,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_source.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/launch_utils.h" #include "chrome/browser/apps/app_service/metrics/app_service_metrics.h" #include "chrome/browser/ash/file_manager/app_id.h" @@ -364,6 +365,18 @@ launch_source, std::move(window_info)); } +void AppServiceProxyBase::LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) { + auto app_type = ConvertMojomAppTypToAppType( + app_registry_cache_.GetAppType(params.app_id)); + auto* publisher = GetPublisher(app_type); + if (!publisher) { + std::move(callback).Run(LaunchResult()); + return; + } + publisher->LaunchAppWithParams(std::move(params), std::move(callback)); +} + void AppServiceProxyBase::SetPermission(const std::string& app_id, apps::mojom::PermissionPtr permission) { if (app_service_.is_connected()) {
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.h b/chrome/browser/apps/app_service/app_service_proxy_base.h index 473ab1d..eae5ae6 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_base.h +++ b/chrome/browser/apps/app_service/app_service_proxy_base.h
@@ -16,6 +16,7 @@ #include "base/memory/weak_ptr.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/apps/app_service/browser_app_launcher.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "components/keyed_service/core/keyed_service.h" #include "components/services/app_service/public/cpp/app_capability_access_cache.h" @@ -38,6 +39,8 @@ class AppServiceMojomImpl; +struct AppLaunchParams; + struct IntentLaunchInfo { IntentLaunchInfo(); ~IntentLaunchInfo(); @@ -156,6 +159,11 @@ apps::mojom::LaunchSource launch_source, apps::mojom::WindowInfoPtr window_info = nullptr); + // Launches an app for the given |params.app_id|. The |params| can also + // contain other param such as launch container, window diposition, etc. + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback = base::DoNothing()); + // Sets |permission| for the app identified by |app_id|. void SetPermission(const std::string& app_id, apps::mojom::PermissionPtr permission);
diff --git a/chrome/browser/apps/app_service/app_service_proxy_lacros.cc b/chrome/browser/apps/app_service/app_service_proxy_lacros.cc index d4499e0..a36e272e1 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_lacros.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_lacros.cc
@@ -14,6 +14,7 @@ #include "base/notreached.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_source.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/browser_app_instance_forwarder.h" #include "chrome/browser/apps/app_service/browser_app_instance_tracker.h" #include "chrome/browser/apps/app_service/intent_util.h" @@ -344,6 +345,12 @@ launch_source, std::move(window_info)); } +void AppServiceProxyLacros::LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) { + // TODO(crbug.com/1244506): Add params on crosapi and implement this. + std::move(callback).Run(LaunchResult()); +} + void AppServiceProxyLacros::SetPermission( const std::string& app_id, apps::mojom::PermissionPtr permission) {
diff --git a/chrome/browser/apps/app_service/app_service_proxy_lacros.h b/chrome/browser/apps/app_service/app_service_proxy_lacros.h index 3dd4f95..3c25a040 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_lacros.h +++ b/chrome/browser/apps/app_service/app_service_proxy_lacros.h
@@ -14,6 +14,7 @@ #include "base/memory/weak_ptr.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/apps/app_service/browser_app_launcher.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chromeos/crosapi/mojom/app_service.mojom.h" #include "components/keyed_service/core/keyed_service.h" #include "components/services/app_service/public/cpp/app_capability_access_cache.h" @@ -44,6 +45,8 @@ class BrowserAppInstanceForwarder; class BrowserAppInstanceTracker; +struct AppLaunchParams; + struct IntentLaunchInfo { std::string app_id; std::string activity_name; @@ -148,6 +151,11 @@ apps::mojom::LaunchSource launch_source, apps::mojom::WindowInfoPtr window_info = nullptr); + // Launches an app for the given |params.app_id|. The |params| can also + // contain other param such as launch container, window diposition, etc. + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback = base::DoNothing()); + // Sets |permission| for the app identified by |app_id|. void SetPermission(const std::string& app_id, apps::mojom::PermissionPtr permission);
diff --git a/chrome/browser/apps/app_service/launch_result_type.h b/chrome/browser/apps/app_service/launch_result_type.h new file mode 100644 index 0000000..0f4ce463 --- /dev/null +++ b/chrome/browser/apps/app_service/launch_result_type.h
@@ -0,0 +1,23 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_APPS_APP_SERVICE_LAUNCH_RESULT_TYPE_H_ +#define CHROME_BROWSER_APPS_APP_SERVICE_LAUNCH_RESULT_TYPE_H_ + +#include "base/callback_forward.h" +#include "base/unguessable_token.h" + +namespace apps { +// LaunchResult, and LaunchCallback can be used in Chrome Ash, lacros, and other +// desktop platforms. So this struct can't be moved to AppPublisher. + +struct LaunchResult { + base::UnguessableToken instance_id; +}; + +using LaunchCallback = base::OnceCallback<void(LaunchResult&&)>; + +} // namespace apps + +#endif // CHROME_BROWSER_APPS_APP_SERVICE_LAUNCH_RESULT_TYPE_H_
diff --git a/chrome/browser/apps/app_service/publishers/app_publisher.h b/chrome/browser/apps/app_service/publishers/app_publisher.h index 3737567..b3024d8 100644 --- a/chrome/browser/apps/app_service/publishers/app_publisher.h +++ b/chrome/browser/apps/app_service/publishers/app_publisher.h
@@ -10,6 +10,7 @@ #include <vector> #include "chrome/browser/apps/app_service/app_service_proxy_forward.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/icon_types.h" @@ -17,12 +18,6 @@ struct AppLaunchParams; -struct LaunchResult { - base::UnguessableToken instance_id; -}; - -using LaunchCallback = base::OnceCallback<void(LaunchResult&&)>; - // AppPublisher parent class (in the App Service sense) for all app publishers. // See components/services/app_service/README.md. //
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.h b/chrome/browser/apps/app_service/publishers/arc_apps.h index 82c84e4..161e6b77 100644 --- a/chrome/browser/apps/app_service/publishers/arc_apps.h +++ b/chrome/browser/apps/app_service/publishers/arc_apps.h
@@ -24,6 +24,7 @@ #include "chrome/browser/apps/app_service/app_notifications.h" #include "chrome/browser/apps/app_service/app_service_proxy_forward.h" #include "chrome/browser/apps/app_service/app_shortcut_item.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/paused_apps.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "chrome/browser/ash/arc/app_shortcuts/arc_app_shortcuts_request.h"
diff --git a/chrome/browser/apps/app_service/publishers/borealis_apps.h b/chrome/browser/apps/app_service/publishers/borealis_apps.h index afec6c2..55e47a99 100644 --- a/chrome/browser/apps/app_service/publishers/borealis_apps.h +++ b/chrome/browser/apps/app_service/publishers/borealis_apps.h
@@ -11,6 +11,7 @@ #include "base/scoped_observation.h" #include "chrome/browser/apps/app_service/app_icon/icon_key_util.h" #include "chrome/browser/apps/app_service/app_service_proxy_forward.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "chrome/browser/ash/borealis/borealis_window_manager.h" #include "chrome/browser/ash/guest_os/guest_os_registry_service.h"
diff --git a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h index 96990d0..bdcbb1e 100644 --- a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h +++ b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h
@@ -8,6 +8,7 @@ #include <string> #include "chrome/browser/apps/app_service/app_service_proxy_forward.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "components/services/app_service/public/cpp/publisher_base.h" #include "components/services/app_service/public/mojom/app_service.mojom.h"
diff --git a/chrome/browser/apps/app_service/publishers/crostini_apps.h b/chrome/browser/apps/app_service/publishers/crostini_apps.h index ed8c3a51c..a1ea72b 100644 --- a/chrome/browser/apps/app_service/publishers/crostini_apps.h +++ b/chrome/browser/apps/app_service/publishers/crostini_apps.h
@@ -13,6 +13,7 @@ #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h" #include "chrome/browser/apps/app_service/app_icon/icon_key_util.h" #include "chrome/browser/apps/app_service/app_service_proxy_forward.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "chrome/browser/ash/guest_os/guest_os_registry_service.h" #include "components/keyed_service/core/keyed_service.h"
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_base.h b/chrome/browser/apps/app_service/publishers/extension_apps_base.h index b5d59e3..5fd62a2 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_base.h +++ b/chrome/browser/apps/app_service/publishers/extension_apps_base.h
@@ -13,6 +13,7 @@ #include "base/scoped_observation.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h" #include "chrome/browser/apps/app_service/app_icon/icon_key_util.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "components/services/app_service/public/cpp/publisher_base.h" #include "components/services/app_service/public/mojom/app_service.mojom.h"
diff --git a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h index d9409eb..83a0d87b 100644 --- a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h +++ b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h
@@ -9,6 +9,7 @@ #include <string> #include "chrome/browser/apps/app_service/app_icon/icon_key_util.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "chrome/browser/ash/guest_os/guest_os_registry_service.h" #include "chrome/browser/ash/plugin_vm/plugin_vm_manager.h"
diff --git a/chrome/browser/apps/app_service/publishers/remote_apps.h b/chrome/browser/apps/app_service/publishers/remote_apps.h index a07fc6a..34b3826 100644 --- a/chrome/browser/apps/app_service/publishers/remote_apps.h +++ b/chrome/browser/apps/app_service/publishers/remote_apps.h
@@ -11,6 +11,7 @@ #include "chrome/browser/apps/app_service/app_icon/icon_key_util.h" #include "chrome/browser/apps/app_service/app_service_proxy_forward.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "chrome/browser/ash/remote_apps/remote_apps_model.h" #include "components/services/app_service/public/cpp/icon_types.h"
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h index d787643..65baa4b 100644 --- a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h +++ b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h
@@ -8,6 +8,7 @@ #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" #include "chrome/browser/apps/app_service/app_icon/icon_key_util.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "chrome/browser/ash/crosapi/browser_manager.h" #include "chrome/browser/ash/crosapi/browser_manager_observer.h"
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h index 4ebe459..9165c0e2 100644 --- a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h +++ b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h
@@ -9,6 +9,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/apps/app_service/app_service_proxy_forward.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "chrome/browser/ash/crosapi/browser_manager.h" #include "chromeos/crosapi/mojom/app_service.mojom.h"
diff --git a/chrome/browser/apps/app_service/publishers/web_apps_crosapi.h b/chrome/browser/apps/app_service/publishers/web_apps_crosapi.h index 618cca59..8e490db 100644 --- a/chrome/browser/apps/app_service/publishers/web_apps_crosapi.h +++ b/chrome/browser/apps/app_service/publishers/web_apps_crosapi.h
@@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/apps/app_service/app_icon/icon_key_util.h" #include "chrome/browser/apps/app_service/app_service_proxy_forward.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "chromeos/crosapi/mojom/app_service.mojom.h" #include "components/keyed_service/core/keyed_service.h"
diff --git a/chrome/browser/ash/file_manager/file_manager_string_util.cc b/chrome/browser/ash/file_manager/file_manager_string_util.cc index 7f530af..eac875b 100644 --- a/chrome/browser/ash/file_manager/file_manager_string_util.cc +++ b/chrome/browser/ash/file_manager/file_manager_string_util.cc
@@ -976,8 +976,6 @@ base::FeatureList::IsEnabled(chromeos::features::kFilesSWA)); dict->SetBoolKey("FILES_TRASH_ENABLED", base::FeatureList::IsEnabled( chromeos::features::kFilesTrash)); - dict->SetBoolKey("ZIP_UNPACK", base::FeatureList::IsEnabled( - chromeos::features::kFilesZipUnpack)); dict->SetBoolKey( "DRIVE_DSS_PIN_ENABLED", base::FeatureList::IsEnabled( @@ -992,5 +990,9 @@ "FILES_BANNER_FRAMEWORK", base::FeatureList::IsEnabled(chromeos::features::kFilesBannerFramework)); + dict->SetBoolKey( + "EXTRACT_ARCHIVE", + base::FeatureList::IsEnabled(chromeos::features::kFilesExtractArchive)); + dict->SetStringKey("UI_LOCALE", locale); }
diff --git a/chrome/browser/ash/input_method/assistive_suggester.cc b/chrome/browser/ash/input_method/assistive_suggester.cc index 25d1a4f..edb62ad 100644 --- a/chrome/browser/ash/input_method/assistive_suggester.cc +++ b/chrome/browser/ash/input_method/assistive_suggester.cc
@@ -137,6 +137,11 @@ void RecordMultiWordTextInputState(PrefService* pref_service, AssistiveSuggesterSwitch* suggester_switch, const std::string& engine_id) { + if (IsLacrosEnabled()) { + RecordTextInputStateMetric(AssistiveTextInputState::kUnsupportedClient); + return; + } + if (!suggester_switch->IsMultiWordSuggestionAllowed()) { RecordTextInputStateMetric( AssistiveTextInputState::kFeatureBlockedByDenylist); @@ -149,11 +154,6 @@ return; } - if (IsLacrosEnabled()) { - RecordTextInputStateMetric(AssistiveTextInputState::kUnsupportedClient); - return; - } - if (!IsUsEnglishEngineId(engine_id)) { RecordTextInputStateMetric(AssistiveTextInputState::kUnsupportedLanguage); return;
diff --git a/chrome/browser/ash/login/screens/lacros_data_migration_screen.cc b/chrome/browser/ash/login/screens/lacros_data_migration_screen.cc index fbea6ef..c767b43 100644 --- a/chrome/browser/ash/login/screens/lacros_data_migration_screen.cc +++ b/chrome/browser/ash/login/screens/lacros_data_migration_screen.cc
@@ -8,8 +8,6 @@ #include "base/command_line.h" #include "base/task/bind_post_task.h" #include "base/threading/sequenced_task_runner_handle.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" #include "chrome/browser/ash/crosapi/browser_data_migrator.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "content/public/browser/browser_thread.h" @@ -19,27 +17,13 @@ namespace ash { namespace { constexpr char kUserActionCancel[] = "cancel"; -constexpr base::TimeDelta kShowSkipButtonDuration = base::Seconds(20); - -class MigratorDelegateImpl - : public LacrosDataMigrationScreen::MigratorDelegate { - base::OnceClosure Migrate( - const std::string& user_id_hash, - const base::RepeatingCallback<void(int)>& progress_callback) override { - return BrowserDataMigrator::Migrate( - user_id_hash, progress_callback, - base::BindOnce(&chrome::AttemptRestart)); - } -}; - -} // namespace +} LacrosDataMigrationScreen::LacrosDataMigrationScreen( LacrosDataMigrationScreenView* view) : BaseScreen(LacrosDataMigrationScreenView::kScreenId, OobeScreenPriority::SCREEN_DEVICE_DEVELOPER_MODIFICATION), - view_(view), - migrator_delegate_(std::make_unique<MigratorDelegateImpl>()) { + view_(view) { DCHECK(view_); if (view_) view_->Bind(this); @@ -60,45 +44,29 @@ if (!view_) return; - // user_id_hash_ is not empty if it is already set by - // `SetUserIdHashForTesting()`. - if (user_id_hash_.empty()) { - user_id_hash_ = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kBrowserDataMigrationForUser); - } - DCHECK(!user_id_hash_.empty()) << "user_id_hash_ should not be empty."; - + const std::string user_id_hash = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kBrowserDataMigrationForUser); base::RepeatingCallback<void(int)> progress_callback = base::BindPostTask( base::SequencedTaskRunnerHandle::Get(), base::BindRepeating(&LacrosDataMigrationScreen::OnProgressUpdate, weak_factory_.GetWeakPtr()), FROM_HERE); - - cancel_callback_ = - migrator_delegate_->Migrate(user_id_hash_, progress_callback); + // TODO(crbug.com/1178702): Hide skip button and only show it after 10s. + // Start browser data migration. + cancel_callback_ = BrowserDataMigrator::Migrate( + user_id_hash, progress_callback, base::BindOnce(&chrome::AttemptRestart)); // Show the screen. view_->Show(); GetWakeLock()->RequestWakeLock(); - - // Post a delayed task to show the skip button after - // `kShowSkipButtonDuration`. - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&LacrosDataMigrationScreen::ShowSkipButton, - weak_factory_.GetWeakPtr()), - kShowSkipButtonDuration); } void LacrosDataMigrationScreen::OnProgressUpdate(int progress) { view_->SetProgressValue(progress); } -void LacrosDataMigrationScreen::ShowSkipButton() { - view_->ShowSkipButton(); -} - void LacrosDataMigrationScreen::OnUserAction(const std::string& action_id) { if (action_id == kUserActionCancel) { if (cancel_callback_) { @@ -134,14 +102,4 @@ return wake_lock_.get(); } -void LacrosDataMigrationScreen::SetMigratorDelegateForTesting( - std::unique_ptr<MigratorDelegate> migrator_delegate) { - migrator_delegate_ = std::move(migrator_delegate); -} - -void LacrosDataMigrationScreen::SetUserIdHashForTesting( - const std::string& user_id_hash) { - user_id_hash_ = user_id_hash; -} - } // namespace ash
diff --git a/chrome/browser/ash/login/screens/lacros_data_migration_screen.h b/chrome/browser/ash/login/screens/lacros_data_migration_screen.h index 1ec5835..5680ba2 100644 --- a/chrome/browser/ash/login/screens/lacros_data_migration_screen.h +++ b/chrome/browser/ash/login/screens/lacros_data_migration_screen.h
@@ -18,17 +18,6 @@ // directory. The screen is shown during login. class LacrosDataMigrationScreen : public BaseScreen { public: - // MigratorDelegate initiates the migration. A fake migrator delegate can be - // set for testing. - class MigratorDelegate { - public: - // Calls the actual migrator method `ash::BrowserDataMigrator::Migrate()`. - virtual base::OnceClosure Migrate( - const std::string& user_id_hash, - const base::RepeatingCallback<void(int)>& progress_callback) = 0; - virtual ~MigratorDelegate() = default; - }; - explicit LacrosDataMigrationScreen(LacrosDataMigrationScreenView* view); ~LacrosDataMigrationScreen() override; LacrosDataMigrationScreen(const LacrosDataMigrationScreen&) = delete; @@ -47,17 +36,6 @@ // value. `progress` is then passed to `LacrosDataMigrationView`. void OnProgressUpdate(int progress); - // Posted as a delayed task from `ShowImpl()`. It calls the method of the same - // name on `LacrosDataMigrationScreenView`. - void ShowSkipButton(); - - // Set `migrator_delegate_` for testing. - void SetMigratorDelegateForTesting( - std::unique_ptr<MigratorDelegate> migrator_delegate); - - // Set `user_id_hash_` for testing. - void SetUserIdHashForTesting(const std::string& user_id_hash); - private: // BaseScreen: void ShowImpl() override; @@ -70,10 +48,8 @@ LacrosDataMigrationScreenView* view_; // Callback to cancel migration. Stores the return value from - // `migrator_delegate->Migrate()`. + // `BrowserDataMigrator::Migrate()`. base::OnceClosure cancel_callback_; - std::unique_ptr<MigratorDelegate> migrator_delegate_; - std::string user_id_hash_; base::WeakPtrFactory<LacrosDataMigrationScreen> weak_factory_{this}; };
diff --git a/chrome/browser/ash/login/screens/lacros_data_migration_screen_browsertest.cc b/chrome/browser/ash/login/screens/lacros_data_migration_screen_browsertest.cc deleted file mode 100644 index 8e12009..0000000 --- a/chrome/browser/ash/login/screens/lacros_data_migration_screen_browsertest.cc +++ /dev/null
@@ -1,109 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ash/login/screens/lacros_data_migration_screen.h" - -#include "ash/constants/ash_switches.h" -#include "base/memory/ptr_util.h" -#include "base/test/task_environment.h" -#include "chrome/browser/ash/crosapi/browser_data_migrator.h" -#include "chrome/browser/ash/login/test/device_state_mixin.h" -#include "chrome/browser/ash/login/test/js_checker.h" -#include "chrome/browser/ash/login/test/login_manager_mixin.h" -#include "chrome/browser/ash/login/test/oobe_base_test.h" -#include "chrome/browser/ash/login/test/oobe_screen_waiter.h" -#include "chrome/browser/ash/login/ui/login_display_host_mojo.h" -#include "chrome/browser/ash/login/wizard_controller.h" -#include "chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/base/mixin_based_in_process_browser_test.h" -#include "content/public/test/browser_test.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace ash { -namespace { -constexpr char kLacrosDataMigrationId[] = "lacros-data-migration"; -const test::UIPath kSkipButton = {kLacrosDataMigrationId, "cancelButton"}; - -class FakeMigrator : public LacrosDataMigrationScreen::MigratorDelegate { - public: - base::OnceClosure Migrate( - const std::string& user_id_hash, - const base::RepeatingCallback<void(int)>& progress_callback) override { - return base::BindOnce([](bool* cancel_called) { *cancel_called = true; }, - &cancel_called_); - } - - // Checks if the returned function from `Migrate()` is called. - bool IsCancelCalled() { return cancel_called_; } - - private: - bool cancel_called_ = false; -}; - -class LacrosDataMigrationScreenTest : public OobeBaseTest { - public: - LacrosDataMigrationScreenTest() { - // Adding a user and marking OOBE completed with DeviceStateMixin ensures - // that chrome://oobe/login is loaded instead of chrome://oobe/oobe and that - // LoginDisplayHostMojo is created instead of LoginDisplayHostWebUI. - login_mixin_.AppendRegularUsers(1); - } - LacrosDataMigrationScreenTest(const LacrosDataMigrationScreenTest&) = delete; - LacrosDataMigrationScreenTest& operator=( - const LacrosDataMigrationScreenTest&) = delete; - ~LacrosDataMigrationScreenTest() override = default; - - void SetUpOnMainThread() override { - LoginDisplayHostMojo* login_display_host = - static_cast<LoginDisplayHostMojo*>(LoginDisplayHost::default_host()); - // Call `StartWizard()` with any screen to ensure that - // `LoginDisplayHostMojo::EnsureOobeDialogLoaded()` is called but do not - // show `LacrosDataMigrationScreen` yet because that will start the - // migration before stubbing certain methonds. - login_display_host->StartWizard(GaiaView::kScreenId); - LacrosDataMigrationScreen* lacros_data_migration_screen = - static_cast<LacrosDataMigrationScreen*>( - WizardController::default_controller()->GetScreen( - LacrosDataMigrationScreenView::kScreenId)); - fake_migrator_ = new FakeMigrator(); - lacros_data_migration_screen->SetMigratorDelegateForTesting( - base::WrapUnique(fake_migrator_)); - lacros_data_migration_screen->SetUserIdHashForTesting("user"); - OobeBaseTest::SetUpOnMainThread(); - } - - protected: - FakeMigrator* fake_migrator() { return fake_migrator_; } - - private: - // This is owned by `LacrosDataMigrationScreen`. - FakeMigrator* fake_migrator_; - DeviceStateMixin device_state_{ - &mixin_host_, DeviceStateMixin::State::OOBE_COMPLETED_CONSUMER_OWNED}; - LoginManagerMixin login_mixin_{&mixin_host_}; -}; - -IN_PROC_BROWSER_TEST_F(LacrosDataMigrationScreenTest, SkipButton) { - OobeScreenWaiter waiter(LacrosDataMigrationScreenView::kScreenId); - WizardController::default_controller()->AdvanceToScreen( - LacrosDataMigrationScreenView::kScreenId); - waiter.Wait(); - - test::OobeJS().ExpectHiddenPath(kSkipButton); - - LacrosDataMigrationScreen* lacros_data_migration_screen = - static_cast<LacrosDataMigrationScreen*>( - WizardController::default_controller()->GetScreen( - LacrosDataMigrationScreenView::kScreenId)); - lacros_data_migration_screen->ShowSkipButton(); - - test::OobeJS().ExpectVisiblePath(kSkipButton); - - EXPECT_FALSE(fake_migrator()->IsCancelCalled()); - test::OobeJS().TapOnPath(kSkipButton); - EXPECT_TRUE(fake_migrator()->IsCancelCalled()); -} -} // namespace -} // namespace ash
diff --git a/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.h b/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.h index 4591814..a4f696c 100644 --- a/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.h +++ b/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.h
@@ -22,7 +22,6 @@ ~SystemExtensionsSandboxedUnpacker(); enum class Status { - kOk, // This is used for the default constructor of `StatusOrSystemExtension`. kUnknown, kFailedDirectoryMissing,
diff --git a/chrome/browser/ash/system_extensions/system_extensions_status_or.h b/chrome/browser/ash/system_extensions/system_extensions_status_or.h index e3ab833..07602fe 100644 --- a/chrome/browser/ash/system_extensions/system_extensions_status_or.h +++ b/chrome/browser/ash/system_extensions/system_extensions_status_or.h
@@ -6,15 +6,16 @@ #define CHROME_BROWSER_ASH_SYSTEM_EXTENSIONS_SYSTEM_EXTENSIONS_STATUS_OR_H_ #include "chrome/browser/ash/system_extensions/system_extension.h" +#include "third_party/abseil-cpp/absl/types/variant.h" // SystemExtensionsStatusOr is a union of an status enum class and an object. // This class either holds an object in a usable state, or a status code // explaining why `T` is not present. This class is typically the return value // of a function which may fail. // -// An SystemExtensionsStatusOr can never hold an "OK" status (an `S::kOk` -// value); instead, the presence of `T` indicates success. Instead of checking -// for a `kOk` value, use the `ok()` member function. +// An SystemExtensionsStatusOr can never hold an "OK" status, instead, the +// presence of `T` indicates success. Instead of checking for a `kOk` value, use +// the `ok()` member function. // // There is nothing SystemExtensions specific about this class so if needed // this can be moved to //base. @@ -24,43 +25,42 @@ // Constructs a new `SystemExtensionsStatusOr` with an `S::kUnknown` status. // This constructor is marked 'explicit' to prevent usages in return values // such as 'return {};'. - explicit SystemExtensionsStatusOr() : status_(S::kUnknown) {} // NOLINT + explicit SystemExtensionsStatusOr() // NOLINT + : status_or_value_(S::kUnknown) {} - // All of these are implicit, so that one may just return Status or - // SystemExtension. - SystemExtensionsStatusOr(S status) : status_(status) {} // NOLINT - SystemExtensionsStatusOr(T value) // NOLINT - : status_(S::kOk), value_(std::move(value)) {} + // All of these are implicit, so that one may just return `S` or `T`. + SystemExtensionsStatusOr(S status) : status_or_value_(status) {} // NOLINT + SystemExtensionsStatusOr(T value) // NOLINT + : status_or_value_(std::move(value)) {} SystemExtensionsStatusOr(SystemExtensionsStatusOr&&) = default; SystemExtensionsStatusOr& operator=(SystemExtensionsStatusOr&&) = default; ~SystemExtensionsStatusOr() = default; - bool ok() const { return status_ == S::kOk; } + bool ok() const { return absl::holds_alternative<T>(status_or_value_); } // Returns the status code when the status is not kOk. Crashes if the // status is kOk. S status() { CHECK(!ok()); - return status_; + return absl::get<S>(status_or_value_); } - // Returns the object if ok() is true. CHECKs otherwise. + // Returns `T` if ok() is true. CHECKs otherwise. const T& value() const& { CHECK(ok()); - return value_; + return absl::get<T>(status_or_value_); } - // Returns the SystemExtension if ok() is true. CHECKs otherwise. + // Returns the `T` if ok() is true. CHECKs otherwise. T&& value() && { CHECK(ok()); - return std::move(value_); + return std::move(absl::get<T>(status_or_value_)); } private: - S status_; - T value_; + absl::variant<S, T> status_or_value_; }; template <typename S>
diff --git a/chrome/browser/browser_switcher/alternative_browser_driver.h b/chrome/browser/browser_switcher/alternative_browser_driver.h index 4cdd2f8..91cd084 100644 --- a/chrome/browser/browser_switcher/alternative_browser_driver.h +++ b/chrome/browser/browser_switcher/alternative_browser_driver.h
@@ -48,9 +48,9 @@ // method is most appropriate. virtual void TryLaunch(const GURL& url, LaunchCallback cb) = 0; - // Returns the localized string for the name of the alternative browser, if it - // was auto-detected. If the name couldn't be auto-detected, returns an empty - // string. + // Returns the string for the name of the alternative browser, if it was + // auto-detected. If the name couldn't be auto-detected, returns + // "alternative browser" virtual std::string GetBrowserName() const = 0; // Returns the type of browser as an enum, if it was auto-detected. Otherwise,
diff --git a/chrome/browser/browser_switcher/alternative_browser_driver_posix.cc b/chrome/browser/browser_switcher/alternative_browser_driver_posix.cc index 83082518..4003b6b3 100644 --- a/chrome/browser/browser_switcher/alternative_browser_driver_posix.cc +++ b/chrome/browser/browser_switcher/alternative_browser_driver_posix.cc
@@ -263,7 +263,7 @@ std::string AlternativeBrowserDriverImpl::GetBrowserName() const { std::string path = prefs_->GetAlternativeBrowserPath(); const auto* mapping = FindBrowserMapping(path); - return mapping ? mapping->browser_name : std::string(); + return mapping ? mapping->browser_name : "alternative browser"; } BrowserType AlternativeBrowserDriverImpl::GetBrowserType() const {
diff --git a/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc b/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc index 0d050ae..e2cf991 100644 --- a/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc +++ b/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc
@@ -107,14 +107,14 @@ #elif defined(OS_MAC) std::string expected = "Safari"; #else - std::string expected; + std::string expected = "alternative browser"; #endif std::string actual = driver()->GetBrowserName(); EXPECT_EQ(expected, actual); SetBrowserPath("bogus.exe"); actual = driver()->GetBrowserName(); - EXPECT_EQ("", actual); + EXPECT_EQ("alternative browser", actual); #if defined(OS_WIN) SetBrowserPath("${ie}");
diff --git a/chrome/browser/browser_switcher/alternative_browser_driver_win.cc b/chrome/browser/browser_switcher/alternative_browser_driver_win.cc index 9ff7d7a8..5063bd7 100644 --- a/chrome/browser/browser_switcher/alternative_browser_driver_win.cc +++ b/chrome/browser/browser_switcher/alternative_browser_driver_win.cc
@@ -334,7 +334,7 @@ std::string AlternativeBrowserDriverImpl::GetBrowserName() const { std::wstring path = base::UTF8ToWide(prefs_->GetAlternativeBrowserPath()); const auto* mapping = FindBrowserMapping(path, false); - return mapping ? mapping->browser_name : std::string(); + return mapping ? mapping->browser_name : "alternative browser"; } BrowserType AlternativeBrowserDriverImpl::GetBrowserType() const {
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index e221d1d3..f4a9d12 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -25,6 +25,8 @@ #include "ash/public/cpp/autotest_ambient_api.h" #include "ash/public/cpp/autotest_desks_api.h" #include "ash/public/cpp/autotest_private_api_utils.h" +#include "ash/public/cpp/holding_space/holding_space_model.h" +#include "ash/public/cpp/holding_space/holding_space_prefs.h" #include "ash/public/cpp/login_screen.h" #include "ash/public/cpp/metrics_util.h" #include "ash/public/cpp/overview_test_api.h" @@ -102,6 +104,8 @@ #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/ash/default_pinned_apps.h" +#include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h" +#include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller_util.h" #include "chrome/browser/ui/ash/shelf/shelf_spinner_controller.h" @@ -139,6 +143,7 @@ #include "components/app_restore/window_properties.h" #include "components/policy/core/browser/policy_conversions.h" #include "components/policy/core/common/policy_service.h" +#include "components/prefs/pref_service.h" #include "components/services/app_service/public/cpp/types_util.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "components/user_manager/user.h" @@ -5267,6 +5272,51 @@ smoothness))); } +//////////////////////////////////////////////////////////////////////////////// +// AutotestPrivateResetHoldingSpaceFunction +//////////////////////////////////////////////////////////////////////////////// + +AutotestPrivateResetHoldingSpaceFunction:: + AutotestPrivateResetHoldingSpaceFunction() = default; + +AutotestPrivateResetHoldingSpaceFunction:: + ~AutotestPrivateResetHoldingSpaceFunction() = default; + +ExtensionFunction::ResponseAction +AutotestPrivateResetHoldingSpaceFunction::Run() { + auto params(api::autotest_private::ResetHoldingSpace::Params::Create(args())); + EXTENSION_FUNCTION_VALIDATE(params); + + Profile* profile = Profile::FromBrowserContext(browser_context()); + + ash::HoldingSpaceKeyedService* service = + ash::HoldingSpaceKeyedServiceFactory::GetInstance()->GetService(profile); + + if (service == nullptr) + return RespondNow(Error("Failed to get `HoldingSpaceKeyedService`.")); + + service->RemoveAll(); + + PrefService* prefs = profile->GetPrefs(); + ash::holding_space_prefs::ResetProfilePrefsForTesting(prefs); + + if (!ash::holding_space_prefs::MarkTimeOfFirstAvailability(prefs)) { + return RespondNow( + Error("Failed to call `MarkTimeOfFirstAvailability()` after clearing " + "prefs.")); + } + + if (!params->options || !params->options->mark_time_of_first_add) + return RespondNow(NoArguments()); + + if (!ash::holding_space_prefs::MarkTimeOfFirstAdd(prefs)) { + return RespondNow( + Error("Failed to call `MarkTimeOfFirstAdd()` after clearing prefs.")); + } + + return RespondNow(NoArguments()); +} + /////////////////////////////////////////////////////////////////////////////// // AutotestPrivateAPI ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h index 7982e81..1b6b5c8 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h
@@ -1431,6 +1431,17 @@ ResponseAction Run() override; }; +class AutotestPrivateResetHoldingSpaceFunction : public ExtensionFunction { + public: + AutotestPrivateResetHoldingSpaceFunction(); + DECLARE_EXTENSION_FUNCTION("autotestPrivate.resetHoldingSpace", + AUTOTESTPRIVATE_RESETHOLDINGSPACE) + + private: + ~AutotestPrivateResetHoldingSpaceFunction() override; + ResponseAction Run() override; +}; + template <> KeyedService* BrowserContextKeyedAPIFactory<AutotestPrivateAPI>::BuildServiceInstanceFor(
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc index 3a33cbb..d58350d 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_apitest.cc
@@ -10,10 +10,13 @@ #include "ash/components/arc/test/arc_util_test_support.h" #include "ash/components/arc/test/connection_holder_util.h" #include "ash/components/arc/test/fake_app_instance.h" +#include "ash/public/cpp/holding_space/holding_space_prefs.h" #include "ash/public/cpp/overview_test_api.h" #include "ash/public/cpp/test/shell_test_api.h" +#include "base/json/json_writer.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" +#include "base/values.h" #include "build/build_config.h" #include "chrome/browser/ash/arc/arc_util.h" #include "chrome/browser/ash/arc/session/arc_session_manager.h" @@ -82,13 +85,33 @@ ->set_test_mode(true); } + bool RunAutotestPrivateExtensionTest(const std::string& test_suite) { + return RunAutotestPrivateExtensionTest( + test_suite, + /*suite_args=*/std::vector<base::Value>()); + } + + bool RunAutotestPrivateExtensionTest(const std::string& test_suite, + std::vector<base::Value> suite_args) { + base::DictionaryValue custom_args; + custom_args.SetKey("testSuite", base::Value(test_suite)); + custom_args.SetKey("args", base::Value(suite_args)); + + std::string json; + if (!base::JSONWriter::Write(custom_args, &json)) { + LOG(ERROR) << "Failed to parse custom args into json."; + return false; + } + + return RunExtensionTest("autotest_private", {.custom_arg = json.c_str()}, + {.load_as_component = true}); + } + ash::ScopedTestingCrosSettings scoped_testing_cros_settings_; }; IN_PROC_BROWSER_TEST_F(AutotestPrivateApiTest, AutotestPrivate) { - ASSERT_TRUE(RunExtensionTest("autotest_private", {.custom_arg = "default"}, - {.load_as_component = true})) - << message_; + ASSERT_TRUE(RunAutotestPrivateExtensionTest("default")) << message_; } // Set of tests where ARC is enabled and test apps and packages are registered. @@ -126,24 +149,66 @@ true /* sync */)); app_instance->SendRefreshPackageList(std::move(packages)); - ASSERT_TRUE(RunExtensionTest("autotest_private", {.custom_arg = "arcEnabled"}, - {.load_as_component = true})) - << message_; + ASSERT_TRUE(RunAutotestPrivateExtensionTest("arcEnabled")) << message_; arc::SetArcPlayStoreEnabledForProfile(profile(), false); } IN_PROC_BROWSER_TEST_F(AutotestPrivateApiTest, ScrollableShelfAPITest) { - ASSERT_TRUE(RunExtensionTest("autotest_private", - {.custom_arg = "scrollableShelf"}, - {.load_as_component = true})) - << message_; + ASSERT_TRUE(RunAutotestPrivateExtensionTest("scrollableShelf")) << message_; } IN_PROC_BROWSER_TEST_F(AutotestPrivateApiTest, ShelfAPITest) { - ASSERT_TRUE(RunExtensionTest("autotest_private", {.custom_arg = "shelf"}, - {.load_as_component = true})) + ASSERT_TRUE(RunAutotestPrivateExtensionTest("shelf")) << message_; +} + +class AutotestPrivateHoldingSpaceApiTest + : public AutotestPrivateApiTest, + public ::testing::WithParamInterface<bool /* mark_time_of_first_add */> { +}; + +INSTANTIATE_TEST_CASE_P(All, + AutotestPrivateHoldingSpaceApiTest, + ::testing::Bool() /* mark_time_of_first_add */); + +IN_PROC_BROWSER_TEST_P(AutotestPrivateHoldingSpaceApiTest, + HoldingSpaceAPITest) { + auto* prefs = browser()->profile()->GetPrefs(); + + ash::holding_space_prefs::SetPreviewsEnabled(prefs, false); + ash::holding_space_prefs::MarkTimeOfFirstAdd(prefs); + ash::holding_space_prefs::MarkTimeOfFirstAvailability(prefs); + ash::holding_space_prefs::MarkTimeOfFirstEntry(prefs); + ash::holding_space_prefs::MarkTimeOfFirstFilesAppChipPress(prefs); + ash::holding_space_prefs::MarkTimeOfFirstPin(prefs); + + const bool mark_time_of_first_add = GetParam(); + + base::DictionaryValue options; + options.SetBoolean("markTimeOfFirstAdd", mark_time_of_first_add); + std::vector<base::Value> suite_args; + suite_args.emplace_back(std::move(options)); + + ASSERT_TRUE( + RunAutotestPrivateExtensionTest("holdingSpace", std::move(suite_args))) << message_; + + absl::optional<base::Time> timeOfFirstAdd = + ash::holding_space_prefs::GetTimeOfFirstAdd(prefs); + absl::optional<base::Time> timeOfFirstAvailability = + ash::holding_space_prefs::GetTimeOfFirstAvailability(prefs); + + ASSERT_TRUE(ash::holding_space_prefs::IsPreviewsEnabled(prefs)); + ASSERT_EQ(timeOfFirstAdd.has_value(), mark_time_of_first_add); + ASSERT_NE(timeOfFirstAvailability, absl::nullopt); + ASSERT_EQ(ash::holding_space_prefs::GetTimeOfFirstEntry(prefs), + absl::nullopt); + ASSERT_EQ(ash::holding_space_prefs::GetTimeOfFirstFilesAppChipPress(prefs), + absl::nullopt); + ASSERT_EQ(ash::holding_space_prefs::GetTimeOfFirstPin(prefs), absl::nullopt); + + if (timeOfFirstAdd) + ASSERT_GT(timeOfFirstAdd, timeOfFirstAvailability); } class AutotestPrivateApiOverviewTest : public AutotestPrivateApiTest { @@ -178,10 +243,7 @@ }; IN_PROC_BROWSER_TEST_F(AutotestPrivateApiOverviewTest, Default) { - ASSERT_TRUE(RunExtensionTest("autotest_private", - {.custom_arg = "overviewDefault"}, - {.load_as_component = true})) - << message_; + ASSERT_TRUE(RunAutotestPrivateExtensionTest("overviewDefault")) << message_; } IN_PROC_BROWSER_TEST_F(AutotestPrivateApiOverviewTest, Drag) { @@ -206,10 +268,7 @@ const gfx::Point end_point(start_point.x() + 50, start_point.y()); generator.MoveTouch(end_point); - ASSERT_TRUE(RunExtensionTest("autotest_private", - {.custom_arg = "overviewDrag"}, - {.load_as_component = true})) - << message_; + ASSERT_TRUE(RunAutotestPrivateExtensionTest("overviewDrag")) << message_; } IN_PROC_BROWSER_TEST_F(AutotestPrivateApiOverviewTest, LeftSnapped) { @@ -234,9 +293,7 @@ generator.MoveTouch(end_point); generator.ReleaseTouch(); - ASSERT_TRUE(RunExtensionTest("autotest_private", - {.custom_arg = "splitviewLeftSnapped"}, - {.load_as_component = true})) + ASSERT_TRUE(RunAutotestPrivateExtensionTest("splitviewLeftSnapped")) << message_; } @@ -274,9 +331,7 @@ // GetAllEnterprisePolicies Sanity check. IN_PROC_BROWSER_TEST_F(AutotestPrivateWithPolicyApiTest, PolicyAPITest) { - ASSERT_TRUE(RunExtensionTest("autotest_private", - {.custom_arg = "enterprisePolicies"}, - {.load_as_component = true})) + ASSERT_TRUE(RunAutotestPrivateExtensionTest("enterprisePolicies")) << message_; } @@ -329,9 +384,7 @@ wm::ActivationChangeObserver::ActivationReason::ACTIVATION_CLIENT, arc_widget->GetNativeWindow(), arc_widget->GetNativeWindow()); - ASSERT_TRUE(RunExtensionTest("autotest_private", - {.custom_arg = "arcPerformanceTracing"}, - {.load_as_component = true})) + ASSERT_TRUE(RunAutotestPrivateExtensionTest("arcPerformanceTracing")) << message_; } @@ -349,10 +402,7 @@ // TODO(crbug.com/1201545): Fix flakiness. IN_PROC_BROWSER_TEST_F(AutotestPrivateSystemWebAppsTest, SystemWebApps) { - ASSERT_TRUE(RunExtensionTest("autotest_private", - {.custom_arg = "systemWebApps"}, - {.load_as_component = true})) - << message_; + ASSERT_TRUE(RunAutotestPrivateExtensionTest("systemWebApps")) << message_; } } // namespace extensions
diff --git a/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc b/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc index 624b3ef4..5d91d3b 100644 --- a/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/files/file_util.h" #include "base/path_service.h" +#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/test/values_test_util.h" #include "base/threading/thread_restrictions.h" @@ -44,7 +45,10 @@ #include "third_party/boringssl/src/include/openssl/ssl.h" using DevToolsProtocolTest = DevToolsProtocolTestBase; +using testing::AllOf; using testing::Eq; +using testing::Contains; +using testing::Not; namespace { @@ -112,6 +116,81 @@ // Should not crash by this point. } +IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, + InputDispatchEventsToCorrectTarget) { + Attach(); + + std::string setup_logging = R"( + window.logs = []; + ['dragenter', 'keydown', 'mousedown', 'mouseenter', 'mouseleave', + 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'click', 'touchcancel', + 'touchend', 'touchmove', 'touchstart', + ].forEach((event) => + window.addEventListener(event, (e) => logs.push(e.type)));)"; + content::WebContents* target_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), GURL("about:blank"), WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + content::WebContents* other_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_TRUE( + content::EvalJs(target_web_contents, setup_logging).error.empty()); + EXPECT_TRUE(content::EvalJs(other_web_contents, setup_logging).error.empty()); + + base::DictionaryValue params; + params.SetStringKey("button", "left"); + params.SetIntKey("clickCount", 1); + params.SetIntKey("x", 100); + params.SetIntKey("y", 250); + params.SetIntKey("clickCount", 1); + + params.SetStringKey("type", "mousePressed"); + SendCommandSync("Input.dispatchMouseEvent", params.Clone()); + + params.SetStringKey("type", "mouseMoved"); + params.SetIntKey("y", 270); + SendCommandSync("Input.dispatchMouseEvent", params.Clone()); + + params.SetStringKey("type", "mouseReleased"); + SendCommandSync("Input.dispatchMouseEvent", std::move(params)); + + params = base::DictionaryValue(); + params.SetIntKey("x", 100); + params.SetIntKey("y", 250); + params.SetStringPath("type", "dragEnter"); + params.SetIntPath("data.dragOperationsMask", 1); + params.SetPath("data.items", base::ListValue()); + SendCommandSync("Input.dispatchDragEvent", std::move(params)); + + params = base::DictionaryValue(); + params.SetIntKey("x", 100); + params.SetIntKey("y", 250); + SendCommandSync("Input.synthesizeTapGesture", std::move(params)); + + params = base::DictionaryValue(); + params.SetStringKey("type", "keyDown"); + params.SetStringKey("key", "a"); + SendCommandSync("Input.dispatchKeyEvent", std::move(params)); + + content::EvalJsResult main_target_events = + content::EvalJs(target_web_contents, "logs.join(' ')"); + content::EvalJsResult other_target_events = + content::EvalJs(other_web_contents, "logs.join(' ')"); + // mouse events might happen in the other_target if the real mouse pointer + // happens to be over the browser window + EXPECT_THAT(base::SplitString(main_target_events.ExtractString(), " ", + base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL), + AllOf(Contains("mouseover"), Contains("mousedown"), Contains("mousemove"), + Contains("mouseup"), Contains("click"), Contains("dragenter"), + Contains("keydown"))); + EXPECT_THAT(base::SplitString(other_target_events.ExtractString(), " ", + base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL), + AllOf(Not(Contains("click")), Not(Contains("dragenter")), + Not(Contains("keydown")))); +} + class DevToolsProtocolTest_AppId : public DevToolsProtocolTest { public: DevToolsProtocolTest_AppId() {
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 7fc5488..8c893d0 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -2169,11 +2169,6 @@ "expiry_milestone": 95 }, { - "name": "enable-layout-ng", - "owners": [ "layout-dev@chromium.org" ], - "expiry_milestone": 80 - }, - { "name": "enable-lazy-frame-loading", "owners": [ "//components/data_reduction_proxy/OWNERS" ], "expiry_milestone": 90 @@ -3133,6 +3128,11 @@ "expiry_milestone": 100 }, { + "name": "files-extract-archive", + "owners": [ "adanilo", "simmonsjosh@google.com" ], + "expiry_milestone": 112 + }, + { "name": "files-filters-in-recents", "owners": [ "simmonsjosh@google.com", "benhartney@google.com" ], "expiry_milestone": 98 @@ -3153,11 +3153,6 @@ "expiry_milestone": 105 }, { - "name": "files-zip-unpack", - "owners": [ "fdegros", "jboulic"], - "expiry_milestone": 100 - }, - { "name": "fill-on-account-select", "owners": [ "kazinova@google.com", "vasilii" ], "expiry_milestone": 100
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 7471e3a..bb631661 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1003,10 +1003,6 @@ const char kEnableCanvasContextLostInBackgroundDescription[] = "Enable canvas context to be cleared when it is running in background"; -const char kEnableLayoutNGName[] = "Enable LayoutNG"; -const char kEnableLayoutNGDescription[] = - "Enable Blink's next generation layout engine."; - const char kEnableLazyFrameLoadingName[] = "Enable lazy frame loading"; const char kEnableLazyFrameLoadingDescription[] = "Defers the loading of iframes marked with the attribute 'loading=lazy' " @@ -4698,6 +4694,10 @@ const char kFilesBannerFrameworkDescription[] = "Enable the updated branner framework in Files app"; +const char kFilesExtractArchiveName[] = "Extract archive in Files app"; +const char kFilesExtractArchiveDescription[] = + "Enable the simplified archive extraction feature in Files app"; + const char kFilesSinglePartitionFormatName[] = "Enable Partitioning of Removable Disks."; const char kFilesSinglePartitionFormatDescription[] = @@ -4711,10 +4711,6 @@ const char kFilesTrashDescription[] = "Enable trash for My files volume in Files App."; -const char kFilesZipUnpackName[] = "New ZIP unpacking in Files App"; -const char kFilesZipUnpackDescription[] = - "Enable new ZIP archive extraction system in File Manager."; - const char kForceSpectreVariant2MitigationName[] = "Force Spectre variant 2 mitigagtion"; const char kForceSpectreVariant2MitigationDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index e9de20d..15215af 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -548,9 +548,6 @@ extern const char kEnableGpuServiceLoggingName[]; extern const char kEnableGpuServiceLoggingDescription[]; -extern const char kEnableLayoutNGName[]; -extern const char kEnableLayoutNGDescription[]; - extern const char kEnableLazyFrameLoadingName[]; extern const char kEnableLazyFrameLoadingDescription[]; @@ -2700,6 +2697,9 @@ extern const char kFilesBannerFrameworkName[]; extern const char kFilesBannerFrameworkDescription[]; +extern const char kFilesExtractArchiveName[]; +extern const char kFilesExtractArchiveDescription[]; + extern const char kFilesSinglePartitionFormatName[]; extern const char kFilesSinglePartitionFormatDescription[]; @@ -2709,9 +2709,6 @@ extern const char kFilesTrashName[]; extern const char kFilesTrashDescription[]; -extern const char kFilesZipUnpackName[]; -extern const char kFilesZipUnpackDescription[]; - extern const char kFiltersInRecentsName[]; extern const char kFiltersInRecentsDescription[];
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc index 29b641a..bd3dfa59 100644 --- a/chrome/browser/net/network_context_configuration_browsertest.cc +++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -612,7 +612,7 @@ break; case NetworkContextType::kSafeBrowsing: g_browser_process->safe_browsing_service() - ->FlushNetworkInterfaceForTesting(); + ->FlushNetworkInterfaceForTesting(GetProfile()); break; case NetworkContextType::kProfile: case NetworkContextType::kIncognitoProfile:
diff --git a/chrome/browser/policy/policy_network_browsertest.cc b/chrome/browser/policy/policy_network_browsertest.cc index 28ebc96e..96a6d07 100644 --- a/chrome/browser/policy/policy_network_browsertest.cc +++ b/chrome/browser/policy/policy_network_browsertest.cc
@@ -215,7 +215,7 @@ CrashNetworkService(); // Make sure the NetworkContext has noticed the pipe was closed. g_browser_process->safe_browsing_service() - ->FlushNetworkInterfaceForTesting(); + ->FlushNetworkInterfaceForTesting(browser()->profile()); EXPECT_FALSE(IsQuicEnabledForSafeBrowsing(browser()->profile())); } } @@ -284,7 +284,7 @@ CrashNetworkService(); // Make sure the NetworkContext has noticed the pipe was closed. g_browser_process->safe_browsing_service() - ->FlushNetworkInterfaceForTesting(); + ->FlushNetworkInterfaceForTesting(browser()->profile()); EXPECT_TRUE(IsQuicEnabledForSafeBrowsing(browser()->profile())); } }
diff --git a/chrome/browser/resources/chromeos/login/debug/debug.js b/chrome/browser/resources/chromeos/login/debug/debug.js index f8280213..51e0945 100644 --- a/chrome/browser/resources/chromeos/login/debug/debug.js +++ b/chrome/browser/resources/chromeos/login/debug/debug.js
@@ -846,14 +846,6 @@ { id: 'lacros-data-migration', kind: ScreenKind.OTHER, - defaultState: 'default', - handledSteps: 'skip-revealed', - states: [{ - id: 'skip-revealed', - trigger: (screen) => { - screen.showSkipButton(); - } - }], }, { id: 'terms-of-service',
diff --git a/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.html b/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.html index 327d90601..36b62aa 100644 --- a/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.html +++ b/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.html
@@ -23,23 +23,17 @@ value="[[progressValue_]]"> </paper-progress> <div slot="subtitle"> - <p> - [[i18nDynamic(locale, 'lacrosDataMigrationSubtitle', progressValue_)]] - </p> - <p hidden="[[!canCancel_]]"> - [[i18nDynamic(locale, 'lacrosDataMigrationSkipSuggestion')]] - </p> + [[i18nDynamic(locale, 'lacrosDataMigrationSubtitle', progressValue_)]] </div> <div slot="content" class="flex layout vertical center center-justified"> <img src="/images/update_boot.svg" class="oobe-illustration" aria-hidden="true"> </div> <!-- Cancel button --> - <div slot="bottom-buttons" + <div slot="bottom-buttons" hidden="[[!canCancel]]" class="flex layout horizontal"> - <oobe-text-button id="cancelButton" hidden="[[!canCancel_]]" - on-click="onCancelButtonClicked_" - text-key="lacrosDataMigrationSkipButton"> + <oobe-text-button id="cancelButton" on-click="onCancelButtonClicked_" + text-key="cancelButton"> </oobe-text-button> </div> </oobe-adaptive-dialog>
diff --git a/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.js b/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.js index db53f8fce..7b58000 100644 --- a/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.js +++ b/chrome/browser/resources/chromeos/login/screens/login/lacros_data_migration.js
@@ -27,19 +27,16 @@ constructor() { super(); this.progressValue_ = 0; - this.canCancel_ = false; } static get properties() { return { progressValue_: {type: Number}, - - canCancel_: {type: Boolean} }; } get EXTERNAL_API() { - return ['setProgressValue', 'showSkipButton']; + return ['setProgressValue']; } /** @@ -50,13 +47,6 @@ this.progressValue_ = progress; } - /** - * Called to make the skip button visible. - */ - showSkipButton() { - this.canCancel_ = true; - } - ready() { super.ready(); this.initializeLoginScreen('LacrosDataMigrationScreen', { @@ -65,7 +55,6 @@ } onCancelButtonClicked_() { - assert(this.canCancel_); this.userActed('cancel'); } }
diff --git a/chrome/browser/resources/print_preview/print_preview.ts b/chrome/browser/resources/print_preview/print_preview.ts index 557f7ee6..4c984ab8 100644 --- a/chrome/browser/resources/print_preview/print_preview.ts +++ b/chrome/browser/resources/print_preview/print_preview.ts
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +export {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; export {PluralStringProxyImpl as PrintPreviewPluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js'; export {CloudPrintInterface, CloudPrintInterfaceEventType} from './cloud_print_interface.js'; export {CloudPrintInterfaceImpl} from './cloud_print_interface_impl.js'; @@ -14,7 +15,7 @@ export {DestinationErrorType, DestinationStore, DestinationStoreEventType} from './data/destination_store.js'; export {PageLayoutInfo} from './data/document_info.js'; export {LocalDestinationInfo, ProvisionalDestinationInfo} from './data/local_parsers.js'; -export {CustomMarginsOrientation, Margins, MarginsType} from './data/margins.js'; +export {CustomMarginsOrientation, Margins, MarginsSetting, MarginsType} from './data/margins.js'; export {MeasurementSystem, MeasurementSystemUnitType} from './data/measurement_system.js'; export {DuplexMode, DuplexType, getInstance, PrintPreviewModelElement, whenReady} from './data/model.js'; // <if expr="chromeos or lacros">
diff --git a/chrome/browser/resources/print_preview/ui/button_strip.ts b/chrome/browser/resources/print_preview/ui/button_strip.ts index 0ce4e91e..71287b5 100644 --- a/chrome/browser/resources/print_preview/ui/button_strip.ts +++ b/chrome/browser/resources/print_preview/ui/button_strip.ts
@@ -181,5 +181,11 @@ // </if> } +declare global { + interface HTMLElementTagNameMap { + 'print-preview-button-strip': PrintPreviewButtonStripElement; + } +} + customElements.define( PrintPreviewButtonStripElement.is, PrintPreviewButtonStripElement);
diff --git a/chrome/browser/resources/print_preview/ui/color_settings.ts b/chrome/browser/resources/print_preview/ui/color_settings.ts index cd35dd0..5d27b330 100644 --- a/chrome/browser/resources/print_preview/ui/color_settings.ts +++ b/chrome/browser/resources/print_preview/ui/color_settings.ts
@@ -61,5 +61,11 @@ } } +declare global { + interface HTMLElementTagNameMap { + 'print-preview-color-settings': PrintPreviewColorSettingsElement; + } +} + customElements.define( PrintPreviewColorSettingsElement.is, PrintPreviewColorSettingsElement);
diff --git a/chrome/browser/resources/print_preview/ui/copies_settings.ts b/chrome/browser/resources/print_preview/ui/copies_settings.ts index 4fa78272..23f2e0f 100644 --- a/chrome/browser/resources/print_preview/ui/copies_settings.ts +++ b/chrome/browser/resources/print_preview/ui/copies_settings.ts
@@ -121,5 +121,11 @@ } } +declare global { + interface HTMLElementTagNameMap { + 'print-preview-copies-settings': PrintPreviewCopiesSettingsElement; + } +} + customElements.define( PrintPreviewCopiesSettingsElement.is, PrintPreviewCopiesSettingsElement);
diff --git a/chrome/browser/resources/print_preview/ui/margin_control_container.ts b/chrome/browser/resources/print_preview/ui/margin_control_container.ts index f0c0428..9f8aafc 100644 --- a/chrome/browser/resources/print_preview/ui/margin_control_container.ts +++ b/chrome/browser/resources/print_preview/ui/margin_control_container.ts
@@ -516,6 +516,13 @@ } } +declare global { + interface HTMLElementTagNameMap { + 'print-preview-margin-control-container': + PrintPreviewMarginControlContainerElement; + } +} + customElements.define( PrintPreviewMarginControlContainerElement.is, PrintPreviewMarginControlContainerElement);
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/about_page_browser_proxy.js b/chrome/browser/resources/settings/chromeos/os_about_page/about_page_browser_proxy.js index 1dfee94ca..3bb3a65 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/about_page_browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/os_about_page/about_page_browser_proxy.js
@@ -175,6 +175,9 @@ /** Opens the OS help page. */ openOsHelpPage() {} + /** Opens the firmware updates page. */ + openFirmwareUpdatesPage() {} + /** * Checks for available update and applies if it exists. */ @@ -272,6 +275,11 @@ } /** @override */ + openFirmwareUpdatesPage() { + chrome.send('openFirmwareUpdatesPage'); + } + + /** @override */ requestUpdate() { chrome.send('requestUpdate'); }
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html index d36db58..106ec9c 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html +++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html
@@ -161,6 +161,12 @@ label="$i18n{aboutDiagnostics}" external deep-link-focus-id$="[[Setting.kDiagnostics]]"> </cr-link-row> + <cr-link-row class="hr" id="firmwareUpdates" + on-click="onFirmwareUpdatesClick_" + hidden$="[[!showFirmwareUpdatesApp_]]" + label="$i18n{aboutFirmwareUpdates}" external + deep-link-focus-id$="[[Setting.kFirmwareUpdates]]"> + </cr-link-row> <cr-link-row class="hr" id="detailed-build-info-trigger" on-click="onDetailedBuildInfoClick_" label="$i18n{aboutDetailedBuildInfo}"
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js index 02e786f7..e6d1ee7 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js +++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js
@@ -158,6 +158,12 @@ } }, + /** @protected */ + showFirmwareUpdatesApp_: { + type: Boolean, + value: () => loadTimeData.getBoolean('isFirmwareUpdaterAppEnabled'), + }, + /** @private {!Map<string, string>} */ focusConfig_: { type: Object, @@ -212,6 +218,7 @@ chromeos.settings.mojom.Setting.kReportAnIssue, chromeos.settings.mojom.Setting.kTermsOfService, chromeos.settings.mojom.Setting.kDiagnostics, + chromeos.settings.mojom.Setting.kFirmwareUpdates, ]), }, }, @@ -345,6 +352,13 @@ }, /** @private */ + onFirmwareUpdatesClick_() { + assert(this.showFirmwareUpdatesApp_); + this.aboutBrowserProxy_.openFirmwareUpdatesPage(); + recordSettingChange(chromeos.settings.mojom.Setting.kFirmwareUpdates); + }, + + /** @private */ onRelaunchClick_() { recordSettingChange(); LifetimeBrowserProxyImpl.getInstance().relaunch();
diff --git a/chrome/browser/resources/settings/lazy_load.ts b/chrome/browser/resources/settings/lazy_load.ts index 04535a17..c774327 100644 --- a/chrome/browser/resources/settings/lazy_load.ts +++ b/chrome/browser/resources/settings/lazy_load.ts
@@ -135,6 +135,7 @@ export {SettingsCategoryDefaultRadioGroupElement} from './site_settings/settings_category_default_radio_group.js'; export {SiteDetailsElement} from './site_settings/site_details.js'; export {SiteDetailsPermissionElement} from './site_settings/site_details_permission.js'; +export {SiteEntryElement} from './site_settings/site_entry.js'; export {SiteListElement} from './site_settings/site_list.js'; export {SiteListEntryElement} from './site_settings/site_list_entry.js'; export {ContentSettingProvider, CookiePrimarySetting, DefaultContentSetting, OriginInfo, RawChooserException, RawSiteException, RecentSitePermissions, SiteException, SiteGroup, SiteSettingsPrefsBrowserProxy, SiteSettingsPrefsBrowserProxyImpl, ZoomLevelEntry} from './site_settings/site_settings_prefs_browser_proxy.js';
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.ts b/chrome/browser/resources/settings/privacy_page/personalization_options.ts index 51dc54a..7fe8bf9 100644 --- a/chrome/browser/resources/settings/privacy_page/personalization_options.ts +++ b/chrome/browser/resources/settings/privacy_page/personalization_options.ts
@@ -208,6 +208,13 @@ } private shouldShowDriveSuggest_(): boolean { + // <if expr="chromeos"> + if (loadTimeData.getBoolean('syncSettingsCategorizationEnabled') && + loadTimeData.getBoolean('isOSSettings')) { + // Should be hidden in OS settings. + return false; + } + // </if> return loadTimeData.getBoolean('driveSuggestAvailable') && !!this.syncStatus && !!this.syncStatus.signedIn && this.syncStatus.statusAction !== StatusAction.REAUTHENTICATE;
diff --git a/chrome/browser/resources/settings/site_favicon.ts b/chrome/browser/resources/settings/site_favicon.ts index d768e898..af244d4 100644 --- a/chrome/browser/resources/settings/site_favicon.ts +++ b/chrome/browser/resources/settings/site_favicon.ts
@@ -76,4 +76,10 @@ } } +declare global { + interface HTMLElementTagNameMap { + 'site-favicon': SiteFaviconElement; + } +} + customElements.define(SiteFaviconElement.is, SiteFaviconElement);
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.ts b/chrome/browser/resources/settings/site_settings/site_entry.ts index 2980f0eb..2c2e0a38 100644 --- a/chrome/browser/resources/settings/site_settings/site_entry.ts +++ b/chrome/browser/resources/settings/site_settings/site_entry.ts
@@ -40,9 +40,11 @@ }, } -interface SiteEntryElement { +export interface SiteEntryElement { $: { expandIcon: CrIconButtonElement, + collapseParent: HTMLElement, + cookies: HTMLElement, originList: CrLazyRenderElement<IronCollapseElement>, toggleButton: HTMLElement, }; @@ -59,7 +61,7 @@ BaseMixinInterface }; -class SiteEntryElement extends SiteEntryElementBase { +export class SiteEntryElement extends SiteEntryElementBase { static get is() { return 'site-entry'; } @@ -482,4 +484,10 @@ } } +declare global { + interface HTMLElementTagNameMap { + 'site-entry': SiteEntryElement; + } +} + customElements.define(SiteEntryElement.is, SiteEntryElement);
diff --git a/chrome/browser/safe_browsing/network_context_service.cc b/chrome/browser/safe_browsing/network_context_service.cc index 35a11cf..cd948f9 100644 --- a/chrome/browser/safe_browsing/network_context_service.cc +++ b/chrome/browser/safe_browsing/network_context_service.cc
@@ -39,6 +39,10 @@ return network_context_->GetURLLoaderFactory(); } +void NetworkContextService::FlushNetworkInterfaceForTesting() { + network_context_->FlushForTesting(); +} + network::mojom::NetworkContextParamsPtr NetworkContextService::CreateNetworkContextParams() { auto params = SystemNetworkContextManager::GetInstance()
diff --git a/chrome/browser/safe_browsing/network_context_service.h b/chrome/browser/safe_browsing/network_context_service.h index b960f9b..e3f894d 100644 --- a/chrome/browser/safe_browsing/network_context_service.h +++ b/chrome/browser/safe_browsing/network_context_service.h
@@ -34,6 +34,8 @@ // Get the URLLoaderFactory associated to this profile scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory(); + void FlushNetworkInterfaceForTesting(); + private: network::mojom::NetworkContextParamsPtr CreateNetworkContextParams();
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index 70eb4999..411050af 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -46,7 +46,6 @@ #include "components/safe_browsing/buildflags.h" #include "components/safe_browsing/content/browser/client_side_phishing_model.h" #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h" -#include "components/safe_browsing/content/browser/safe_browsing_network_context.h" #include "components/safe_browsing/content/browser/triggers/trigger_manager.h" #include "components/safe_browsing/content/browser/ui_manager.h" #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h" @@ -140,12 +139,6 @@ bool result = base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); DCHECK(result); - network_context_ = - std::make_unique<safe_browsing::SafeBrowsingNetworkContext>( - user_data_dir, features::ShouldTriggerNetworkDataMigration(), - base::BindRepeating(&SafeBrowsingService::CreateNetworkContextParams, - base::Unretained(this))); - WebUIInfoSingleton::GetInstance()->set_safe_browsing_service(this); ui_manager_ = CreateUIManager(); @@ -187,7 +180,6 @@ WebUIInfoSingleton::GetInstance()->set_safe_browsing_service(nullptr); - network_context_->ServiceShuttingDown(); proxy_config_monitor_.reset(); } @@ -214,9 +206,14 @@ return service->GetURLLoaderFactory(); } -void SafeBrowsingService::FlushNetworkInterfaceForTesting() { - if (network_context_) - network_context_->FlushForTesting(); +void SafeBrowsingService::FlushNetworkInterfaceForTesting( + content::BrowserContext* browser_context) { + NetworkContextService* service = + NetworkContextServiceFactory::GetForBrowserContext(browser_context); + if (!service) + return; + + service->FlushNetworkInterfaceForTesting(); } const scoped_refptr<SafeBrowsingUIManager>& SafeBrowsingService::ui_manager()
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h index 203358d..d55a9fd 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.h +++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -69,7 +69,6 @@ #endif class PasswordProtectionService; class SafeBrowsingDatabaseManager; -class SafeBrowsingNetworkContext; class SafeBrowsingServiceFactory; class SafeBrowsingUIManager; class TriggerManager; @@ -133,7 +132,8 @@ content::BrowserContext* browser_context); // Flushes above two interfaces to avoid races in tests. - void FlushNetworkInterfaceForTesting(); + void FlushNetworkInterfaceForTesting( + content::BrowserContext* browser_context); const scoped_refptr<SafeBrowsingUIManager>& ui_manager() const; @@ -272,10 +272,6 @@ std::unique_ptr<ProxyConfigMonitor> proxy_config_monitor_; - // This owns the URLRequestContext inside the network service. This is used by - // SimpleURLLoader for safe browsing requests. - std::unique_ptr<safe_browsing::SafeBrowsingNetworkContext> network_context_; - // Provides phishing and malware statistics. Accessed on UI thread. std::unique_ptr<PingManager> ping_manager_;
diff --git a/chrome/browser/signin/signin_util.cc b/chrome/browser/signin/signin_util.cc index 399fe13..96763400 100644 --- a/chrome/browser/signin/signin_util.cc +++ b/chrome/browser/signin/signin_util.cc
@@ -63,12 +63,9 @@ virtual void OnProfileDeleted(DeleteProfileDialogManager* manager) = 0; }; - DeleteProfileDialogManager(Profile* profile, - std::string primary_account_email, + DeleteProfileDialogManager(std::string primary_account_email, Delegate* delegate) - : profile_(profile), - primary_account_email_(primary_account_email), - delegate_(delegate) {} + : primary_account_email_(primary_account_email), delegate_(delegate) {} DeleteProfileDialogManager(const DeleteProfileDialogManager&) = delete; DeleteProfileDialogManager& operator=(const DeleteProfileDialogManager&) = @@ -76,16 +73,21 @@ ~DeleteProfileDialogManager() override { BrowserList::RemoveObserver(this); } - void PresentDialogOnAllBrowserWindows() { + void PresentDialogOnAllBrowserWindows(Profile* profile) { + DCHECK(profile); + DCHECK(profile_path_.empty()); + profile_path_ = profile->GetPath(); + BrowserList::AddObserver(this); - Browser* active_browser = chrome::FindLastActiveWithProfile(profile_); + Browser* active_browser = chrome::FindLastActiveWithProfile(profile); if (active_browser) OnBrowserSetLastActive(active_browser); } void OnBrowserSetLastActive(Browser* browser) override { - DCHECK(profile_); - if (browser->profile() != profile_) + DCHECK(!profile_path_.empty()); + + if (profile_path_ != browser->profile()->GetPath()) return; DCHECK(browser->window()->GetNativeWindow()); @@ -99,15 +101,15 @@ gaia::ExtractDomainName(primary_account_email_)))); webui::DeleteProfileAtPath( - profile_->GetPath(), + profile_path_, ProfileMetrics::DELETE_PROFILE_PRIMARY_ACCOUNT_NOT_ALLOWED); delegate_->OnProfileDeleted(this); } private: - Profile* profile_; std::string primary_account_email_; Delegate* delegate_; + base::FilePath profile_path_; }; #endif // defined(CAN_DELETE_PROFILE) @@ -145,8 +147,8 @@ if (delete_profile_dialog_manager_) return; delete_profile_dialog_manager_ = - std::make_unique<DeleteProfileDialogManager>(profile, email, this); - delete_profile_dialog_manager_->PresentDialogOnAllBrowserWindows(); + std::make_unique<DeleteProfileDialogManager>(email, this); + delete_profile_dialog_manager_->PresentDialogOnAllBrowserWindows(profile); } void OnProfileDeleted(DeleteProfileDialogManager* dialog_manager) override {
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 5e0423f..327e47c 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -5040,6 +5040,8 @@ "web_applications/web_app_dialog_utils.h", "web_applications/web_app_launch_manager.cc", "web_applications/web_app_launch_manager.h", + "web_applications/web_app_launch_process.cc", + "web_applications/web_app_launch_process.h", "web_applications/web_app_launch_utils.cc", "web_applications/web_app_launch_utils.h", "web_applications/web_app_menu_model.cc",
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc index 54c4765d..7865a8e9 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc
@@ -332,6 +332,10 @@ return holding_space_model_.UpdateItem(id); } +void HoldingSpaceKeyedService::RemoveAll() { + holding_space_model_.RemoveAll(); +} + void HoldingSpaceKeyedService::CancelItem(const HoldingSpaceItem* item) { // Currently it is only possible to cancel download type items. if (!HoldingSpaceItem::IsDownload(item->type()) || !downloads_delegate_)
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h index 8a77a5f..74db9dd 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h +++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h
@@ -147,6 +147,9 @@ std::unique_ptr<HoldingSpaceModel::ScopedItemUpdate> UpdateItem( const std::string& id); + // Removes all holding space items directly from the model. + void RemoveAll(); + // Attempts to cancel/pause/resume the specified holding space `item`. void CancelItem(const HoldingSpaceItem* item); void PauseItem(const HoldingSpaceItem* item);
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc index 88916f2b..7656d8c 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
@@ -2013,6 +2013,42 @@ EXPECT_TRUE(BitmapsAreEqual(actual_image, expected_image)); } +TEST_F(HoldingSpaceKeyedServiceTest, RemoveAll) { + // Wait for the holding space model to attach. + TestingProfile* profile = GetProfile(); + HoldingSpaceModelAttachedWaiter(profile).Wait(); + + // Verify the holding space `model` is empty. + HoldingSpaceModel* const model = HoldingSpaceController::Get()->model(); + ASSERT_EQ(0u, model->items().size()); + + // Create a test mount point. + std::unique_ptr<ScopedTestMountPoint> mount_point = + ScopedTestMountPoint::CreateAndMountDownloads(profile); + ASSERT_TRUE(mount_point->IsValid()); + + auto* service = + HoldingSpaceKeyedServiceFactory::GetInstance()->GetService(profile); + + // Create files on the file system. + const base::FilePath download_path = mount_point->CreateFile( + /*relative_path=*/base::FilePath("bar"), /*content=*/"bar"); + const base::FilePath pinned_file_path = mount_point->CreateFile( + /*relative_path=*/base::FilePath("foo"), /*content=*/"foo"); + + // Add them both to holding space, one in pinned files the other in downloads. + service->AddDownload(HoldingSpaceItem::Type::kDownload, download_path); + service->AddPinnedFiles( + {file_manager::util::GetFileManagerFileSystemContext(profile) + ->CrackURLInFirstPartyContext( + holding_space_util::ResolveFileSystemUrl(profile, + pinned_file_path))}); + + ASSERT_EQ(2u, model->items().size()); + service->RemoveAll(); + EXPECT_EQ(0u, model->items().size()); +} + // Base class for tests of in-progress downloads integration. Parameterized by // whether the holding space in-progress downloads feature is enabled. class HoldingSpaceKeyedServiceInProgressDownloadsTest
diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc index 57f5b5622..2ef9f7a 100644 --- a/chrome/browser/ui/chrome_pages.cc +++ b/chrome/browser/ui/chrome_pages.cc
@@ -467,6 +467,12 @@ LaunchSystemWebAppAsync(profile, web_app::SystemAppType::DIAGNOSTICS); } +void ShowFirmwareUpdatesApp(Profile* profile) { + DCHECK(base::FeatureList::IsEnabled(chromeos::features::kFirmwareUpdaterApp)); + + LaunchSystemWebAppAsync(profile, web_app::SystemAppType::FIRMWARE_UPDATE); +} + GURL GetOSSettingsUrl(const std::string& sub_page) { DCHECK(sub_page.empty() || chromeos::settings::IsOSSettingsSubPage(sub_page)) << sub_page;
diff --git a/chrome/browser/ui/chrome_pages.h b/chrome/browser/ui/chrome_pages.h index 4b0c7c03..e0c47e5 100644 --- a/chrome/browser/ui/chrome_pages.h +++ b/chrome/browser/ui/chrome_pages.h
@@ -173,6 +173,9 @@ void ShowScanningApp(Profile* profile); void ShowDiagnosticsApp(Profile* profile); + +void ShowFirmwareUpdatesApp(Profile* profile); + #endif #if BUILDFLAG(ENABLE_DICE_SUPPORT)
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc index d315803..6fb7cc85 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/ui/autofill/payments/local_card_migration_dialog_controller_impl.h" #include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -172,25 +173,8 @@ "components/test/data/autofill"); embedded_test_server()->StartAcceptingConnections(); - SyncServiceFactory::GetAsSyncServiceImplForProfile(browser()->profile()) - ->OverrideNetworkForTest( - fake_server::CreateFakeServerHttpPostProviderFactory( - GetFakeServer()->AsWeakPtr())); - std::string username; -#if BUILDFLAG(IS_CHROMEOS_ASH) - // In ChromeOS browser tests, the profile may already by authenticated with - // stub account |user_manager::kStubUserEmail|. - CoreAccountInfo info = - IdentityManagerFactory::GetForProfile(browser()->profile()) - ->GetPrimaryAccountInfo(signin::ConsentLevel::kSync); - username = info.email; -#endif - if (username.empty()) - username = "user@gmail.com"; - - harness_ = SyncServiceImplHarness::Create( - browser()->profile(), username, "password", - SyncServiceImplHarness::SigninType::FAKE_SIGNIN); + ASSERT_TRUE(SetupClients()); + chrome::NewTab(GetBrowser(0)); // Set up the URL loader factory for the payments client so we can intercept // those network requests too. @@ -214,19 +198,18 @@ ->local_card_migration_manager_.get(); local_card_migration_manager_->SetEventObserverForTesting(this); - personal_data_ = - PersonalDataManagerFactory::GetForProfile(browser()->profile()); + personal_data_ = PersonalDataManagerFactory::GetForProfile(GetProfile(0)); // Wait for Personal Data Manager to be fully loaded to prevent that // spurious notifications deceive the tests. - WaitForPersonalDataManagerToBeLoaded(browser()->profile()); + WaitForPersonalDataManagerToBeLoaded(GetProfile(0)); // Set up the fake geolocation data. geolocation_overrider_ = std::make_unique<device::ScopedGeolocationOverrider>( kFakeGeolocationLatitude, kFakeGeolocationLongitude); - ASSERT_TRUE(harness_->SetupSync()); + ASSERT_TRUE(SetupSync()); // Set the billing_customer_number to designate existence of a Payments // account. @@ -249,7 +232,7 @@ void SetPaymentsCustomerData(const PaymentsCustomerData& customer_data) { scoped_refptr<AutofillWebDataService> wds = WebDataServiceFactory::GetAutofillWebDataForProfile( - browser()->profile(), ServiceAccessType::EXPLICIT_ACCESS); + GetProfile(0), ServiceAccessType::EXPLICIT_ACCESS); base::RunLoop loop; wds->GetDBTaskRunner()->PostTaskAndReply( FROM_HERE, @@ -275,9 +258,9 @@ void NavigateTo(const std::string& file_path) { ASSERT_TRUE(ui_test_utils::NavigateToURL( - browser(), file_path.find("data:") == 0U - ? GURL(file_path) - : embedded_test_server()->GetURL(file_path))); + GetBrowser(0), file_path.find("data:") == 0U + ? GURL(file_path) + : embedded_test_server()->GetURL(file_path))); } void OnDecideToRequestLocalCardMigration() override { @@ -314,7 +297,7 @@ if (set_nickname) local_card.SetNickname(u"card nickname"); - AddTestCreditCard(browser()->profile(), local_card); + AddTestCreditCard(GetProfile(0), local_card); return local_card; } @@ -326,7 +309,7 @@ card_number.substr(0, 12)); server_card.set_record_type(CreditCard::FULL_SERVER_CARD); server_card.set_server_id("full_id_" + card_number); - AddTestServerCreditCard(browser()->profile(), server_card); + AddTestServerCreditCard(GetProfile(0), server_card); return server_card; } @@ -468,7 +451,7 @@ PageActionIconView* GetLocalCardMigrationIconView() { BrowserView* browser_view = - BrowserView::GetBrowserViewForBrowser(browser()); + BrowserView::GetBrowserViewForBrowser(GetBrowser(0)); PageActionIconView* icon = browser_view->toolbar_button_provider()->GetPageActionIconView( PageActionIconType::kLocalCardMigration); @@ -499,7 +482,7 @@ } content::WebContents* GetActiveWebContents() { - return browser()->tab_strip_model()->GetActiveWebContents(); + return GetBrowser(0)->tab_strip_model()->GetActiveWebContents(); } void ResetEventWaiterForSequence(std::list<DialogEvent> event_sequence) { @@ -513,15 +496,13 @@ return &test_url_loader_factory_; } - void WaitForCardDeletion() { - WaitForPersonalDataChange(browser()->profile()); - } + void WaitForCardDeletion() { WaitForPersonalDataChange(GetProfile(0)); } void WaitForAnimationToComplete() { if (base::FeatureList::IsEnabled( features::kAutofillEnableToolbarStatusChip)) { views::test::WaitForAnimatingLayoutManager( - BrowserView::GetBrowserViewForBrowser(browser()) + BrowserView::GetBrowserViewForBrowser(GetBrowser(0)) ->toolbar() ->toolbar_account_icon_container()); } @@ -532,8 +513,6 @@ PersonalDataManager* personal_data_; PersonalDataLoadedObserverMock personal_data_observer_; - std::unique_ptr<SyncServiceImplHarness> harness_; - private: std::unique_ptr<autofill::EventWaiter<DialogEvent>> event_waiter_; std::unique_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_; @@ -1062,7 +1041,8 @@ #endif IN_PROC_BROWSER_TEST_F(LocalCardMigrationBrowserTestForStatusChip, MAYBE_ActivateFirstInactiveBubbleForAccessibility) { - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + BrowserView* browser_view = + BrowserView::GetBrowserViewForBrowser(GetBrowser(0)); ToolbarView* toolbar_view = browser_view->toolbar(); EXPECT_FALSE(toolbar_view->toolbar_account_icon_container() ->page_action_icon_controller() @@ -1102,8 +1082,10 @@ EXPECT_TRUE(GetLocalCardMigrationIconView()->GetVisible()); EXPECT_TRUE(GetLocalCardMigrationOfferBubbleViews()->GetVisible()); - AddTabAtIndex(1, GURL("http://example.com/"), ui::PAGE_TRANSITION_TYPED); - TabStripModel* tab_model = browser()->tab_strip_model(); + AddTabAtIndexToBrowser(GetBrowser(0), 1, GURL("http://example.com/"), + ui::PAGE_TRANSITION_TYPED, + /*check_navigation_success=*/true); + TabStripModel* tab_model = GetBrowser(0)->tab_strip_model(); tab_model->ActivateTabAt(1, {TabStripModel::GestureType::kOther}); WaitForAnimationToComplete(); @@ -1196,7 +1178,7 @@ UseCardAndWaitForMigrationOffer(kFirstCardNumber); views::test::WidgetDestroyedWaiter destroyed_waiter( GetLocalCardMigrationOfferBubbleViews()->GetWidget()); - browser()->tab_strip_model()->CloseAllTabs(); + GetBrowser(0)->tab_strip_model()->CloseAllTabs(); destroyed_waiter.Wait(); histogram_tester.ExpectUniqueSample(
diff --git a/chrome/browser/ui/web_applications/web_app_launch_manager.cc b/chrome/browser/ui/web_applications/web_app_launch_manager.cc index df2c401..77991690 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_manager.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_manager.cc
@@ -11,79 +11,31 @@ #include "base/files/file_path.h" #include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" -#include "chrome/browser/app_mode/app_mode_utils.h" #include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/launch_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/browser_navigator.h" -#include "chrome/browser/ui/browser_navigator_params.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/web_applications/app_browser_controller.h" -#include "chrome/browser/ui/web_applications/share_target_utils.h" -#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" +#include "chrome/browser/ui/web_applications/web_app_launch_process.h" #include "chrome/browser/ui/web_applications/web_app_launch_utils.h" -#include "chrome/browser/web_applications/os_integration_manager.h" -#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_install_utils.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/browser/web_applications/web_app_registrar.h" -#include "chrome/browser/web_applications/web_app_sync_bridge.h" -#include "chrome/browser/web_applications/web_app_tab_helper.h" -#include "chrome/browser/web_launch/web_launch_files_helper.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" -#include "components/services/app_service/public/cpp/intent_util.h" -#include "components/site_engagement/content/site_engagement_service.h" -#include "components/webapps/browser/banners/app_banner_settings_helper.h" -#include "content/public/browser/page_navigator.h" #include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/referrer.h" #include "extensions/common/constants.h" #include "third_party/blink/public/common/custom_handlers/protocol_handler_utils.h" -#include "ui/base/page_transition_types.h" #include "ui/base/window_open_disposition.h" -#include "ui/display/display.h" -#include "ui/display/scoped_display_for_new_windows.h" -#include "ui/display/screen.h" #include "url/gurl.h" namespace web_app { namespace { -// TODO(crbug.com/1019239): Passing a WebAppProvider seems to be a bit of an -// anti-pattern. We should refactor this and other existing functions in this -// file to receive an OsIntegrationManager instead. -absl::optional<GURL> GetProtocolHandlingTranslatedUrl( - WebAppProvider& provider, - const apps::AppLaunchParams& params) { - if (!params.protocol_handler_launch_url.has_value()) - return absl::nullopt; - - GURL protocol_url(params.protocol_handler_launch_url.value()); - if (!protocol_url.is_valid()) - return absl::nullopt; - - absl::optional<GURL> translated_url = - provider.os_integration_manager().TranslateProtocolUrl(params.app_id, - protocol_url); - - return translated_url; -} - WebAppLaunchManager::OpenApplicationCallback& GetOpenApplicationCallbackForTesting() { static base::NoDestructor<WebAppLaunchManager::OpenApplicationCallback> @@ -91,323 +43,6 @@ return *callback; } -class LaunchProcess { - public: - LaunchProcess(Profile& profile, const apps::AppLaunchParams& params); - - content::WebContents* Run(); - - private: - const apps::ShareTarget* MaybeGetShareTarget() const; - std::tuple<GURL, bool /*is_file_handling*/> GetLaunchUrl( - const apps::ShareTarget* share_target) const; - WindowOpenDisposition GetNavigationDisposition(bool is_new_browser) const; - content::WebContents* MaybeLaunchSystemWebApp(const GURL& launch_url); - std::tuple<Browser*, bool /*is_new_browser*/> EnsureBrowser(); - LaunchHandler::RouteTo GetLaunchRouteTo() const; - - Browser* MaybeFindBrowserForLaunch() const; - Browser* CreateBrowserForLaunch(); - content::WebContents* NavigateBrowser(Browser* browser, - bool is_new_browser, - const GURL& launch_url, - const apps::ShareTarget* share_target); - void MaybeEnqueueWebLaunchParams(const GURL& launch_url, - bool is_file_handling, - content::WebContents* web_contents); - void RecordMetrics(const GURL& launch_url, - content::WebContents* web_contents); - - Profile& profile_; - WebAppProvider& provider_; - const apps::AppLaunchParams& params_; - const WebApp* web_app_ = nullptr; -}; - -LaunchProcess::LaunchProcess(Profile& profile, - const apps::AppLaunchParams& params) - : profile_(profile), - provider_(*WebAppProvider::GetForLocalAppsUnchecked(&profile)), - params_(params), - web_app_(provider_.registrar().GetAppById(params.app_id)) {} - -content::WebContents* LaunchProcess::Run() { - if (Browser::GetCreationStatusForProfile(&profile_) != - Browser::CreationStatus::kOk || - !provider_.registrar().IsInstalled(params_.app_id)) { - return nullptr; - } - - // Place new windows on the specified display. - display::ScopedDisplayForNewWindows scoped_display(params_.display_id); - - const apps::ShareTarget* share_target = MaybeGetShareTarget(); - GURL launch_url; - bool is_file_handling = false; - std::tie(launch_url, is_file_handling) = GetLaunchUrl(share_target); - -#if defined(OS_CHROMEOS) - // TODO(crbug.com/1265381): URL Handlers allows web apps to be opened with - // associated origin URLs. There's no utility function to test whether a URL - // is in a web app's extended scope at the moment. - // Because URL Handlers is not implemented for Chrome OS we can perform this - // DCHECK on the basic scope. - DCHECK(provider_.registrar().IsUrlInAppScope(launch_url, params_.app_id)); -#endif - - // System Web Apps have their own launch code path. - // TODO(crbug.com/1231886): Don't use a separate code path so that SWAs can - // maintain feature parity with regular web apps (e.g. launch_handler - // behaviours). - content::WebContents* web_contents = MaybeLaunchSystemWebApp(launch_url); - if (web_contents) - return web_contents; - - Browser* browser = nullptr; - bool is_new_browser; - std::tie(browser, is_new_browser) = EnsureBrowser(); - - web_contents = - NavigateBrowser(browser, is_new_browser, launch_url, share_target); - if (!web_contents) - return nullptr; - - MaybeEnqueueWebLaunchParams(launch_url, is_file_handling, web_contents); - - RecordMetrics(launch_url, web_contents); - - return web_contents; -} - -const apps::ShareTarget* LaunchProcess::MaybeGetShareTarget() const { - DCHECK(web_app_); - bool is_share_intent = - params_.intent && - (params_.intent->action == apps_util::kIntentActionSend || - params_.intent->action == apps_util::kIntentActionSendMultiple); - return is_share_intent && web_app_->share_target().has_value() - ? &web_app_->share_target().value() - : nullptr; -} - -std::tuple<GURL, bool /*is_file_handling*/> LaunchProcess::GetLaunchUrl( - const apps::ShareTarget* share_target) const { - DCHECK(web_app_); - GURL launch_url; - bool is_file_handling = false; - bool is_note_taking_intent = - params_.intent && - params_.intent->action == apps_util::kIntentActionCreateNote; - - if (!params_.override_url.is_empty()) { - launch_url = params_.override_url; - } else if (params_.url_handler_launch_url.has_value() && - params_.url_handler_launch_url->is_valid()) { - // Handle url_handlers launch. - launch_url = params_.url_handler_launch_url.value(); - } else if (absl::optional<GURL> file_handler_url = - provider_.os_integration_manager().GetMatchingFileHandlerURL( - params_.app_id, params_.launch_files)) { - // Handle file_handlers launch. - launch_url = file_handler_url.value(); - is_file_handling = true; - } else if (absl::optional<GURL> protocol_handler_translated_url = - GetProtocolHandlingTranslatedUrl(provider_, params_)) { - // Handle protocol_handlers launch. - launch_url = protocol_handler_translated_url.value(); - } else if (share_target) { - // Handle share_target launch. - launch_url = share_target->action; - } else if (is_note_taking_intent && - web_app_->note_taking_new_note_url().is_valid()) { - // Handle Create Note launch. - launch_url = web_app_->note_taking_new_note_url(); - } else { - // This is a default launch. - launch_url = provider_.registrar().GetAppLaunchUrl(params_.app_id); - } - DCHECK(launch_url.is_valid()); - - return {launch_url, is_file_handling}; -} - -WindowOpenDisposition LaunchProcess::GetNavigationDisposition( - bool is_new_browser) const { - if (is_new_browser) { - // By opening a new window we've already performed part of a "disposition", - // the only remaining thing for Navigate() to do is navigate the new window. - return WindowOpenDisposition::CURRENT_TAB; - // TODO(crbug.com/1200944): Use NEW_FOREGROUND_TAB instead of CURRENT_TAB. - // The window has no tabs so it doesn't make sense to open the "current" - // tab. We use it anyway because it happens to work. - // If NEW_FOREGROUND_TAB is used the the WindowCanOpenTabs() check fails - // when `launch_url` is out of scope for web app windows causing it to - // open another separate browser window. It should be updated to check the - // extended scope. - } - - // If launch handler is routing to an existing client, we want to use the - // existing WebContents rather than opening a new tab. - if (GetLaunchRouteTo() == LaunchHandler::RouteTo::kExistingClient) { - return WindowOpenDisposition::CURRENT_TAB; - } - - // Only CURRENT_TAB and NEW_FOREGROUND_TAB dispositions are supported for web - // app launches. - return params_.disposition == WindowOpenDisposition::CURRENT_TAB - ? WindowOpenDisposition::CURRENT_TAB - : WindowOpenDisposition::NEW_FOREGROUND_TAB; -} - -LaunchHandler::RouteTo LaunchProcess::GetLaunchRouteTo() const { - DCHECK(web_app_); - LaunchHandler launch_handler = - web_app_->launch_handler().value_or(LaunchHandler()); - if (launch_handler.route_to == LaunchHandler::RouteTo::kAuto) - return LaunchHandler::RouteTo::kNewClient; - return launch_handler.route_to; -} - -content::WebContents* LaunchProcess::MaybeLaunchSystemWebApp( - const GURL& launch_url) { - absl::optional<SystemAppType> system_app_type = - GetSystemWebAppTypeForAppId(&profile_, params_.app_id); - if (!system_app_type) - return nullptr; - - Browser* browser = - LaunchSystemWebAppImpl(&profile_, *system_app_type, launch_url, params_); - return browser->tab_strip_model()->GetActiveWebContents(); -} - -std::tuple<Browser*, bool /*is_new_browser*/> LaunchProcess::EnsureBrowser() { - Browser* browser = MaybeFindBrowserForLaunch(); - bool is_new_browser = false; - if (browser) { - browser->window()->Activate(); - } else { - browser = CreateBrowserForLaunch(); - is_new_browser = true; - } - browser->window()->Show(); - return {browser, is_new_browser}; -} - -Browser* LaunchProcess::MaybeFindBrowserForLaunch() const { - if (params_.container == apps::mojom::LaunchContainer::kLaunchContainerTab) { - return chrome::FindTabbedBrowser( - &profile_, /*match_original_profiles=*/false, - display::Screen::GetScreen()->GetDisplayForNewWindows().id()); - } - - if (!provider_.registrar().IsTabbedWindowModeEnabled(params_.app_id) && - GetLaunchRouteTo() == LaunchHandler::RouteTo::kNewClient) { - return nullptr; - } - - for (Browser* browser : *BrowserList::GetInstance()) { - if (browser->profile() == &profile_ && - AppBrowserController::IsForWebApp(browser, params_.app_id)) { - return browser; - } - } - - return nullptr; -} - -Browser* LaunchProcess::CreateBrowserForLaunch() { - if (params_.container == apps::mojom::LaunchContainer::kLaunchContainerTab) { - return Browser::Create(Browser::CreateParams(Browser::TYPE_NORMAL, - &profile_, - /*user_gesture=*/true)); - } - - return CreateWebApplicationWindow(&profile_, params_.app_id, - params_.disposition, params_.restore_id); -} - -content::WebContents* LaunchProcess::NavigateBrowser( - Browser* browser, - bool is_new_browser, - const GURL& launch_url, - const apps::ShareTarget* share_target) { - WindowOpenDisposition navigation_disposition = - GetNavigationDisposition(is_new_browser); - - if (share_target) { - NavigateParams nav_params = - NavigateParamsForShareTarget(browser, *share_target, *params_.intent); - nav_params.disposition = navigation_disposition; - return NavigateWebAppUsingParams(params_.app_id, nav_params); - } - - TabStripModel* const tab_strip = browser->tab_strip_model(); - if (tab_strip->empty() || - navigation_disposition != WindowOpenDisposition::CURRENT_TAB) { - return NavigateWebApplicationWindow(browser, params_.app_id, launch_url, - navigation_disposition); - } - - content::WebContents* existing_tab = tab_strip->GetActiveWebContents(); - DCHECK(existing_tab); - const int tab_index = tab_strip->GetIndexOfWebContents(existing_tab); - - existing_tab->OpenURL(content::OpenURLParams( - launch_url, - content::Referrer::SanitizeForRequest( - launch_url, - content::Referrer(existing_tab->GetURL(), - network::mojom::ReferrerPolicy::kDefault)), - navigation_disposition, ui::PAGE_TRANSITION_AUTO_BOOKMARK, - /*is_renderer_initiated=*/false)); - - content::WebContents* web_contents = tab_strip->GetActiveWebContents(); - tab_strip->ActivateTabAt(tab_index, {TabStripModel::GestureType::kOther}); - WebAppTabHelper::FromWebContents(web_contents)->SetAppId(params_.app_id); - return web_contents; -} - -void LaunchProcess::MaybeEnqueueWebLaunchParams( - const GURL& launch_url, - bool is_file_handling, - content::WebContents* web_contents) { - if (is_file_handling || web_app_->launch_handler().has_value()) { - web_launch::WebLaunchFilesHelper::EnqueueLaunchParams( - web_contents, provider_.registrar().GetAppScope(web_app_->app_id()), - /*await_navigation=*/true, launch_url, - /*launch_dir=*/{}, - is_file_handling ? params_.launch_files - : std::vector<base::FilePath>()); - } -} - -void LaunchProcess::RecordMetrics(const GURL& launch_url, - content::WebContents* web_contents) { - // TODO(crbug.com/1014328): Populate WebApp metrics instead of Extensions. - if (params_.container == apps::mojom::LaunchContainer::kLaunchContainerTab) { - UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", - extensions::LAUNCH_TYPE_REGULAR, 100); - } else if (params_.container == - apps::mojom::LaunchContainer::kLaunchContainerWindow) { - RecordAppWindowLaunch(&profile_, params_.app_id); - } - UMA_HISTOGRAM_ENUMERATION("Extensions.BookmarkAppLaunchSource", - apps::GetAppLaunchSource(params_.launch_source)); - UMA_HISTOGRAM_ENUMERATION("Extensions.BookmarkAppLaunchContainer", - params_.container); - - // Record the launch time in the site engagement service. A recent web - // app launch will provide an engagement boost to the origin. - site_engagement::SiteEngagementService::Get(&profile_) - ->SetLastShortcutLaunchTime(web_contents, launch_url); - provider_.sync_bridge().SetAppLastLaunchTime(params_.app_id, - base::Time::Now()); - // Refresh the app banner added to homescreen event. The user may have - // cleared their browsing data since installing the app, which removes the - // event and will potentially permit a banner to be shown for the site. - RecordAppBanner(web_contents, launch_url); -} - } // namespace WebAppLaunchManager::WebAppLaunchManager(Profile* profile) @@ -421,7 +56,7 @@ if (GetOpenApplicationCallbackForTesting()) return GetOpenApplicationCallbackForTesting().Run(std::move(params)); - return LaunchProcess(*profile_, params).Run(); + return WebAppLaunchProcess(*profile_, params).Run(); } void WebAppLaunchManager::LaunchApplication(
diff --git a/chrome/browser/ui/web_applications/web_app_launch_process.cc b/chrome/browser/ui/web_applications/web_app_launch_process.cc new file mode 100644 index 0000000..05aaa20a --- /dev/null +++ b/chrome/browser/ui/web_applications/web_app_launch_process.cc
@@ -0,0 +1,345 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/web_applications/web_app_launch_process.h" + +#include "base/files/file_path.h" +#include "base/metrics/histogram_macros.h" +#include "build/build_config.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" +#include "chrome/browser/apps/app_service/launch_utils.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_navigator_params.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/web_applications/app_browser_controller.h" +#include "chrome/browser/ui/web_applications/share_target_utils.h" +#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" +#include "chrome/browser/ui/web_applications/web_app_launch_utils.h" +#include "chrome/browser/web_applications/os_integration_manager.h" +#include "chrome/browser/web_applications/web_app.h" +#include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/browser/web_applications/web_app_registrar.h" +#include "chrome/browser/web_applications/web_app_sync_bridge.h" +#include "chrome/browser/web_applications/web_app_tab_helper.h" +#include "chrome/browser/web_launch/web_launch_files_helper.h" +#include "components/services/app_service/public/cpp/intent_util.h" +#include "components/site_engagement/content/site_engagement_service.h" +#include "extensions/common/constants.h" +#include "ui/display/scoped_display_for_new_windows.h" +#include "url/gurl.h" + +namespace web_app { + +namespace { + +absl::optional<GURL> GetProtocolHandlingTranslatedUrl( + OsIntegrationManager& os_integration_manager, + const apps::AppLaunchParams& params) { + if (!params.protocol_handler_launch_url.has_value()) + return absl::nullopt; + + GURL protocol_url(params.protocol_handler_launch_url.value()); + if (!protocol_url.is_valid()) + return absl::nullopt; + + absl::optional<GURL> translated_url = + os_integration_manager.TranslateProtocolUrl(params.app_id, protocol_url); + + return translated_url; +} + +} // namespace + +WebAppLaunchProcess::WebAppLaunchProcess(Profile& profile, + const apps::AppLaunchParams& params) + : profile_(profile), + provider_(*WebAppProvider::GetForLocalAppsUnchecked(&profile)), + params_(params), + web_app_(provider_.registrar().GetAppById(params.app_id)) {} + +content::WebContents* WebAppLaunchProcess::Run() { + if (Browser::GetCreationStatusForProfile(&profile_) != + Browser::CreationStatus::kOk || + !provider_.registrar().IsInstalled(params_.app_id)) { + return nullptr; + } + + // Place new windows on the specified display. + display::ScopedDisplayForNewWindows scoped_display(params_.display_id); + + const apps::ShareTarget* share_target = MaybeGetShareTarget(); + GURL launch_url; + bool is_file_handling = false; + std::tie(launch_url, is_file_handling) = GetLaunchUrl(share_target); + +#if defined(OS_CHROMEOS) + // TODO(crbug.com/1265381): URL Handlers allows web apps to be opened with + // associated origin URLs. There's no utility function to test whether a URL + // is in a web app's extended scope at the moment. + // Because URL Handlers is not implemented for Chrome OS we can perform this + // DCHECK on the basic scope. + DCHECK(provider_.registrar().IsUrlInAppScope(launch_url, params_.app_id)); +#endif + + // System Web Apps have their own launch code path. + // TODO(crbug.com/1231886): Don't use a separate code path so that SWAs can + // maintain feature parity with regular web apps (e.g. launch_handler + // behaviours). + content::WebContents* web_contents = MaybeLaunchSystemWebApp(launch_url); + if (web_contents) + return web_contents; + + Browser* browser = nullptr; + bool is_new_browser; + std::tie(browser, is_new_browser) = EnsureBrowser(); + + web_contents = + NavigateBrowser(browser, is_new_browser, launch_url, share_target); + if (!web_contents) + return nullptr; + + MaybeEnqueueWebLaunchParams(launch_url, is_file_handling, web_contents); + + RecordMetrics(launch_url, web_contents); + + return web_contents; +} + +const apps::ShareTarget* WebAppLaunchProcess::MaybeGetShareTarget() const { + DCHECK(web_app_); + bool is_share_intent = + params_.intent && + (params_.intent->action == apps_util::kIntentActionSend || + params_.intent->action == apps_util::kIntentActionSendMultiple); + return is_share_intent && web_app_->share_target().has_value() + ? &web_app_->share_target().value() + : nullptr; +} + +std::tuple<GURL, bool /*is_file_handling*/> WebAppLaunchProcess::GetLaunchUrl( + const apps::ShareTarget* share_target) const { + DCHECK(web_app_); + GURL launch_url; + bool is_file_handling = false; + bool is_note_taking_intent = + params_.intent && + params_.intent->action == apps_util::kIntentActionCreateNote; + + if (!params_.override_url.is_empty()) { + launch_url = params_.override_url; + } else if (params_.url_handler_launch_url.has_value() && + params_.url_handler_launch_url->is_valid()) { + // Handle url_handlers launch. + launch_url = params_.url_handler_launch_url.value(); + } else if (absl::optional<GURL> file_handler_url = + provider_.os_integration_manager().GetMatchingFileHandlerURL( + params_.app_id, params_.launch_files)) { + // Handle file_handlers launch. + launch_url = file_handler_url.value(); + is_file_handling = true; + } else if (absl::optional<GURL> protocol_handler_translated_url = + GetProtocolHandlingTranslatedUrl( + provider_.os_integration_manager(), params_)) { + // Handle protocol_handlers launch. + launch_url = protocol_handler_translated_url.value(); + } else if (share_target) { + // Handle share_target launch. + launch_url = share_target->action; + } else if (is_note_taking_intent && + web_app_->note_taking_new_note_url().is_valid()) { + // Handle Create Note launch. + launch_url = web_app_->note_taking_new_note_url(); + } else { + // This is a default launch. + launch_url = provider_.registrar().GetAppLaunchUrl(params_.app_id); + } + DCHECK(launch_url.is_valid()); + + return {launch_url, is_file_handling}; +} + +WindowOpenDisposition WebAppLaunchProcess::GetNavigationDisposition( + bool is_new_browser) const { + if (is_new_browser) { + // By opening a new window we've already performed part of a "disposition", + // the only remaining thing for Navigate() to do is navigate the new window. + return WindowOpenDisposition::CURRENT_TAB; + // TODO(crbug.com/1200944): Use NEW_FOREGROUND_TAB instead of CURRENT_TAB. + // The window has no tabs so it doesn't make sense to open the "current" + // tab. We use it anyway because it happens to work. + // If NEW_FOREGROUND_TAB is used the the WindowCanOpenTabs() check fails + // when `launch_url` is out of scope for web app windows causing it to + // open another separate browser window. It should be updated to check the + // extended scope. + } + + // If launch handler is routing to an existing client, we want to use the + // existing WebContents rather than opening a new tab. + if (GetLaunchRouteTo() == LaunchHandler::RouteTo::kExistingClient) { + return WindowOpenDisposition::CURRENT_TAB; + } + + // Only CURRENT_TAB and NEW_FOREGROUND_TAB dispositions are supported for web + // app launches. + return params_.disposition == WindowOpenDisposition::CURRENT_TAB + ? WindowOpenDisposition::CURRENT_TAB + : WindowOpenDisposition::NEW_FOREGROUND_TAB; +} + +LaunchHandler::RouteTo WebAppLaunchProcess::GetLaunchRouteTo() const { + DCHECK(web_app_); + LaunchHandler launch_handler = + web_app_->launch_handler().value_or(LaunchHandler()); + if (launch_handler.route_to == LaunchHandler::RouteTo::kAuto) + return LaunchHandler::RouteTo::kNewClient; + return launch_handler.route_to; +} + +content::WebContents* WebAppLaunchProcess::MaybeLaunchSystemWebApp( + const GURL& launch_url) { + absl::optional<SystemAppType> system_app_type = + GetSystemWebAppTypeForAppId(&profile_, params_.app_id); + if (!system_app_type) + return nullptr; + + Browser* browser = + LaunchSystemWebAppImpl(&profile_, *system_app_type, launch_url, params_); + return browser->tab_strip_model()->GetActiveWebContents(); +} + +std::tuple<Browser*, bool /*is_new_browser*/> +WebAppLaunchProcess::EnsureBrowser() { + Browser* browser = MaybeFindBrowserForLaunch(); + bool is_new_browser = false; + if (browser) { + browser->window()->Activate(); + } else { + browser = CreateBrowserForLaunch(); + is_new_browser = true; + } + browser->window()->Show(); + return {browser, is_new_browser}; +} + +Browser* WebAppLaunchProcess::MaybeFindBrowserForLaunch() const { + if (params_.container == apps::mojom::LaunchContainer::kLaunchContainerTab) { + return chrome::FindTabbedBrowser( + &profile_, /*match_original_profiles=*/false, + display::Screen::GetScreen()->GetDisplayForNewWindows().id()); + } + + if (!provider_.registrar().IsTabbedWindowModeEnabled(params_.app_id) && + GetLaunchRouteTo() == LaunchHandler::RouteTo::kNewClient) { + return nullptr; + } + + for (Browser* browser : *BrowserList::GetInstance()) { + if (browser->profile() == &profile_ && + AppBrowserController::IsForWebApp(browser, params_.app_id)) { + return browser; + } + } + + return nullptr; +} + +Browser* WebAppLaunchProcess::CreateBrowserForLaunch() { + if (params_.container == apps::mojom::LaunchContainer::kLaunchContainerTab) { + return Browser::Create(Browser::CreateParams(Browser::TYPE_NORMAL, + &profile_, + /*user_gesture=*/true)); + } + + return CreateWebApplicationWindow(&profile_, params_.app_id, + params_.disposition, params_.restore_id); +} + +content::WebContents* WebAppLaunchProcess::NavigateBrowser( + Browser* browser, + bool is_new_browser, + const GURL& launch_url, + const apps::ShareTarget* share_target) { + WindowOpenDisposition navigation_disposition = + GetNavigationDisposition(is_new_browser); + + if (share_target) { + NavigateParams nav_params = + NavigateParamsForShareTarget(browser, *share_target, *params_.intent); + nav_params.disposition = navigation_disposition; + return NavigateWebAppUsingParams(params_.app_id, nav_params); + } + + TabStripModel* const tab_strip = browser->tab_strip_model(); + if (tab_strip->empty() || + navigation_disposition != WindowOpenDisposition::CURRENT_TAB) { + return NavigateWebApplicationWindow(browser, params_.app_id, launch_url, + navigation_disposition); + } + + content::WebContents* existing_tab = tab_strip->GetActiveWebContents(); + DCHECK(existing_tab); + const int tab_index = tab_strip->GetIndexOfWebContents(existing_tab); + + existing_tab->OpenURL(content::OpenURLParams( + launch_url, + content::Referrer::SanitizeForRequest( + launch_url, + content::Referrer(existing_tab->GetURL(), + network::mojom::ReferrerPolicy::kDefault)), + navigation_disposition, ui::PAGE_TRANSITION_AUTO_BOOKMARK, + /*is_renderer_initiated=*/false)); + + content::WebContents* web_contents = tab_strip->GetActiveWebContents(); + tab_strip->ActivateTabAt(tab_index, {TabStripModel::GestureType::kOther}); + WebAppTabHelper::FromWebContents(web_contents)->SetAppId(params_.app_id); + return web_contents; +} + +void WebAppLaunchProcess::MaybeEnqueueWebLaunchParams( + const GURL& launch_url, + bool is_file_handling, + content::WebContents* web_contents) { + if (is_file_handling || web_app_->launch_handler().has_value()) { + web_launch::WebLaunchFilesHelper::EnqueueLaunchParams( + web_contents, provider_.registrar().GetAppScope(web_app_->app_id()), + /*await_navigation=*/true, launch_url, + /*launch_dir=*/{}, + is_file_handling ? params_.launch_files + : std::vector<base::FilePath>()); + } +} + +void WebAppLaunchProcess::RecordMetrics(const GURL& launch_url, + content::WebContents* web_contents) { + // TODO(crbug.com/1014328): Populate WebApp metrics instead of Extensions. + if (params_.container == apps::mojom::LaunchContainer::kLaunchContainerTab) { + UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", + extensions::LAUNCH_TYPE_REGULAR, 100); + } else if (params_.container == + apps::mojom::LaunchContainer::kLaunchContainerWindow) { + RecordAppWindowLaunch(&profile_, params_.app_id); + } + UMA_HISTOGRAM_ENUMERATION("Extensions.BookmarkAppLaunchSource", + apps::GetAppLaunchSource(params_.launch_source)); + UMA_HISTOGRAM_ENUMERATION("Extensions.BookmarkAppLaunchContainer", + params_.container); + + // Record the launch time in the site engagement service. A recent web + // app launch will provide an engagement boost to the origin. + site_engagement::SiteEngagementService::Get(&profile_) + ->SetLastShortcutLaunchTime(web_contents, launch_url); + provider_.sync_bridge().SetAppLastLaunchTime(params_.app_id, + base::Time::Now()); + // Refresh the app banner added to homescreen event. The user may have + // cleared their browsing data since installing the app, which removes the + // event and will potentially permit a banner to be shown for the site. + RecordAppBanner(web_contents, launch_url); +} + +} // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_launch_process.h b/chrome/browser/ui/web_applications/web_app_launch_process.h new file mode 100644 index 0000000..d30d220 --- /dev/null +++ b/chrome/browser/ui/web_applications/web_app_launch_process.h
@@ -0,0 +1,73 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_PROCESS_H_ +#define CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_PROCESS_H_ + +#include "base/memory/raw_ptr.h" +#include "third_party/blink/public/common/manifest/manifest.h" + +class Browser; +enum class WindowOpenDisposition; +class GURL; +class Profile; + +namespace apps { +struct AppLaunchParams; +struct ShareTarget; +} // namespace apps + +namespace content { +class WebContents; +} // namespace content + +namespace web_app { + +class WebApp; +class WebAppProvider; + +// Used by WebAppLaunchManager, this executes an individual launch of a web app +// from any entry point (OS launcher, file handler, protocol handler, +// link capturing, etc.). +// +// Implements the behaviour of the `launch_handler` manifest field: +// https://github.com/WICG/sw-launch/blob/main/launch_handler.md +class WebAppLaunchProcess { + public: + WebAppLaunchProcess(Profile& profile, const apps::AppLaunchParams& params); + WebAppLaunchProcess(const WebAppLaunchProcess&) = delete; + + content::WebContents* Run(); + + private: + using RouteTo = blink::Manifest::LaunchHandler::RouteTo; + const apps::ShareTarget* MaybeGetShareTarget() const; + std::tuple<GURL, bool /*is_file_handling*/> GetLaunchUrl( + const apps::ShareTarget* share_target) const; + WindowOpenDisposition GetNavigationDisposition(bool is_new_browser) const; + content::WebContents* MaybeLaunchSystemWebApp(const GURL& launch_url); + std::tuple<Browser*, bool /*is_new_browser*/> EnsureBrowser(); + RouteTo GetLaunchRouteTo() const; + + Browser* MaybeFindBrowserForLaunch() const; + Browser* CreateBrowserForLaunch(); + content::WebContents* NavigateBrowser(Browser* browser, + bool is_new_browser, + const GURL& launch_url, + const apps::ShareTarget* share_target); + void MaybeEnqueueWebLaunchParams(const GURL& launch_url, + bool is_file_handling, + content::WebContents* web_contents); + void RecordMetrics(const GURL& launch_url, + content::WebContents* web_contents); + + Profile& profile_; + WebAppProvider& provider_; + const apps::AppLaunchParams& params_; + const raw_ptr<const WebApp> web_app_; +}; + +} // namespace web_app + +#endif // CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_PROCESS_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.cc index 6487b3a9..1b8d5bf9 100644 --- a/chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.cc
@@ -30,10 +30,6 @@ IDS_LACROS_DATA_MIGRATION_SCREEN_TITLE); builder->Add("lacrosDataMigrationSubtitle", IDS_LACROS_DATA_MIGRATION_SCREEN_SUBTITLE); - builder->Add("lacrosDataMigrationSkipButton", - IDS_LACROS_DATA_MIGRATION_SCREEN_SKIP_BUTTON); - builder->Add("lacrosDataMigrationSkipSuggestion", - IDS_LACROS_DATA_MIGRATION_SCREEN_SKIP_SUGGESTION); } void LacrosDataMigrationScreenHandler::Bind(LacrosDataMigrationScreen* screen) { @@ -58,10 +54,6 @@ CallJS("login.LacrosDataMigrationScreen.setProgressValue", progress); } -void LacrosDataMigrationScreenHandler::ShowSkipButton() { - CallJS("login.LacrosDataMigrationScreen.showSkipButton"); -} - void LacrosDataMigrationScreenHandler::Initialize() { if (show_on_init_) { Show();
diff --git a/chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.h index e2f03e3e..3f356154 100644 --- a/chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.h
@@ -32,9 +32,6 @@ // Updates the progress bar. virtual void SetProgressValue(int progress) = 0; - - // Displays the skip button. - virtual void ShowSkipButton() = 0; }; class LacrosDataMigrationScreenHandler : public BaseScreenHandler, @@ -59,7 +56,6 @@ void Unbind() override; void Show() override; void SetProgressValue(int progress) override; - void ShowSkipButton() override; private: // BaseScreenHandler:
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc index fa39673..127f194 100644 --- a/chrome/browser/ui/webui/settings/about_handler.cc +++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -287,6 +287,12 @@ "openDiagnostics", base::BindRepeating(&AboutHandler::HandleOpenDiagnostics, base::Unretained(this))); + + web_ui()->RegisterDeprecatedMessageCallback( + "openFirmwareUpdatesPage", + base::BindRepeating(&AboutHandler::HandleOpenFirmwareUpdates, + base::Unretained(this))); + web_ui()->RegisterDeprecatedMessageCallback( "openOsHelpPage", base::BindRepeating(&AboutHandler::HandleOpenOsHelpPage, base::Unretained(this))); @@ -439,6 +445,11 @@ chrome::ShowDiagnosticsApp(profile_); } +void AboutHandler::HandleOpenFirmwareUpdates(const base::ListValue* args) { + DCHECK(args->GetList().empty()); + chrome::ShowFirmwareUpdatesApp(profile_); +} + void AboutHandler::HandleCheckInternetConnection(const base::ListValue* args) { CHECK_EQ(1U, args->GetList().size()); const std::string& callback_id = args->GetList()[0].GetString();
diff --git a/chrome/browser/ui/webui/settings/about_handler.h b/chrome/browser/ui/webui/settings/about_handler.h index eba44e0..7ad6f8d 100644 --- a/chrome/browser/ui/webui/settings/about_handler.h +++ b/chrome/browser/ui/webui/settings/about_handler.h
@@ -158,6 +158,8 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) void HandleOpenDiagnostics(const base::ListValue* args); + void HandleOpenFirmwareUpdates(const base::ListValue* args); + void HandleGetRegulatoryInfo(const base::ListValue* args); // Callback for when the directory with the regulatory label image and alt
diff --git a/chrome/browser/ui/webui/settings/chromeos/about_section.cc b/chrome/browser/ui/webui/settings/chromeos/about_section.cc index 04a3864..722dcce 100644 --- a/chrome/browser/ui/webui/settings/chromeos/about_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/about_section.cc
@@ -113,6 +113,18 @@ return *tags; } +const std::vector<SearchConcept>& GetFirmwareUpdatesAppSearchConcepts() { + static const base::NoDestructor<std::vector<SearchConcept>> tags({ + {IDS_OS_SETTINGS_TAG_ABOUT_FIRMWARE_UPDATES, + mojom::kAboutChromeOsDetailsSubpagePath, + mojom::SearchResultIcon::kChrome, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kFirmwareUpdates}}, + }); + return *tags; +} + const std::vector<SearchConcept>& GetDeviceNameSearchConcepts() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_OS_SETTINGS_TAG_ABOUT_DEVICE_NAME, @@ -200,6 +212,10 @@ updater.AddSearchTags(GetDiagnosticsAppSearchConcepts()); } + if (base::FeatureList::IsEnabled(chromeos::features::kFirmwareUpdaterApp)) { + updater.AddSearchTags(GetFirmwareUpdatesAppSearchConcepts()); + } + if (base::FeatureList::IsEnabled( chromeos::features::kEnableHostnameSetting)) { updater.AddSearchTags(GetDeviceNameSearchConcepts()); @@ -216,6 +232,7 @@ {"aboutReportAnIssue", IDS_SETTINGS_ABOUT_PAGE_REPORT_AN_ISSUE}, #endif {"aboutDiagnostics", IDS_SETTINGS_ABOUT_PAGE_DIAGNOSTICS}, + {"aboutFirmwareUpdates", IDS_SETTINGS_ABOUT_PAGE_FIRMWARE_UPDATES}, {"aboutRelaunch", IDS_SETTINGS_ABOUT_PAGE_RELAUNCH}, {"aboutUpgradeCheckStarted", IDS_SETTINGS_ABOUT_UPGRADE_CHECK_STARTED}, {"aboutUpgradeRelaunch", IDS_SETTINGS_UPGRADE_SUCCESSFUL_RELAUNCH}, @@ -390,6 +407,10 @@ "diagnosticsAppEnabled", base::FeatureList::IsEnabled(chromeos::features::kDiagnosticsApp)); + html_source->AddBoolean( + "isFirmwareUpdaterAppEnabled", + base::FeatureList::IsEnabled(chromeos::features::kFirmwareUpdaterApp)); + #if BUILDFLAG(GOOGLE_CHROME_BRANDING) html_source->AddString("aboutTermsURL", chrome::kChromeUITermsURL); html_source->AddLocalizedString("aboutProductTos", @@ -439,7 +460,8 @@ static constexpr mojom::Setting kAboutChromeOsDetailsSettings[] = { mojom::Setting::kCheckForOsUpdate, mojom::Setting::kSeeWhatsNew, mojom::Setting::kGetHelpWithChromeOs, mojom::Setting::kReportAnIssue, - mojom::Setting::kTermsOfService, mojom::Setting::kDiagnostics}; + mojom::Setting::kTermsOfService, mojom::Setting::kDiagnostics, + mojom::Setting::kFirmwareUpdates}; RegisterNestedSettingBulk(mojom::Subpage::kAboutChromeOsDetails, kAboutChromeOsDetailsSettings, generator);
diff --git a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom index 73e7e29..a0be0d5c9 100644 --- a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom +++ b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
@@ -200,6 +200,7 @@ kAddFingerprintV2 = 1111, kRemoveFingerprintV2 = 1112, kPeripheralDataAccessProtection = 1113, + kSnoopingProtection = 1114, // Languages and Input section. kAddLanguage = 1200, @@ -267,6 +268,7 @@ kTermsOfService = 1706, kDiagnostics = 1707, kChangeDeviceName = 1708, + kFirmwareUpdates = 1709, // Kerberos section. kAddKerberosTicketV2 = 1800,
diff --git a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc index 6abfc21b..b591ae9 100644 --- a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
@@ -109,8 +109,6 @@ {.subpage = mojom::Subpage::kSecurityAndSignInV2}}}); } - // TODO(chromium:1262869): add smart privacy search concepts. - return all_tags; }()); @@ -164,6 +162,26 @@ return *tags; } +const std::vector<SearchConcept>& GetSmartPrivacySearchConcepts() { + static const base::NoDestructor<std::vector<SearchConcept>> tags( + {{IDS_OS_SETTINGS_TAG_SMART_PRIVACY_SNOOPING, + mojom::kSmartPrivacySubpagePath, + mojom::SearchResultIcon::kShield, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kSnoopingProtection}, + {IDS_OS_SETTINGS_TAG_SMART_PRIVACY_SNOOPING_ALT1, + IDS_OS_SETTINGS_TAG_SMART_PRIVACY_SNOOPING_ALT2}}, + {IDS_OS_SETTINGS_TAG_SMART_PRIVACY, + mojom::kSmartPrivacySubpagePath, + mojom::SearchResultIcon::kShield, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSubpage, + {.subpage = mojom::Subpage::kSmartPrivacy}}}); + + return *tags; +} + #if BUILDFLAG(GOOGLE_CHROME_BRANDING) const std::vector<SearchConcept>& GetPrivacyGoogleChromeSearchConcepts() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ @@ -218,6 +236,10 @@ if (chromeos::features::IsPciguardUiEnabled()) { updater.AddSearchTags(GetPciguardSearchConcepts()); } + + if (ash::features::IsSnoopingProtectionEnabled()) { + updater.AddSearchTags(GetSmartPrivacySearchConcepts()); + } } PrivacySection::~PrivacySection() = default; @@ -375,6 +397,8 @@ IDS_OS_SETTINGS_SMART_PRIVACY_TITLE, mojom::Subpage::kSmartPrivacy, mojom::SearchResultIcon::kShield, mojom::SearchResultDefaultRank::kMedium, mojom::kSmartPrivacySubpagePath); + RegisterNestedSettingBulk(mojom::Subpage::kSmartPrivacy, + {{mojom::Setting::kSnoopingProtection}}, generator); } bool PrivacySection::AreFingerprintSettingsAllowed() {
diff --git a/chrome/browser/web_applications/app_service/web_apps.h b/chrome/browser/web_applications/app_service/web_apps.h index b5545f2..10792d5 100644 --- a/chrome/browser/web_applications/app_service/web_apps.h +++ b/chrome/browser/web_applications/app_service/web_apps.h
@@ -12,6 +12,7 @@ #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" #include "build/chromeos_buildflags.h" +#include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "chrome/browser/web_applications/app_service/web_app_publisher_helper.h" #include "chrome/browser/web_applications/web_app_id.h"
diff --git a/chrome/browser/web_applications/web_app_proto_utils.cc b/chrome/browser/web_applications/web_app_proto_utils.cc index f86d7ee..f9cdd478 100644 --- a/chrome/browser/web_applications/web_app_proto_utils.cc +++ b/chrome/browser/web_applications/web_app_proto_utils.cc
@@ -81,6 +81,9 @@ } sync_pb::WebAppSpecifics WebAppToSyncProto(const WebApp& app) { + DCHECK(!app.start_url().is_empty()); + DCHECK(app.start_url().is_valid()); + sync_pb::WebAppSpecifics sync_proto; if (app.manifest_id().has_value()) sync_proto.set_manifest_id(app.manifest_id().value());
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.cc b/chrome/browser/web_applications/web_app_sync_bridge.cc index 2a96e647..bcaa1129 100644 --- a/chrome/browser/web_applications/web_app_sync_bridge.cc +++ b/chrome/browser/web_applications/web_app_sync_bridge.cc
@@ -771,8 +771,10 @@ const sync_pb::WebAppSpecifics& specifics = entity_data.specifics.web_app(); const GURL start_url(specifics.start_url()); - DCHECK(!start_url.is_empty()); - DCHECK(start_url.is_valid()); + if (start_url.is_empty() || !start_url.is_valid()) { + DLOG(ERROR) << "GetClientTag: start_url parse error."; + return std::string(); + } absl::optional<std::string> manifest_id = absl::nullopt; if (specifics.has_manifest_id())
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index e759ccb..cc59f4b 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1637193204-e5ba9fe8d9b1fbcf3ae90b98f1e62d3e080b3ec9.profdata +chrome-linux-main-1637235889-a85b2f13939122953dd1cce0e97f01f74feaac2b.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 19cf1d7..66e3476 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1637193204-c44e60b3a110e5e789228a478afd2d9380a13d10.profdata +chrome-mac-main-1637235889-f25cd44c04387a04a9b21fff487f282cb21ec2ac.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 8792be2..720bbd3 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1637193204-05f8a04b3a0697b9b788db1fd49e1c4abaa13560.profdata +chrome-win32-main-1637225975-91b3bd1fe58f1ba9d31308244df09804bcdf4f19.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index fb3ff24..33fc82c 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1637193204-57a455ee87b529d85233e774f3d3faeb8bc7446b.profdata +chrome-win64-main-1637225975-57c417340ab5182751e354c1b5154d63f3e2ea4e.profdata
diff --git a/chrome/common/extensions/api/autotest_private.idl b/chrome/common/extensions/api/autotest_private.idl index 8626d70..f604db6 100644 --- a/chrome/common/extensions/api/autotest_private.idl +++ b/chrome/common/extensions/api/autotest_private.idl
@@ -587,6 +587,14 @@ // getDisplaySmoothness is called. callback GetDisplaySmoothnessCallback = void (long smoothness); + // Options for resetting the holding space. + dictionary ResetHoldingSpaceOptions { + // Whether to call `ash::holding_space_prefs::MarkTimeOfFirstAdd()` after + // reset. Used to show the holding space tray in tests, since it's otherwise + // hidden after OOBE. + boolean markTimeOfFirstAdd; + }; + interface Functions { // Must be called to allow autotestPrivateAPI events to be fired. static void initializeEvents(); @@ -1202,6 +1210,11 @@ [supportsPromises] static void getDisplaySmoothness( optional DOMString displayId, GetDisplaySmoothnessCallback callback); + + // Resets the holding space by removing all items and clearing the prefs. + [supportsPromises] static void resetHoldingSpace( + optional ResetHoldingSpaceOptions options, + VoidCallback callback); }; interface Events {
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 27fd89f7..1289572 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -271,6 +271,7 @@ const char kChromeUICryptohomeHost[] = "cryptohome"; const char kChromeUIDeviceEmulatorHost[] = "device-emulator"; const char kChromeUIDiagnosticsAppURL[] = "chrome://diagnostics"; +const char kChromeUIFirmwareUpdatesAppURL[] = "chrome://accessory-update"; const char kChromeUIIntenetConfigDialogURL[] = "chrome://internet-config-dialog/"; const char kChromeUIIntenetDetailDialogURL[] =
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index def804a..10fb1f2 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -261,6 +261,7 @@ extern const char kChromeUIDiagnosticsAppURL[]; extern const char kChromeUIEmojiPickerURL[]; extern const char kChromeUIEmojiPickerHost[]; +extern const char kChromeUIFirmwareUpdatesAppURL[]; extern const char kChromeUIIntenetConfigDialogURL[]; extern const char kChromeUIIntenetDetailDialogURL[]; extern const char kChromeUIInternetConfigDialogHost[];
diff --git a/chrome/services/sharing/nearby/platform/wifi_lan_socket.cc b/chrome/services/sharing/nearby/platform/wifi_lan_socket.cc index ee7194c..1f27696 100644 --- a/chrome/services/sharing/nearby/platform/wifi_lan_socket.cc +++ b/chrome/services/sharing/nearby/platform/wifi_lan_socket.cc
@@ -73,15 +73,10 @@ return *bidirectional_stream_.GetOutputStream(); } -// Note: This is thread safe because we can call reset() on -// |tcp_connected_socket_| as many times as we want, and -// BidirectionalStream::Close() is thread safe. +// Note: Both CloseTcpSocketIfNecessary() and BidirectionalStream::Close() are +// thread safe. Exception WifiLanSocket::Close() { - if (tcp_connected_socket_) { - VLOG(1) << "WifiLanSocket::" << __func__ - << ": Closing TCP connected socket."; - tcp_connected_socket_.reset(); - } + CloseTcpSocketIfNecessary(); return bidirectional_stream_.Close(); } @@ -97,6 +92,16 @@ Close(); } +void WifiLanSocket::CloseTcpSocketIfNecessary() { + base::AutoLock lock(lock_); + + if (!tcp_connected_socket_) + return; + + VLOG(1) << "WifiLanSocket::" << __func__ << ": Closing TCP connected socket."; + tcp_connected_socket_.reset(); +} + } // namespace chrome } // namespace nearby } // namespace location
diff --git a/chrome/services/sharing/nearby/platform/wifi_lan_socket.h b/chrome/services/sharing/nearby/platform/wifi_lan_socket.h index bb50dfb6..b06440675 100644 --- a/chrome/services/sharing/nearby/platform/wifi_lan_socket.h +++ b/chrome/services/sharing/nearby/platform/wifi_lan_socket.h
@@ -6,6 +6,7 @@ #define CHROME_SERVICES_SHARING_NEARBY_PLATFORM_WIFI_LAN_SOCKET_H_ #include "base/memory/scoped_refptr.h" +#include "base/synchronization/lock.h" #include "chrome/services/sharing/nearby/platform/bidirectional_stream.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/shared_remote.h" @@ -69,6 +70,11 @@ // Close if the TCP socket disconnects. void OnTcpConnectedSocketDisconnected(); + void CloseTcpSocketIfNecessary(); + + // Protects |tcp_connected_socket_| while closing. + base::Lock lock_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; mojo::SharedRemote<network::mojom::TCPConnectedSocket> tcp_connected_socket_; BidirectionalStream bidirectional_stream_;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7d4a6d6..cd5a67a 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3163,7 +3163,6 @@ "../browser/ash/login/screens/fingerprint_setup_browsertest.cc", "../browser/ash/login/screens/gesture_navigation_screen_browsertest.cc", "../browser/ash/login/screens/hid_detection_screen_browsertest.cc", - "../browser/ash/login/screens/lacros_data_migration_screen_browsertest.cc", "../browser/ash/login/screens/management_transition_screen_browsertest.cc", "../browser/ash/login/screens/marketing_opt_in_screen_browsertest.cc", "../browser/ash/login/screens/mock_arc_terms_of_service_screen.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java index e8975ff0..2b24104b 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/tests/FirstRunControllerTest.java
@@ -36,6 +36,9 @@ @Rule public final TestRule mChain = RuleChain.outerRule(mChromeUiRule).around(mUiAutomatorRule); + @Rule + public TestRule mCommandLineFlagsRule = CommandLineFlags.getTestRule(); + @Before public void setUp() { mChromeUiRule.launchApplication();
diff --git a/chrome/test/data/extensions/api_test/autotest_private/test.js b/chrome/test/data/extensions/api_test/autotest_private/test.js index 8129ff5..d05639c2 100644 --- a/chrome/test/data/extensions/api_test/autotest_private/test.js +++ b/chrome/test/data/extensions/api_test/autotest_private/test.js
@@ -1390,7 +1390,7 @@ // Because the File app has been unpinned, there is no update in pin state. chrome.test.assertEq([], unpinResults); - chrome.test.succeed() + chrome.test.succeed(); } ]; @@ -1405,6 +1405,14 @@ })); }]; +var holdingSpaceTests = [ + function resetHoldingSpace(options) { + // State after this call is checked in C++ test code. + chrome.autotestPrivate.resetHoldingSpace(options, + chrome.test.callbackPass()); + }, +]; + // Tests that requires a concrete system web app installation. var systemWebAppsTests = [ function getRegisteredSystemWebApps() { @@ -1456,13 +1464,22 @@ 'splitviewLeftSnapped': splitviewLeftSnappedTests, 'scrollableShelf': scrollableShelfTests, 'shelf': shelfTests, + 'holdingSpace': holdingSpaceTests, 'systemWebApps': systemWebAppsTests, }; chrome.test.getConfig(function(config) { - var suite = test_suites[config.customArg]; - if (config.customArg in test_suites) { - chrome.test.runTests(test_suites[config.customArg]); + var customArg = JSON.parse(config.customArg); + // In the customArg object, we expect the name of the test suite at the + // 'testSuite' key, and the arguments to be passed to the test functions as an + // array at the 'args' key. + var [suite_name, args] = [customArg['testSuite'], customArg['args']]; + + chrome.test.assertTrue(Array.isArray(args)); + + if (suite_name in test_suites) { + var suite = test_suites[suite_name].map(f => f.bind({}, ...args)); + chrome.test.runTests(suite); } else { chrome.test.fail('Invalid test suite'); }
diff --git a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js index cb3746e..0aa4300 100644 --- a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js +++ b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js
@@ -94,7 +94,7 @@ // TODO(michaelcheco): Remove this stub test once the page has more // capabilities to test. assertEquals( - 'Firmware updates', + 'Update peripherals', page.shadowRoot.querySelector('#header').textContent.trim()); });
diff --git a/chrome/test/data/webui/print_preview/BUILD.gn b/chrome/test/data/webui/print_preview/BUILD.gn index 9d644764..db9746fce 100644 --- a/chrome/test/data/webui/print_preview/BUILD.gn +++ b/chrome/test/data/webui/print_preview/BUILD.gn
@@ -10,6 +10,8 @@ # Print Preview test files that contain // <if expr> and therefore require # preprocessing. preprocessed_tests = [ + "button_strip_test.ts", + "color_settings_test.ts", "destination_settings_test.js", "destination_store_test.js", "invalid_settings_browsertest.js", @@ -30,12 +32,10 @@ non_preprocessed_tests = [ "advanced_dialog_test.ts", "advanced_item_test.ts", - "button_strip_interactive_test.js", - "button_strip_test.js", + "button_strip_interactive_test.ts", "cloud_print_interface_stub.ts", - "color_settings_test.js", - "copies_settings_test.js", - "custom_margins_test.js", + "copies_settings_test.ts", + "custom_margins_test.ts", "destination_dialog_cros_interactive_test.js", "destination_dialog_cros_test.js", "destination_dialog_interactive_test.js",
diff --git a/chrome/test/data/webui/print_preview/button_strip_interactive_test.js b/chrome/test/data/webui/print_preview/button_strip_interactive_test.ts similarity index 65% rename from chrome/test/data/webui/print_preview/button_strip_interactive_test.js rename to chrome/test/data/webui/print_preview/button_strip_interactive_test.ts index 8075e6ff..cd72580 100644 --- a/chrome/test/data/webui/print_preview/button_strip_interactive_test.js +++ b/chrome/test/data/webui/print_preview/button_strip_interactive_test.ts
@@ -4,26 +4,24 @@ import {Destination, DestinationConnectionStatus, DestinationOrigin, DestinationType, PrintPreviewButtonStripElement, State} from 'chrome://print/print_preview.js'; import {assert} from 'chrome://resources/js/assert.m.js'; -import {assertTrue} from 'chrome://webui-test/chai_assert.js'; import {eventToPromise} from 'chrome://webui-test/test_util.js'; -window.button_strip_interactive_test = {}; -const button_strip_interactive_test = window.button_strip_interactive_test; -button_strip_interactive_test.suiteName = 'ButtonStripInteractiveTest'; -/** @enum {string} */ -button_strip_interactive_test.TestNames = { - FocusPrintOnReady: 'focus print on ready', +const button_strip_interactive_test = { + suiteName: 'ButtonStripInteractiveTest', + TestNames: { + FocusPrintOnReady: 'focus print on ready', + }, }; -suite(button_strip_interactive_test.suiteName, function() { - /** @type {!PrintPreviewButtonStripElement} */ - let buttonStrip; +Object.assign( + window, {button_strip_interactive_test: button_strip_interactive_test}); - /** @override */ +suite(button_strip_interactive_test.suiteName, function() { + let buttonStrip: PrintPreviewButtonStripElement; + setup(function() { document.body.innerHTML = ''; - buttonStrip = /** @type {!PrintPreviewButtonStripElement} */ ( - document.createElement('print-preview-button-strip')); + buttonStrip = document.createElement('print-preview-button-strip'); buttonStrip.destination = new Destination( 'FooDevice', DestinationType.GOOGLE, DestinationOrigin.COOKIES, 'FooName', DestinationConnectionStatus.ONLINE); @@ -38,8 +36,8 @@ assert(button_strip_interactive_test.TestNames.FocusPrintOnReady), function() { const printButton = - assert(buttonStrip.shadowRoot.querySelector('.action-button')); - const whenFocusDone = eventToPromise('focus', printButton); + assert(buttonStrip.shadowRoot!.querySelector('.action-button')); + const whenFocusDone = eventToPromise('focus', printButton!); // Simulate initialization finishing. buttonStrip.state = State.READY;
diff --git a/chrome/test/data/webui/print_preview/button_strip_test.js b/chrome/test/data/webui/print_preview/button_strip_test.js deleted file mode 100644 index c6bd7e22..0000000 --- a/chrome/test/data/webui/print_preview/button_strip_test.js +++ /dev/null
@@ -1,106 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {Destination, DestinationConnectionStatus, DestinationOrigin, DestinationType, PrintPreviewButtonStripElement, State} from 'chrome://print/print_preview.js'; -import {assert} from 'chrome://resources/js/assert.m.js'; -import {isWindows} from 'chrome://resources/js/cr.m.js'; - -import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; -import {eventToPromise} from 'chrome://webui-test/test_util.js'; - -window.button_strip_test = {}; -const button_strip_test = window.button_strip_test; -button_strip_test.suiteName = 'ButtonStripTest'; -/** @enum {string} */ -button_strip_test.TestNames = { - ButtonStripChangesForState: 'button strip changes for state', - ButtonOrder: 'button order', - ButtonStripFiresEvents: 'button strip fires events', -}; - -suite(button_strip_test.suiteName, function() { - /** @type {!PrintPreviewButtonStripElement} */ - let buttonStrip; - - /** @override */ - setup(function() { - document.body.innerHTML = ''; - buttonStrip = /** @type {!PrintPreviewButtonStripElement} */ ( - document.createElement('print-preview-button-strip')); - - buttonStrip.destination = new Destination( - 'FooDevice', DestinationType.GOOGLE, DestinationOrigin.COOKIES, - 'FooName', DestinationConnectionStatus.ONLINE); - buttonStrip.state = State.READY; - // No max sheets limit is specified. - buttonStrip.maxSheets = 0; - document.body.appendChild(buttonStrip); - }); - - // Tests that the correct message is shown for non-READY states, and that - // the print button is disabled appropriately. - test( - assert(button_strip_test.TestNames.ButtonStripChangesForState), - function() { - const printButton = - buttonStrip.shadowRoot.querySelector('.action-button'); - assertFalse(printButton.disabled); - - buttonStrip.state = State.NOT_READY; - assertTrue(printButton.disabled); - - buttonStrip.state = State.PRINTING; - assertTrue(printButton.disabled); - - buttonStrip.state = State.ERROR; - assertTrue(printButton.disabled); - - buttonStrip.state = State.FATAL_ERROR; - assertTrue(printButton.disabled); - }); - - // Tests that the buttons are in the correct order for different platforms. - // See https://crbug.com/880562. - test(assert(button_strip_test.TestNames.ButtonOrder), function() { - // Verify that there are only 2 buttons. - assertEquals( - 2, buttonStrip.shadowRoot.querySelectorAll('cr-button').length); - - const firstButton = - buttonStrip.shadowRoot.querySelector('cr-button:not(:last-child)'); - const lastButton = - buttonStrip.shadowRoot.querySelector('cr-button:last-child'); - const printButton = - buttonStrip.shadowRoot.querySelector('cr-button.action-button'); - const cancelButton = - buttonStrip.shadowRoot.querySelector('cr-button.cancel-button'); - - if (isWindows) { - // On Windows, the print button is on the left. - assertEquals(firstButton, printButton); - assertEquals(lastButton, cancelButton); - } else { - assertEquals(firstButton, cancelButton); - assertEquals(lastButton, printButton); - } - }); - - // Tests that the button strip fires print-requested and cancel-requested - // events. - test(assert(button_strip_test.TestNames.ButtonStripFiresEvents), function() { - const printButton = - buttonStrip.shadowRoot.querySelector('cr-button.action-button'); - const cancelButton = - buttonStrip.shadowRoot.querySelector('cr-button.cancel-button'); - - const whenPrintRequested = eventToPromise('print-requested', buttonStrip); - printButton.click(); - return whenPrintRequested.then(() => { - const whenCancelRequested = - eventToPromise('cancel-requested', buttonStrip); - cancelButton.click(); - return whenCancelRequested; - }); - }); -});
diff --git a/chrome/test/data/webui/print_preview/button_strip_test.ts b/chrome/test/data/webui/print_preview/button_strip_test.ts new file mode 100644 index 0000000..b7090133 --- /dev/null +++ b/chrome/test/data/webui/print_preview/button_strip_test.ts
@@ -0,0 +1,104 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {CrButtonElement, Destination, DestinationConnectionStatus, DestinationOrigin, DestinationType, PrintPreviewButtonStripElement, State} from 'chrome://print/print_preview.js'; +import {assert} from 'chrome://resources/js/assert.m.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {eventToPromise} from 'chrome://webui-test/test_util.js'; + +const button_strip_test = { + suiteName: 'ButtonStripTest', + TestNames: { + ButtonStripChangesForState: 'button strip changes for state', + ButtonOrder: 'button order', + ButtonStripFiresEvents: 'button strip fires events', + }, +}; + +Object.assign(window, {button_strip_test: button_strip_test}); + +suite(button_strip_test.suiteName, function() { + let buttonStrip: PrintPreviewButtonStripElement; + + setup(function() { + document.body.innerHTML = ''; + buttonStrip = document.createElement('print-preview-button-strip'); + + buttonStrip.destination = new Destination( + 'FooDevice', DestinationType.GOOGLE, DestinationOrigin.COOKIES, + 'FooName', DestinationConnectionStatus.ONLINE); + buttonStrip.state = State.READY; + // No max sheets limit is specified. + buttonStrip.maxSheets = 0; + document.body.appendChild(buttonStrip); + }); + + // Tests that the correct message is shown for non-READY states, and that + // the print button is disabled appropriately. + test( + assert(button_strip_test.TestNames.ButtonStripChangesForState), + function() { + const printButton = + buttonStrip.shadowRoot!.querySelector<CrButtonElement>( + '.action-button')!; + assertFalse(printButton.disabled); + + buttonStrip.state = State.NOT_READY; + assertTrue(printButton.disabled); + + buttonStrip.state = State.PRINTING; + assertTrue(printButton.disabled); + + buttonStrip.state = State.ERROR; + assertTrue(printButton.disabled); + + buttonStrip.state = State.FATAL_ERROR; + assertTrue(printButton.disabled); + }); + + // Tests that the buttons are in the correct order for different platforms. + // See https://crbug.com/880562. + test(assert(button_strip_test.TestNames.ButtonOrder), function() { + // Verify that there are only 2 buttons. + assertEquals( + 2, buttonStrip.shadowRoot!.querySelectorAll('cr-button').length); + + const firstButton = + buttonStrip.shadowRoot!.querySelector('cr-button:not(:last-child)'); + const lastButton = + buttonStrip.shadowRoot!.querySelector('cr-button:last-child'); + const printButton = + buttonStrip.shadowRoot!.querySelector('cr-button.action-button'); + const cancelButton = + buttonStrip.shadowRoot!.querySelector('cr-button.cancel-button'); + + // <if expr="is_win"> + // On Windows, the print button is on the left. + assertEquals(firstButton, printButton); + assertEquals(lastButton, cancelButton); + // </if> + // <if expr="not is_win"> + assertEquals(firstButton, cancelButton); + assertEquals(lastButton, printButton); + // </if> + }); + + // Tests that the button strip fires print-requested and cancel-requested + // events. + test(assert(button_strip_test.TestNames.ButtonStripFiresEvents), function() { + const printButton = buttonStrip.shadowRoot!.querySelector<HTMLElement>( + 'cr-button.action-button')!; + const cancelButton = buttonStrip.shadowRoot!.querySelector<HTMLElement>( + 'cr-button.cancel-button')!; + + const whenPrintRequested = eventToPromise('print-requested', buttonStrip); + printButton.click(); + return whenPrintRequested.then(() => { + const whenCancelRequested = + eventToPromise('cancel-requested', buttonStrip); + cancelButton.click(); + return whenCancelRequested; + }); + }); +});
diff --git a/chrome/test/data/webui/print_preview/color_settings_test.js b/chrome/test/data/webui/print_preview/color_settings_test.js deleted file mode 100644 index 7a8be017..0000000 --- a/chrome/test/data/webui/print_preview/color_settings_test.js +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'chrome://print/print_preview.js'; - -import {assert} from 'chrome://resources/js/assert.m.js'; -import {isChromeOS, isLacros} from 'chrome://resources/js/cr.m.js'; - -import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; -import {eventToPromise, fakeDataBind} from 'chrome://webui-test/test_util.js'; - -import {selectOption} from './print_preview_test_utils.js'; - -suite('ColorSettingsTest', function() { - /** @type {!PrintPreviewColorSettingsElement} */ - let colorSection; - - /** @type {!PrintPreviewModelElement} */ - let model; - - /** @override */ - setup(function() { - document.body.innerHTML = ''; - model = /** @type {!PrintPreviewModelElement} */ ( - document.createElement('print-preview-model')); - document.body.appendChild(model); - - colorSection = /** @type {!PrintPreviewColorSettingsElement} */ ( - document.createElement('print-preview-color-settings')); - colorSection.settings = model.settings; - colorSection.disabled = false; - fakeDataBind(model, colorSection, 'settings'); - model.set('settings.color.available', true); - document.body.appendChild(colorSection); - }); - - // Tests that setting the setting updates the UI. - test('set setting', async () => { - const select = colorSection.shadowRoot.querySelector('select'); - assertEquals('color', select.value); - - colorSection.setSetting('color', false); - await eventToPromise('process-select-change', colorSection); - assertEquals('bw', select.value); - }); - - // Tests that selecting a new option in the dropdown updates the setting. - test('select option', async () => { - // Verify that the selected option and names are as expected. - const select = colorSection.shadowRoot.querySelector('select'); - assertEquals('color', select.value); - assertTrue(/** @type {boolean} */ (colorSection.getSettingValue('color'))); - assertFalse(colorSection.getSetting('color').setFromUi); - assertEquals(2, select.options.length); - - // Verify that selecting an new option in the dropdown sets the setting. - await selectOption(colorSection, 'bw'); - assertFalse(/** @type {boolean} */ (colorSection.getSettingValue('color'))); - assertTrue(colorSection.getSetting('color').setFromUi); - }); - - if (isChromeOS || isLacros) { - // Tests that if the setting is enforced by enterprise policy it is - // disabled. - test('disabled by policy', function() { - // Verify that the selected option and names are as expected. - const select = colorSection.shadowRoot.querySelector('select'); - assertFalse(select.disabled); - - model.set('settings.color.setByPolicy', true); - assertTrue(select.disabled); - }); - } -});
diff --git a/chrome/test/data/webui/print_preview/color_settings_test.ts b/chrome/test/data/webui/print_preview/color_settings_test.ts new file mode 100644 index 0000000..35236a1 --- /dev/null +++ b/chrome/test/data/webui/print_preview/color_settings_test.ts
@@ -0,0 +1,69 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://print/print_preview.js'; + +import {PrintPreviewColorSettingsElement, PrintPreviewModelElement} from 'chrome://print/print_preview.js'; + +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {eventToPromise, fakeDataBind} from 'chrome://webui-test/test_util.js'; + +import {selectOption} from './print_preview_test_utils.js'; + +suite('ColorSettingsTest', function() { + let colorSection: PrintPreviewColorSettingsElement; + + let model: PrintPreviewModelElement; + + setup(function() { + document.body.innerHTML = ''; + model = document.createElement('print-preview-model'); + document.body.appendChild(model); + + colorSection = document.createElement('print-preview-color-settings'); + colorSection.settings = model.settings; + colorSection.disabled = false; + fakeDataBind(model, colorSection, 'settings'); + model.set('settings.color.available', true); + document.body.appendChild(colorSection); + }); + + // Tests that setting the setting updates the UI. + test('set setting', async () => { + const select = colorSection.shadowRoot!.querySelector('select')!; + assertEquals('color', select.value); + + colorSection.setSetting('color', false); + await eventToPromise('process-select-change', colorSection); + assertEquals('bw', select.value); + }); + + // Tests that selecting a new option in the dropdown updates the setting. + test('select option', async () => { + // Verify that the selected option and names are as expected. + const select = colorSection.shadowRoot!.querySelector('select')!; + assertEquals('color', select.value); + assertTrue(colorSection.getSettingValue('color') as boolean); + assertFalse(colorSection.getSetting('color').setFromUi); + assertEquals(2, select.options.length); + + // Verify that selecting an new option in the dropdown sets the setting. + await selectOption(colorSection, 'bw'); + assertFalse(colorSection.getSettingValue('color') as boolean); + assertTrue(colorSection.getSetting('color').setFromUi); + }); + + // <if expr="chromeos or lacros"> + // Tests that if the setting is enforced by enterprise policy it is + // disabled. + test('disabled by policy', function() { + // Verify that the selected option and names are as expected. + const select = colorSection.shadowRoot!.querySelector('select')!; + assertFalse(select.disabled); + + model.set('settings.color.setByPolicy', true); + assertTrue(select.disabled); + }); + // </if> +});
diff --git a/chrome/test/data/webui/print_preview/copies_settings_test.js b/chrome/test/data/webui/print_preview/copies_settings_test.ts similarity index 81% rename from chrome/test/data/webui/print_preview/copies_settings_test.js rename to chrome/test/data/webui/print_preview/copies_settings_test.ts index aa086c1..622cf6f1 100644 --- a/chrome/test/data/webui/print_preview/copies_settings_test.js +++ b/chrome/test/data/webui/print_preview/copies_settings_test.ts
@@ -3,7 +3,6 @@ // found in the LICENSE file. import {DEFAULT_MAX_COPIES, PrintPreviewCopiesSettingsElement, PrintPreviewModelElement} from 'chrome://print/print_preview.js'; -import {assert} from 'chrome://resources/js/assert.m.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {fakeDataBind} from 'chrome://webui-test/test_util.js'; @@ -11,22 +10,17 @@ import {triggerInputEvent} from './print_preview_test_utils.js'; suite('CopiesSettingsTest', function() { - /** @type {!PrintPreviewCopiesSettingsElement} */ - let copiesSection; + let copiesSection: PrintPreviewCopiesSettingsElement; - /** @type {!PrintPreviewModelElement} */ - let model; + let model: PrintPreviewModelElement; - /** @override */ setup(function() { document.body.innerHTML = ''; - model = /** @type {!PrintPreviewModelElement} */ ( - document.createElement('print-preview-model')); + model = document.createElement('print-preview-model'); document.body.appendChild(model); model.set('settings.collate.available', true); - copiesSection = /** @type {!PrintPreviewCopiesSettingsElement} */ ( - document.createElement('print-preview-copies-settings')); + copiesSection = document.createElement('print-preview-copies-settings'); copiesSection.settings = model.settings; copiesSection.disabled = false; fakeDataBind(model, copiesSection, 'settings'); @@ -35,12 +29,12 @@ /** * Confirms that |max| is currently set as copiesSection's maxCopies. - * @param {number} max Expected maximum copies value to check. + * @param max Expected maximum copies value to check. */ - async function checkCopiesMax(max) { - const input = copiesSection.shadowRoot - .querySelector('print-preview-number-settings-section') - .getInput(); + async function checkCopiesMax(max: number) { + const input = + copiesSection.shadowRoot! + .querySelector('print-preview-number-settings-section')!.getInput(); // Check that |max| copies is valid. await triggerInputEvent(input, max.toString(), copiesSection); @@ -55,9 +49,8 @@ // supported. test('set copies max', async () => { const copiesInput = - copiesSection.shadowRoot - .querySelector('print-preview-number-settings-section') - .getInput(); + copiesSection.shadowRoot! + .querySelector('print-preview-number-settings-section')!.getInput(); assertEquals('1', copiesInput.value); assertFalse(copiesSection.getSetting('copies').setFromUi); @@ -70,7 +63,8 @@ }); test('collate visibility', async () => { - const collateSection = copiesSection.shadowRoot.querySelector('.checkbox'); + const collateSection = + copiesSection.shadowRoot!.querySelector<HTMLElement>('.checkbox')!; assertTrue(collateSection.hidden); copiesSection.setSetting('copies', 2); @@ -83,9 +77,8 @@ // Set copies empty. const copiesInput = - copiesSection.shadowRoot - .querySelector('print-preview-number-settings-section') - .getInput(); + copiesSection.shadowRoot! + .querySelector('print-preview-number-settings-section')!.getInput(); await triggerInputEvent(copiesInput, '', copiesSection); assertTrue(collateSection.hidden); @@ -102,9 +95,8 @@ // correctly. test('set copies', async () => { const copiesInput = - copiesSection.shadowRoot - .querySelector('print-preview-number-settings-section') - .getInput(); + copiesSection.shadowRoot! + .querySelector('print-preview-number-settings-section')!.getInput(); assertEquals('1', copiesInput.value); assertFalse(copiesSection.getSetting('copies').setFromUi); @@ -143,9 +135,8 @@ // Verifies that the inputs update when the value is updated. test('update from settings', function() { const copiesInput = - copiesSection.shadowRoot - .querySelector('print-preview-number-settings-section') - .getInput(); + copiesSection.shadowRoot! + .querySelector('print-preview-number-settings-section')!.getInput(); const collateCheckbox = copiesSection.$.collate; assertEquals('1', copiesInput.value);
diff --git a/chrome/test/data/webui/print_preview/custom_margins_test.js b/chrome/test/data/webui/print_preview/custom_margins_test.ts similarity index 79% rename from chrome/test/data/webui/print_preview/custom_margins_test.js rename to chrome/test/data/webui/print_preview/custom_margins_test.ts index e008698..84c218a2f 100644 --- a/chrome/test/data/webui/print_preview/custom_margins_test.js +++ b/chrome/test/data/webui/print_preview/custom_margins_test.ts
@@ -2,64 +2,57 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {CustomMarginsOrientation, Margins, MarginsType, MeasurementSystem, MeasurementSystemUnitType, PrintPreviewMarginControlContainerElement, PrintPreviewMarginControlElement, PrintPreviewModelElement, Size, State} from 'chrome://print/print_preview.js'; +import {CustomMarginsOrientation, Margins, MarginsSetting, MarginsType, MeasurementSystem, MeasurementSystemUnitType, PrintPreviewMarginControlContainerElement, PrintPreviewMarginControlElement, PrintPreviewModelElement, Size, State} from 'chrome://print/print_preview.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {eventToPromise, fakeDataBind} from 'chrome://webui-test/test_util.js'; -window.custom_margins_test = {}; -const custom_margins_test = window.custom_margins_test; -custom_margins_test.suiteName = 'CustomMarginsTest'; -/** @enum {string} */ -custom_margins_test.TestNames = { - ControlsCheck: 'controls check', - SetFromStickySettings: 'set from sticky settings', - DragControls: 'drag controls', - SetControlsWithTextbox: 'set controls with textbox', - SetControlsWithTextboxMetric: 'set controls with textbox metric', - RestoreStickyMarginsAfterDefault: 'restore sticky margins after default', - MediaSizeClearsCustomMargins: 'media size clears custom margins', - LayoutClearsCustomMargins: 'layout clears custom margins', - IgnoreDocumentMarginsFromPDF: 'ignore document margins from pdf', - MediaSizeClearsCustomMarginsPDF: 'media size clears custom margins pdf', - RequestScrollToOutOfBoundsTextbox: 'request scroll to out of bounds textbox', - ControlsDisabledOnError: 'controls disabled on error', +const custom_margins_test = { + suiteName: 'CustomMarginsTest', + TestNames: { + ControlsCheck: 'controls check', + SetFromStickySettings: 'set from sticky settings', + DragControls: 'drag controls', + SetControlsWithTextbox: 'set controls with textbox', + SetControlsWithTextboxMetric: 'set controls with textbox metric', + RestoreStickyMarginsAfterDefault: 'restore sticky margins after default', + MediaSizeClearsCustomMargins: 'media size clears custom margins', + LayoutClearsCustomMargins: 'layout clears custom margins', + IgnoreDocumentMarginsFromPDF: 'ignore document margins from pdf', + MediaSizeClearsCustomMarginsPDF: 'media size clears custom margins pdf', + RequestScrollToOutOfBoundsTextbox: + 'request scroll to out of bounds textbox', + ControlsDisabledOnError: 'controls disabled on error', + }, }; +Object.assign(window, {custom_margins_test: custom_margins_test}); suite(custom_margins_test.suiteName, function() { - /** @type {!PrintPreviewMarginControlContainerElement} */ - let container; + let container: PrintPreviewMarginControlContainerElement; - /** @type {PrintPreviewModelElement} */ - let model; + let model: PrintPreviewModelElement; - /** @type {!Array<!CustomMarginsOrientation>} */ - let sides = []; + let sides: CustomMarginsOrientation[] = []; - /** @type {!MeasurementSystem} */ - let measurementSystem; + let measurementSystem: MeasurementSystem; - /** @type {number} */ - const pixelsPerInch = 100; + const pixelsPerInch: number = 100; - /** @type {number} */ - const pointsPerInch = 72.0; + const pointsPerInch: number = 72.0; - /** @type {number} */ - const defaultMarginPts = 36; // 0.5 inch + const defaultMarginPts: number = 36; // 0.5 inch // Keys for the custom margins setting, in order. - const keys = ['marginTop', 'marginRight', 'marginBottom', 'marginLeft']; + const keys: string[] = + ['marginTop', 'marginRight', 'marginBottom', 'marginLeft']; - /** @override */ setup(function() { document.body.innerHTML = ''; measurementSystem = new MeasurementSystem(',', '.', MeasurementSystemUnitType.IMPERIAL); - model = /** @type {!PrintPreviewModelElement} */ ( - document.createElement('print-preview-model')); + model = document.createElement('print-preview-model'); document.body.appendChild(model); model.set('settings.mediaSize.available', true); @@ -68,8 +61,8 @@ CustomMarginsOrientation.BOTTOM, CustomMarginsOrientation.LEFT ]; - container = /** @type {!PrintPreviewMarginControlContainerElement} */ ( - document.createElement('print-preview-margin-control-container')); + container = + document.createElement('print-preview-margin-control-container'); container.previewLoaded = false; // 8.5 x 11, in points container.pageSize = new Size(612, 794); @@ -78,10 +71,9 @@ container.state = State.NOT_READY; }); - /** @return {!NodeList<!PrintPreviewMarginControlElement>} */ - function getControls() { - return /** @type {!NodeList<!PrintPreviewMarginControlElement>} */ ( - container.shadowRoot.querySelectorAll('print-preview-margin-control')); + function getControls(): PrintPreviewMarginControlElement[] { + return Array.from( + container.shadowRoot!.querySelectorAll('print-preview-margin-control')); } /* @@ -111,23 +103,25 @@ } /** - * @param {!NodeList<!PrintPreviewMarginControlElement>} controls - * @return {!Promise} Promise that resolves when transitionend has fired + * @return Promise that resolves when transitionend has fired * for all of the controls. */ - function getAllTransitions(controls) { - return Promise.all(Array.from(controls).map( - control => eventToPromise('transitionend', control))); + function getAllTransitions(controls: PrintPreviewMarginControlElement[]): + Promise<any[]> { + return Promise.all( + controls.map(control => eventToPromise('transitionend', control))); } /** * Simulates dragging the margin control. - * @param {!PrintPreviewMarginControlElement} control The control to move. - * @param {number} start The starting position for the control in pixels. - * @param {number} end The ending position for the control in pixels. + * @param control The control to move. + * @param start The starting position for the control in pixels. + * @param end The ending position for the control in pixels. */ - function dragControl(control, start, end) { - if (window.getComputedStyle(control)['pointer-events'] === 'none') { + function dragControl( + control: PrintPreviewMarginControlElement, start: number, end: number) { + if (window.getComputedStyle(control).getPropertyValue('pointer-events') === + 'none') { return; } @@ -141,12 +135,12 @@ yEnd = end; break; case CustomMarginsOrientation.RIGHT: - xStart = control.clipSize.width - start; - xEnd = control.clipSize.width - end; + xStart = control.clipSize!.width - start; + xEnd = control.clipSize!.width - end; break; case CustomMarginsOrientation.BOTTOM: - yStart = control.clipSize.height - start; - yEnd = control.clipSize.height - end; + yStart = control.clipSize!.height - start; + yEnd = control.clipSize!.height - end; break; case CustomMarginsOrientation.LEFT: xStart = start; @@ -168,18 +162,20 @@ /** * Tests setting the margin control with its textbox. - * @param {!PrintPreviewMarginControlElement} control The control. - * @param {string} key The control's key in the custom margin setting. - * @param {number} currentValuePts The current margin value in points. - * @param {string} input The new textbox input for the margin. - * @param {boolean} invalid Whether the new value is invalid. - * @param {number=} newValuePts the new margin value in pts. If not + * @param control The control. + * @param key The control's key in the custom margin setting. + * @param currentValuePts The current margin value in points. + * @param input The new textbox input for the margin. + * @param invalid Whether the new value is invalid. + * @param newValuePts the new margin value in pts. If not * specified, computes the value assuming it is in bounds and assuming * the default measurement system. - * @return {!Promise} Promise that resolves when the test is complete. + * @return Promise that resolves when the test is complete. */ function testControlTextbox( - control, key, currentValuePts, input, invalid, newValuePts) { + control: PrintPreviewMarginControlElement, key: string, + currentValuePts: number, input: string, invalid: boolean, + newValuePts?: number): Promise<void> { if (newValuePts === undefined) { newValuePts = invalid ? currentValuePts : Math.round(parseFloat(input) * pointsPerInch); @@ -207,10 +203,8 @@ /* * Initializes the settings custom margins to some test values, and returns * a map with the values. - * @return {!Map<!CustomMarginsOrientation, - * number>} */ - function setupCustomMargins() { + function setupCustomMargins(): Map<CustomMarginsOrientation, number> { const orientationEnum = CustomMarginsOrientation; const marginValues = new Map([ [orientationEnum.TOP, 72], [orientationEnum.RIGHT, 36], @@ -228,11 +222,12 @@ /* * Tests that the custom margins and margin value are cleared when the * setting |settingName| is set to have value |newValue|. - * @param {string} settingName The name of the setting to check. - * @param {*} newValue The value to set the setting to. - * @return {!Promise} Promise that resolves when the check is complete. + * @param settingName The name of the setting to check. + * @param newValue The value to set the setting to. + * @return Promise that resolves when the check is complete. */ - function validateMarginsClearedForSetting(settingName, newValue) { + function validateMarginsClearedForSetting( + settingName: string, newValue: any) { const marginValues = setupCustomMargins(); return finishSetup().then(() => { // Simulate setting custom margins. @@ -241,7 +236,7 @@ // Validate control positions are set based on the custom values. const controls = getControls(); controls.forEach((control, index) => { - const side = sides[index]; + const side = sides[index]!; assertEquals(side, control.side); assertEquals(marginValues.get(side), control.getPositionInPts()); }); @@ -268,10 +263,8 @@ // Test that controls correctly appear when custom margins are selected and // disappear when the preview is loading. test(assert(custom_margins_test.TestNames.ControlsCheck), function() { - /** @return {!MarginsSetting} */ - const getCustomMarginsValue = function() { - return /** @type {!MarginsSetting} */ ( - container.getSettingValue('customMargins')); + const getCustomMarginsValue = function(): MarginsSetting { + return container.getSettingValue('customMargins') as MarginsSetting; }; return finishSetup() .then(() => { @@ -318,7 +311,7 @@ }) .then(function() { const controls = getControls(); - controls.forEach((control, index) => { + controls.forEach(control => { assertEquals('0', window.getComputedStyle(control).opacity); assertTrue(control.invisible); assertTrue(control.disabled); @@ -340,7 +333,7 @@ // Validate control positions have been updated. controls.forEach((control, index) => { - const side = sides[index]; + const side = sides[index]!; assertEquals(side, control.side); assertEquals(marginValues.get(side), control.getPositionInPts()); }); @@ -357,9 +350,12 @@ * of controls. * @param {number} newPositionInPts The new position in points. */ - const testControl = function(control, index, newPositionInPts) { - const oldValue = container.getSettingValue('customMargins'); - assertEquals(defaultMarginPts, oldValue[keys[index]]); + const testControl = function( + control: PrintPreviewMarginControlElement, index: number, + newPositionInPts: number): Promise<void> { + const oldValue = + container.getSettingValue('customMargins') as {[k: string]: number}; + assertEquals(defaultMarginPts, oldValue[keys[index]!]); // Compute positions in pixels. const oldPositionInPixels = @@ -371,7 +367,7 @@ dragControl(control, oldPositionInPixels, newPositionInPixels); return whenDragChanged.then(function() { const newValue = container.getSettingValue('customMargins'); - assertEquals(newPositionInPts, newValue[keys[index]]); + assertEquals(newPositionInPts, newValue[keys[index]!]); }); }; @@ -387,40 +383,41 @@ // with the correct initial margin offset. // Set all controls to 108 = 1.5" in points. window.requestAnimationFrame(function() { - return testControl(controls[0], 0, 108) - .then(testControl(controls[1], 1, 108)) - .then(testControl(controls[2], 2, 108)) - .then(testControl(controls[3], 3, 108)); + return testControl(controls[0]!, 0, 108) + .then(() => testControl(controls[1]!, 1, 108)) + .then(() => testControl(controls[2]!, 2, 108)) + .then(() => testControl(controls[3]!, 3, 108)); }); }); }); /** - * @param {!NodeList<!PrintPreviewMarginControlElement>} controls - * @param {number} currentValue Current margin value in pts - * @param {string} input String to set in margin textboxes - * @param {boolean} invalid Whether the string is invalid - * @param {number=} newValuePts the new margin value in pts. If not + * @param currentValue Current margin value in pts + * @param input String to set in margin textboxes + * @param invalid Whether the string is invalid + * @param newValuePts the new margin value in pts. If not * specified, computes the value assuming it is in bounds and assuming * the default measurement system. - * @return {!Promise} Promise that resolves when all controls have been + * @return Promise that resolves when all controls have been * tested. */ function testAllTextboxes( - controls, currentValue, input, invalid, newValuePts) { + controls: PrintPreviewMarginControlElement[], currentValue: number, + input: string, invalid: boolean, newValuePts?: number): Promise<void> { return testControlTextbox( - controls[0], keys[0], currentValue, input, invalid, newValuePts) + controls[0]!, keys[0]!, currentValue, input, invalid, + newValuePts) .then( () => testControlTextbox( - controls[1], keys[1], currentValue, input, invalid, + controls[1]!, keys[1]!, currentValue, input, invalid, newValuePts)) .then( () => testControlTextbox( - controls[2], keys[2], currentValue, input, invalid, + controls[2]!, keys[2]!, currentValue, input, invalid, newValuePts)) .then( () => testControlTextbox( - controls[3], keys[3], currentValue, input, invalid, + controls[3]!, keys[3]!, currentValue, input, invalid, newValuePts)); } @@ -433,7 +430,7 @@ // Set a shorter delay for testing so the test doesn't take too // long. controls.forEach(c => { - c.getInput().setAttribute('data-timeout-delay', 1); + c.getInput().setAttribute('data-timeout-delay', '1'); }); model.set('settings.margins.value', MarginsType.CUSTOM); flush(); @@ -460,11 +457,11 @@ .then(() => testAllTextboxes(controls, newMargin2, value3, false)) .then( () => testControlTextbox( - controls[0], keys[0], newMargin3, '100', false, + controls[0]!, keys[0]!, newMargin3, '100', false, maxTopMargin)) .then( () => testControlTextbox( - controls[0], keys[0], maxTopMargin, '1,000', false, + controls[0]!, keys[0]!, maxTopMargin, '1,000', false, maxTopMargin)); }); }); @@ -483,7 +480,7 @@ // Set a shorter delay for testing so the test doesn't take too // long. controls.forEach(c => { - c.getInput().setAttribute('data-timeout-delay', 1); + c.getInput().setAttribute('data-timeout-delay', '1'); }); model.set('settings.margins.value', MarginsType.CUSTOM); flush(); @@ -525,11 +522,11 @@ newMargin3Pts)) .then( () => testControlTextbox( - controls[0], keys[0], newMargin3Pts, '1.000.000', false, + controls[0]!, keys[0]!, newMargin3Pts, '1.000.000', false, maxTopMargin)) .then( () => testControlTextbox( - controls[0], keys[0], maxTopMargin, '1.000', false, + controls[0]!, keys[0]!, maxTopMargin, '1.000', false, maxTopMargin)); }); }); @@ -547,7 +544,7 @@ // Validate control positions are set based on the custom values. controls.forEach((control, index) => { - const side = sides[index]; + const side = sides[index]!; assertEquals(side, control.side); assertEquals(marginValues.get(side), control.getPositionInPts()); }); @@ -557,7 +554,7 @@ // Validate control positions still reflect the custom values. controls.forEach((control, index) => { - const side = sides[index]; + const side = sides[index]!; assertEquals(side, control.side); assertEquals(marginValues.get(side), control.getPositionInPts()); }); @@ -664,7 +661,7 @@ // Focus the bottom control, which is currently not visible since // the viewer is showing only the top left quarter of the page. - const bottomControl = controls[2]; + const bottomControl = controls[2]!; const whenEventFired = eventToPromise('text-focus-position', container); bottomControl.$.input.focus();
diff --git a/chrome/test/data/webui/print_preview/print_preview_test_utils.ts b/chrome/test/data/webui/print_preview/print_preview_test_utils.ts index 63e6275..945f309e 100644 --- a/chrome/test/data/webui/print_preview/print_preview_test_utils.ts +++ b/chrome/test/data/webui/print_preview/print_preview_test_utils.ts
@@ -3,6 +3,7 @@ // found in the LICENSE file. import {CapabilitiesResponse, Cdd, DEFAULT_MAX_COPIES, Destination, DestinationCertificateStatus, DestinationConnectionStatus, DestinationOrigin, DestinationStore, DestinationType, GooglePromotedDestinationId, LocalDestinationInfo, MeasurementSystemUnitType, MediaSizeCapability, MediaSizeOption, NativeInitialSettings, VendorCapabilityValueType} from 'chrome://print/print_preview.js'; +import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {WebUIListenerMixin} from 'chrome://resources/js/web_ui_listener_mixin.js'; @@ -301,7 +302,7 @@ * @return Promise that resolves when the input-change event has fired. */ export function triggerInputEvent( - inputElement: HTMLInputElement, input: string, + inputElement: HTMLInputElement|CrInputElement, input: string, parentElement: HTMLElement): Promise<void> { inputElement.value = input; inputElement.dispatchEvent(
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn index 88371827..32238a2 100644 --- a/chrome/test/data/webui/settings/BUILD.gn +++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -104,7 +104,7 @@ "site_data_test.js", "site_details_permission_tests.ts", "site_details_tests.ts", - "site_entry_tests.js", + "site_entry_tests.ts", "site_favicon_test.js", "site_list_tests.ts", "site_settings_page_test.ts",
diff --git a/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js b/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js index 3092b8c..f199b87 100644 --- a/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js
@@ -79,6 +79,26 @@ } /** + * @param {string} id + */ + function navigateToSettingsPageWithId(id) { + const params = new URLSearchParams; + params.append('settingId', id); + settings.Router.getInstance().navigateTo( + settings.routes.ABOUT_ABOUT, params); + + Polymer.dom.flush(); + } + + /** + * @param {string} id + * @return {!HTMLButtonElement} + */ + function getDeepLinkButtonElementById(id) { + return page.$$(`#${id}`).shadowRoot.querySelector('cr-icon-button'); + } + + /** * Test that the status icon and status message update according to * incoming 'update-status-changed' events. */ @@ -543,19 +563,48 @@ await initNewPage(); Polymer.dom.flush(); - const params = new URLSearchParams; - params.append('settingId', '1707'); // Setting::kDiagnostics - settings.Router.getInstance().navigateTo( - settings.routes.ABOUT_ABOUT, params); + const diagnosticsId = '1707'; + navigateToSettingsPageWithId(diagnosticsId); - Polymer.dom.flush(); - - const deepLinkElement = - page.$$('#diagnostics').shadowRoot.querySelector('cr-icon-button'); + const deepLinkElement = getDeepLinkButtonElementById('diagnostics'); await test_util.waitAfterNextRender(deepLinkElement); assertEquals( deepLinkElement, getDeepActiveElement(), - 'Diagnostics should be focused for settingId=1707.'); + `Diagnostics should be focused for settingId=${diagnosticsId}.`); + }); + + test('LaunchFirmwareUpdates', async function() { + loadTimeData.overrideValues({ + isDeepLinkingEnabled: true, + isFirmwareUpdaterAppEnabled: true, + }); + + await initNewPage(); + Polymer.dom.flush(); + + assertTrue(!!page.$.firmwareUpdates); + page.$.firmwareUpdates.click(); + await aboutBrowserProxy.whenCalled('openFirmwareUpdatesPage'); + }); + + test('Deep link to firmware updates', async () => { + loadTimeData.overrideValues({ + isDeepLinkingEnabled: true, + isFirmwareUpdaterAppEnabled: true, + }); + + await initNewPage(); + Polymer.dom.flush(); + + const firmwareUpdatesId = '1709'; + navigateToSettingsPageWithId(firmwareUpdatesId); + + const deepLinkElement = getDeepLinkButtonElementById('firmwareUpdates'); + await test_util.waitAfterNextRender(deepLinkElement); + assertEquals( + deepLinkElement, getDeepActiveElement(), + `Firmware updates should be focused for settingId=${ + firmwareUpdatesId}.`); }); // Regression test for crbug.com/1220294
diff --git a/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js b/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js index 768c52e..af968cb 100644 --- a/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js +++ b/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js
@@ -27,6 +27,7 @@ 'refreshTPMFirmwareUpdateStatus', 'requestUpdate', 'setChannel', + 'openFirmwareUpdatesPage', ]); /** @private {!UpdateStatus} */ @@ -217,4 +218,9 @@ launchReleaseNotes() { this.methodCalled('launchReleaseNotes'); } + + /** @override */ + openFirmwareUpdatesPage() { + this.methodCalled('openFirmwareUpdatesPage'); + } }
diff --git a/chrome/test/data/webui/settings/site_entry_tests.js b/chrome/test/data/webui/settings/site_entry_tests.ts similarity index 78% rename from chrome/test/data/webui/settings/site_entry_tests.js rename to chrome/test/data/webui/settings/site_entry_tests.ts index 0a4ebe4c..7de992d 100644 --- a/chrome/test/data/webui/settings/site_entry_tests.js +++ b/chrome/test/data/webui/settings/site_entry_tests.ts
@@ -7,8 +7,9 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {ContentSettingsTypes, LocalDataBrowserProxyImpl, SiteSettingsPrefsBrowserProxyImpl, SortMethod} from 'chrome://settings/lazy_load.js'; +import {LocalDataBrowserProxyImpl, SiteEntryElement, SiteSettingsPrefsBrowserProxyImpl, SortMethod} from 'chrome://settings/lazy_load.js'; import {Router, routes} from 'chrome://settings/settings.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {eventToPromise} from 'chrome://webui-test/test_util.js'; import {TestLocalDataBrowserProxy} from './test_local_data_browser_proxy.js'; @@ -20,7 +21,6 @@ suite('SiteEntry_DisabledConsolidatedControls', function() { /** * An example eTLD+1 Object with multiple origins grouped under it. - * @type {!SiteGroup} */ const TEST_MULTIPLE_SITE_GROUP = createSiteGroup('example.com', [ 'http://example.com', @@ -30,44 +30,25 @@ /** * An example eTLD+1 Object with a single origin in it. - * @type {!SiteGroup} */ const TEST_SINGLE_SITE_GROUP = createSiteGroup('foo.com', [ 'https://login.foo.com', ]); - const TEST_COOKIE_LIST = { - id: 'foo', - children: [ - {domain: 'example.com'}, - {domain: 'example.com'}, - {domain: 'example.com'}, - ] - }; - /** * The mock proxy object to use during test. - * @type {TestSiteSettingsPrefsBrowserProxy} */ - let browserProxy; + let browserProxy: TestSiteSettingsPrefsBrowserProxy; /** * The mock local data proxy object to use during test. - * @type {TestLocalDataBrowserProxy} */ - let localDataBrowserProxy; + let localDataBrowserProxy: TestLocalDataBrowserProxy; /** * A site list element created before each test. - * @type {SiteList} */ - let testElement; - - /** - * The clickable element that expands to show the list of origins. - * @type {Element} - */ - let toggleButton; + let testElement: SiteEntryElement; suiteSetup(function() { loadTimeData.overrideValues({ @@ -82,12 +63,9 @@ SiteSettingsPrefsBrowserProxyImpl.setInstance(browserProxy); LocalDataBrowserProxyImpl.setInstance(localDataBrowserProxy); - PolymerTest.clearBody(); + document.body.innerHTML = ''; testElement = document.createElement('site-entry'); - assertTrue(!!testElement); document.body.appendChild(testElement); - - toggleButton = testElement.$.toggleButton; }); teardown(function() { @@ -106,28 +84,32 @@ test('expands and closes to show more origins', function() { testElement.siteGroup = TEST_MULTIPLE_SITE_GROUP; - assertTrue(testElement.grouped_(testElement.siteGroup)); - assertEquals('false', toggleButton.getAttribute('aria-expanded')); + assertFalse(testElement.$.expandIcon.hidden); + assertEquals( + 'false', testElement.$.toggleButton.getAttribute('aria-expanded')); const originList = testElement.$.originList.get(); assertTrue(originList.classList.contains('iron-collapse-closed')); assertEquals('true', originList.getAttribute('aria-hidden')); - toggleButton.click(); - assertEquals('true', toggleButton.getAttribute('aria-expanded')); + testElement.$.toggleButton.click(); + assertEquals( + 'true', testElement.$.toggleButton.getAttribute('aria-expanded')); assertTrue(originList.classList.contains('iron-collapse-opened')); assertEquals('false', originList.getAttribute('aria-hidden')); }); test('with single origin navigates to Site Details', function() { testElement.siteGroup = TEST_SINGLE_SITE_GROUP; - assertFalse(testElement.grouped_(testElement.siteGroup)); - assertEquals('false', toggleButton.getAttribute('aria-expanded')); + assertTrue(testElement.$.expandIcon.hidden); + assertEquals( + 'false', testElement.$.toggleButton.getAttribute('aria-expanded')); const originList = testElement.$.originList.get(); assertTrue(originList.classList.contains('iron-collapse-closed')); assertEquals('true', originList.getAttribute('aria-hidden')); - toggleButton.click(); - assertEquals('false', toggleButton.getAttribute('aria-expanded')); + testElement.$.toggleButton.click(); + assertEquals( + 'false', testElement.$.toggleButton.getAttribute('aria-expanded')); assertTrue(originList.classList.contains('iron-collapse-closed')); assertEquals('true', originList.getAttribute('aria-hidden')); assertEquals( @@ -143,25 +125,28 @@ flush(); const collapseChild = testElement.$.originList.get(); flush(); - const originList = collapseChild.querySelectorAll('.origin-link'); + const originList = + collapseChild.querySelectorAll<HTMLElement>('.origin-link'); assertEquals(3, originList.length); // Test clicking on one of these origins takes the user to Site Details, // with the correct origin. - originList[1].click(); + originList[1]!.click(); assertEquals( routes.SITE_SETTINGS_SITE_DETAILS.path, Router.getInstance().getCurrentRoute().path); assertEquals( - TEST_MULTIPLE_SITE_GROUP.origins[1].origin, + TEST_MULTIPLE_SITE_GROUP.origins[1]!.origin, Router.getInstance().getQueryParameters().get('site')); }); test('with single origin, shows overflow menu', function() { testElement.siteGroup = TEST_SINGLE_SITE_GROUP; flush(); - const overflowMenuButton = testElement.$$('#overflowMenuButton'); - assertFalse(overflowMenuButton.closest('.row-aligned').hidden); + const overflowMenuButton = + testElement.$$<HTMLElement>('#overflowMenuButton')!; + assertFalse( + overflowMenuButton.closest<HTMLElement>('.row-aligned')!.hidden); }); test('clear data for single origin fires the right method', async function() { @@ -176,9 +161,9 @@ for (let i = 0; i < originList.length; i++) { const menuOpened = eventToPromise('open-menu', testElement); - const originEntry = originList[i]; + const originEntry = originList[i]!; const overflowMenuButton = - originEntry.querySelector('#originOverflowMenuButton'); + originEntry.querySelector<HTMLElement>('#originOverflowMenuButton')!; overflowMenuButton.click(); const openMenuEvent = await menuOpened; @@ -186,7 +171,7 @@ const {actionScope, index, origin} = args; assertEquals('origin', actionScope); assertEquals(testElement.listIndex, index); - assertEquals(testElement.siteGroup.origins[i].origin, origin); + assertEquals(testElement.siteGroup.origins[i]!.origin, origin); } }); @@ -197,19 +182,20 @@ testElement.siteGroup = JSON.parse(JSON.stringify(TEST_MULTIPLE_SITE_GROUP)); flush(); - toggleButton.click(); + testElement.$.toggleButton.click(); assertTrue(testElement.$.originList.get().opened); // Remove all origins except one, then make sure it's not still // expanded. - testElement.siteGroup.origins.splice(1); + const siteGroupUpdated = + JSON.parse(JSON.stringify(TEST_MULTIPLE_SITE_GROUP)); + siteGroupUpdated.origins.splice(1); + testElement.siteGroup = siteGroupUpdated; assertEquals(1, testElement.siteGroup.origins.length); - testElement.onSiteGroupChanged_(testElement.siteGroup); assertFalse(testElement.$.originList.get().opened); }); test('cookies show correctly for grouped entries', function() { - localDataBrowserProxy.setCookieDetails(TEST_COOKIE_LIST); testElement.siteGroup = TEST_MULTIPLE_SITE_GROUP; flush(); const cookiesLabel = testElement.$.cookies; @@ -226,7 +212,7 @@ .then((args) => { assertEquals(3, args); assertFalse(cookiesLabel.hidden); - assertEquals('· 3 cookies', cookiesLabel.textContent.trim()); + assertEquals('· 3 cookies', cookiesLabel.textContent!.trim()); }); }); @@ -249,7 +235,7 @@ .then((args) => { assertEquals(3, args); assertFalse(cookiesLabel.hidden); - assertEquals('· 3 cookies', cookiesLabel.textContent.trim()); + assertEquals('· 3 cookies', cookiesLabel.textContent!.trim()); }); }); @@ -264,12 +250,14 @@ testSiteGroup.origins[2].usage = numBytes3; testElement.siteGroup = testSiteGroup; flush(); - return browserProxy.whenCalled('getFormattedBytes').then((args) => { + return browserProxy.whenCalled('getFormattedBytes').then(args => { const sumBytes = numBytes1 + numBytes2 + numBytes3; + assertEquals(sumBytes, args); assertEquals( `${sumBytes} B`, - testElement.root.querySelector('#displayName .data-unit') - .textContent.trim()); + testElement.shadowRoot! + .querySelector<HTMLElement>( + '#displayName .data-unit')!.textContent!.trim()); }); }); @@ -280,11 +268,13 @@ testSiteGroup.origins[0].usage = numBytes; testElement.siteGroup = testSiteGroup; flush(); - return browserProxy.whenCalled('getFormattedBytes').then((args) => { + return browserProxy.whenCalled('getFormattedBytes').then(args => { + assertEquals(numBytes, args); assertEquals( `${numBytes} B`, - testElement.root.querySelector('#displayName .data-unit') - .textContent.trim()); + testElement.shadowRoot! + .querySelector<HTMLElement>( + '#displayName .data-unit')!.textContent!.trim()); }); }); @@ -304,10 +294,12 @@ flush(); return browserProxy.whenCalled('getFormattedBytes').then((args) => { const sumBytes = numBytes1 + numBytes2 + numBytes3; + assertEquals(sumBytes, args); assertEquals( `${sumBytes} B`, - testElement.root.querySelector('#displayName .data-unit') - .textContent.trim()); + testElement.shadowRoot! + .querySelector<HTMLElement>( + '#displayName .data-unit')!.textContent!.trim()); }); }); @@ -320,7 +312,7 @@ testElement.siteGroup = testSiteGroup; flush(); assertEquals( - testElement.$.collapseParent.querySelector('site-favicon').url, + testElement.$.collapseParent.querySelector('site-favicon')!.url, 'https://www.example.com'); }); @@ -334,7 +326,7 @@ testElement.siteGroup = testSiteGroup; flush(); assertEquals( - testElement.$.collapseParent.querySelector('site-favicon').url, + testElement.$.collapseParent.querySelector('site-favicon')!.url, 'https://login.example.com'); }); @@ -351,7 +343,7 @@ testElement.siteGroup = testSiteGroup; flush(); assertEquals( - testElement.$.collapseParent.querySelector('site-favicon').url, + testElement.$.collapseParent.querySelector('site-favicon')!.url, 'https://abc.example.com'); }); @@ -376,13 +368,16 @@ assertEquals(3, origins.length); assertEquals( 'www.example.com', - origins[0].querySelector('#originSiteRepresentation').innerText.trim()); + origins[0]!.querySelector<HTMLElement>( + '#originSiteRepresentation')!.innerText.trim()); assertEquals( 'example.com', - origins[1].querySelector('#originSiteRepresentation').innerText.trim()); + origins[1]!.querySelector<HTMLElement>( + '#originSiteRepresentation')!.innerText.trim()); assertEquals( 'login.example.com', - origins[2].querySelector('#originSiteRepresentation').innerText.trim()); + origins[2]!.querySelector<HTMLElement>( + '#originSiteRepresentation')!.innerText.trim()); }); test('can be sorted by storage', function() { @@ -406,13 +401,16 @@ assertEquals(3, origins.length); assertEquals( 'www.example.com', - origins[0].querySelector('#originSiteRepresentation').innerText.trim()); + origins[0]!.querySelector<HTMLElement>( + '#originSiteRepresentation')!.innerText.trim()); assertEquals( 'login.example.com', - origins[1].querySelector('#originSiteRepresentation').innerText.trim()); + origins[1]!.querySelector<HTMLElement>( + '#originSiteRepresentation')!.innerText.trim()); assertEquals( 'example.com', - origins[2].querySelector('#originSiteRepresentation').innerText.trim()); + origins[2]!.querySelector<HTMLElement>( + '#originSiteRepresentation')!.innerText.trim()); }); test('can be sorted by name', function() { @@ -436,20 +434,22 @@ assertEquals(3, origins.length); assertEquals( 'example.com', - origins[0].querySelector('#originSiteRepresentation').innerText.trim()); + origins[0]!.querySelector<HTMLElement>( + '#originSiteRepresentation')!.innerText.trim()); assertEquals( 'login.example.com', - origins[1].querySelector('#originSiteRepresentation').innerText.trim()); + origins[1]!.querySelector<HTMLElement>( + '#originSiteRepresentation')!.innerText.trim()); assertEquals( 'www.example.com', - origins[2].querySelector('#originSiteRepresentation').innerText.trim()); + origins[2]!.querySelector<HTMLElement>( + '#originSiteRepresentation')!.innerText.trim()); }); }); suite('SiteEntry_EnabledConsolidatedControls', function() { /** * An example eTLD+1 Object with multiple origins grouped under it. - * @type {!SiteGroup} */ const TEST_MULTIPLE_SITE_GROUP = createSiteGroup('example.com', [ 'http://example.com', @@ -458,39 +458,19 @@ ]); /** - * An example eTLD+1 Object with a single origin in it. - * @type {!SiteGroup} - */ - const TEST_SINGLE_SITE_GROUP = createSiteGroup('foo.com', [ - 'https://login.foo.com', - ]); - - const TEST_COOKIE_LIST = { - id: 'foo', - children: [ - {domain: 'example.com'}, - {domain: 'example.com'}, - {domain: 'example.com'}, - ] - }; - - /** * The mock proxy object to use during test. - * @type {TestSiteSettingsPrefsBrowserProxy} */ - let browserProxy; + let browserProxy: TestSiteSettingsPrefsBrowserProxy; /** * The mock local data proxy object to use during test. - * @type {TestLocalDataBrowserProxy} */ - let localDataBrowserProxy; + let localDataBrowserProxy: TestLocalDataBrowserProxy; /** * A site list element created before each test. - * @type {SiteList} */ - let testElement; + let testElement: SiteEntryElement; suiteSetup(function() { loadTimeData.overrideValues({ @@ -502,12 +482,11 @@ setup(function() { browserProxy = new TestSiteSettingsPrefsBrowserProxy(); localDataBrowserProxy = new TestLocalDataBrowserProxy(); - SiteSettingsPrefsBrowserProxyImpl.instance_ = browserProxy; - LocalDataBrowserProxyImpl.instance_ = localDataBrowserProxy; + SiteSettingsPrefsBrowserProxyImpl.setInstance(browserProxy); + LocalDataBrowserProxyImpl.setInstance(localDataBrowserProxy); - PolymerTest.clearBody(); + document.body.innerHTML = ''; testElement = document.createElement('site-entry'); - assertTrue(!!testElement); document.body.appendChild(testElement); }); @@ -523,13 +502,13 @@ for (let i = 0; i < originList.length; i++) { const siteRemoved = eventToPromise('remove-site', testElement); - originList[i].querySelector('#removeOriginButton').click(); + originList[i]!.querySelector<HTMLElement>('#removeOriginButton')!.click(); const siteRemovedEvent = await siteRemoved; const {actionScope, index, origin} = siteRemovedEvent.detail; assertEquals('origin', actionScope); assertEquals(testElement.listIndex, index); - assertEquals(testElement.siteGroup.origins[i].origin, origin); + assertEquals(testElement.siteGroup.origins[i]!.origin, origin); } }); @@ -539,7 +518,7 @@ flush(); const siteRemoved = eventToPromise('remove-site', testElement); - testElement.$$('#removeSiteButton').click(); + testElement.$$<HTMLElement>('#removeSiteButton')!.click(); const siteRemovedEvent = await siteRemoved; const {actionScope, index, origin} = siteRemovedEvent.detail;
diff --git a/chrome/test/origin_policy/origin_policy_browsertest.cc b/chrome/test/origin_policy/origin_policy_browsertest.cc index f1bebfa..1b83b66 100644 --- a/chrome/test/origin_policy/origin_policy_browsertest.cc +++ b/chrome/test/origin_policy/origin_policy_browsertest.cc
@@ -5,10 +5,19 @@ #include "base/bind.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/chrome_content_browser_client.h" +#include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/security_interstitials/content/security_interstitial_page.h" +#include "components/security_interstitials/content/security_interstitial_tab_helper.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition_config.h" +#include "content/public/common/content_client.h" #include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" +#include "content/public/test/content_mock_cert_verifier.h" +#include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" @@ -21,6 +30,35 @@ // The title of the Origin Policy error interstitial. This is used to determine // whether the page load was blocked by the origin policy throttle. const char16_t kErrorInterstitialTitle[] = u"Origin Policy Error"; + +class TestContentBrowserClient : public ChromeContentBrowserClient { + public: + TestContentBrowserClient(const GURL& site, + const std::string& partition_domain) + : site_(site), partition_domain_(partition_domain) {} + ~TestContentBrowserClient() override = default; + TestContentBrowserClient(const TestContentBrowserClient&) = delete; + TestContentBrowserClient& operator=(const TestContentBrowserClient&) = delete; + + protected: + // ChromeContentBrowserClient: + content::StoragePartitionConfig GetStoragePartitionConfigForSite( + content::BrowserContext* browser_context, + const GURL& site) override { + if (site == site_) { + return content::StoragePartitionConfig::Create( + browser_context, partition_domain_, /*partition_name=*/"", + browser_context->IsOffTheRecord()); + } + return ChromeContentBrowserClient::GetStoragePartitionConfigForSite( + browser_context, site); + } + + private: + GURL site_; + std::string partition_domain_; +}; + } // namespace namespace content { @@ -39,7 +77,13 @@ ~OriginPolicyBrowserTest() override = default; + void SetUpCommandLine(base::CommandLine* command_line) override { + InProcessBrowserTest::SetUpCommandLine(command_line); + mock_cert_verifier_.SetUpCommandLine(command_line); + } + void SetUpInProcessBrowserTestFixture() override { + mock_cert_verifier_.SetUpInProcessBrowserTestFixture(); server_ = std::make_unique<net::test_server::EmbeddedTestServer>( net::test_server::EmbeddedTestServer::TYPE_HTTPS); server_->AddDefaultHandlers(base::FilePath(kDataRoot)); @@ -50,17 +94,27 @@ feature_list_.InitAndEnableFeature(features::kOriginPolicy); } - void TearDownInProcessBrowserTestFixture() override { server_.reset(); } + void SetUpOnMainThread() override { + host_resolver()->AddRule("*", "127.0.0.1"); + mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK); + } + + void TearDownInProcessBrowserTestFixture() override { + server_.reset(); + mock_cert_verifier_.TearDownInProcessBrowserTestFixture(); + } net::test_server::EmbeddedTestServer* server() { return server_.get(); } // Most tests here are set up to use the page title to distinguish between // successful load or the error page. For those tests, this method implements // the bulk of the test logic. - std::u16string NavigateToAndReturnTitle(const char* url) { + std::u16string NavigateToAndReturnTitle(const char* path, + const char* host = nullptr) { EXPECT_TRUE(server()); - EXPECT_TRUE( - ui_test_utils::NavigateToURL(browser(), GURL(server()->GetURL(url)))); + GURL url = + GURL(host ? server()->GetURL(host, path) : server()->GetURL(path)); + EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); std::u16string title; ui_test_utils::GetCurrentTabTitle(browser(), &title); return title; @@ -94,6 +148,7 @@ } std::unique_ptr<net::test_server::EmbeddedTestServer> server_; + content::ContentMockCertVerifier mock_cert_verifier_; base::test::ScopedFeatureList feature_list_; net::HttpStatusCode status_; @@ -144,4 +199,43 @@ NavigateToAndReturnTitle("/page-with-policy.html")); } +IN_PROC_BROWSER_TEST_F(OriginPolicyBrowserTest, NonDefaultStoragePartition) { + const char* partitioned_host = "partitioned.com"; + const char* partitioned_site = "https://partitioned.com/"; + const char* normal_host = "example.com"; + + TestContentBrowserClient test_browser_client(GURL(partitioned_site), + "test_partition"); + content::ContentBrowserClient* old_browser_client = + content::SetBrowserClientForTesting(&test_browser_client); + + SetStatus(net::HTTP_TEMPORARY_REDIRECT); + SetLocationHeader("/.well-known/origin-policy/example-policy"); + + // Verify that both the normal and partitioned pages hit the interstitial. + EXPECT_EQ(kErrorInterstitialTitle, + NavigateToAndReturnTitle("/page-with-policy.html", normal_host)); + EXPECT_EQ( + kErrorInterstitialTitle, + NavigateToAndReturnTitle("/page-with-policy.html", partitioned_host)); + + // Simulate clicking Allow in the interstitial. + auto* helper = + security_interstitials::SecurityInterstitialTabHelper::FromWebContents( + browser()->tab_strip_model()->GetActiveWebContents()); + auto* interstitial = + helper->GetBlockingPageForCurrentlyCommittedNavigationForTesting(); + EXPECT_NE(nullptr, interstitial); + interstitial->CommandReceived("1"); // "1" == Proceed + + // The normal site should still be blocked, but not the partitioned one. + EXPECT_EQ(kErrorInterstitialTitle, + NavigateToAndReturnTitle("/page-with-policy.html", normal_host)); + EXPECT_EQ( + u"Page With Policy", + NavigateToAndReturnTitle("/page-with-policy.html", partitioned_host)); + + content::SetBrowserClientForTesting(old_browser_client); +} + } // namespace content
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 40982ea..0847e9a 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -2419,6 +2419,47 @@ <message name="IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_SKU_WARNING" translateable="false" desc="The text warning explaining when the device's SKU should be changed."> The SKU should only be changed if the new component(s) are different from the ones they replaced. For example, a touchscreen replacing a non-touchscreen, or memory being upgraded from 8GB to 16GB. </message> + + <!-- Firmware Update --> + <message name="IDS_FIRMWARE_TITLE_TEXT" desc="The title of the Firmware update app."> + Update peripherals + </message> + <message name="IDS_FIRMWARE_CRITICAL_UPDATE_TEXT" desc="The text shown when an update is deemed critcal."> + Critical update + </message> + <message name="IDS_FIRMWARE_PREPARE_DEVICE_TEXT" desc="Title of the dialog that explains how to prepare the device to be updated."> + Prepare your device + </message> + <message name="IDS_FIRMWARE_NEXT_BUTTON_TEXT" desc="Label for button that transitions the user to the firmware update dialog."> + Next + </message> + <message name="IDS_FIRMWARE_CANCEL_BUTTON_TEXT" desc="Label for the button that cancels the dialog."> + Cancel + </message> + <message name="IDS_FIRMWARE_DONE_BUTTON_TEXT" desc="Label for button shown when the firmware update is completed."> + Done + </message> + <message name="IDS_FIRMWARE_UPDATE_BUTTON_TEXT" desc="Label for button to start the firmware update."> + Update + </message> + <message name="IDS_FIRMWARE_UPDATING_TEXT" desc="Label for showing that a device is being updated."> + Updating <ph name="DEVICE_NAME">$1<ex>Logitech keyboard</ex></ph> + </message> + <message name="IDS_FIRMWARE_DEVICE_UP_TO_DATE_TEXT" desc="Label for when a device is up to date."> + Your <ph name="DEVICE_NAME">$1<ex>Logitech keyboard</ex></ph> is up to date + </message> + <message name="IDS_FIRMWARE_HAS_BEEN_UPDATED_TEXT" desc="Label for displaying which version the device has been updated to."> + Firmware <ph name="DEVICE_NAME">$1<ex>Logitech keyboard</ex></ph> has been updated to version <ph name="VERSION">$2<ex>2.0.12</ex></ph> + </message> + <message name="IDS_FIRMWARE_UPDATING_INFO_TEXT" desc="Label for communicating information about what actions a user can take during an update."> + While updating, you can minimize window but do not unplug your device. This may take a few minutes and your device might not work during this update + </message> + <message name="IDS_FIRMWARE_INSTALLING_TEXT" desc="Label that displays what percentage of the update has been installed."> + Installing - <ph name="PERCENTAGE_VALUE">$1<ex>94</ex></ph>% + </message> + <message name="IDS_FIRMWARE_UP_TO_DATE_TEXT" desc="Label shown when no firmware updates are available."> + All peripherals are up to date + </message> </messages> </release> </grit>
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_CANCEL_BUTTON_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_CANCEL_BUTTON_TEXT.png.sha1 new file mode 100644 index 0000000..979db84 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_CANCEL_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@ +1461b5afa4350cb9eef34ba915a00055948b40a3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_CRITICAL_UPDATE_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_CRITICAL_UPDATE_TEXT.png.sha1 new file mode 100644 index 0000000..7306ba4 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_CRITICAL_UPDATE_TEXT.png.sha1
@@ -0,0 +1 @@ +1d73a1c1768c5d710a3fd1f8cb0206a81266ef4c \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_DEVICE_UP_TO_DATE_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_DEVICE_UP_TO_DATE_TEXT.png.sha1 new file mode 100644 index 0000000..416a2c461 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_DEVICE_UP_TO_DATE_TEXT.png.sha1
@@ -0,0 +1 @@ +eeb9a317e7c1a463aa7e50401202e7a1c57c626e \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_DONE_BUTTON_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_DONE_BUTTON_TEXT.png.sha1 new file mode 100644 index 0000000..416a2c461 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_DONE_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@ +eeb9a317e7c1a463aa7e50401202e7a1c57c626e \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_HAS_BEEN_UPDATED_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_HAS_BEEN_UPDATED_TEXT.png.sha1 new file mode 100644 index 0000000..416a2c461 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_HAS_BEEN_UPDATED_TEXT.png.sha1
@@ -0,0 +1 @@ +eeb9a317e7c1a463aa7e50401202e7a1c57c626e \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_INSTALLING_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_INSTALLING_TEXT.png.sha1 new file mode 100644 index 0000000..947663d --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_INSTALLING_TEXT.png.sha1
@@ -0,0 +1 @@ +547ccff2209eb9e2e7c7a0886563ab0b3d6d0712 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_NEXT_BUTTON_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_NEXT_BUTTON_TEXT.png.sha1 new file mode 100644 index 0000000..979db84 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_NEXT_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@ +1461b5afa4350cb9eef34ba915a00055948b40a3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_PREPARE_DEVICE_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_PREPARE_DEVICE_TEXT.png.sha1 new file mode 100644 index 0000000..979db84 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_PREPARE_DEVICE_TEXT.png.sha1
@@ -0,0 +1 @@ +1461b5afa4350cb9eef34ba915a00055948b40a3 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_TITLE_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_TITLE_TEXT.png.sha1 new file mode 100644 index 0000000..7306ba4 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_TITLE_TEXT.png.sha1
@@ -0,0 +1 @@ +1d73a1c1768c5d710a3fd1f8cb0206a81266ef4c \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UPDATE_BUTTON_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UPDATE_BUTTON_TEXT.png.sha1 new file mode 100644 index 0000000..7306ba4 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UPDATE_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@ +1d73a1c1768c5d710a3fd1f8cb0206a81266ef4c \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UPDATING_INFO_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UPDATING_INFO_TEXT.png.sha1 new file mode 100644 index 0000000..947663d --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UPDATING_INFO_TEXT.png.sha1
@@ -0,0 +1 @@ +547ccff2209eb9e2e7c7a0886563ab0b3d6d0712 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UPDATING_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UPDATING_TEXT.png.sha1 new file mode 100644 index 0000000..947663d --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UPDATING_TEXT.png.sha1
@@ -0,0 +1 @@ +547ccff2209eb9e2e7c7a0886563ab0b3d6d0712 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UP_TO_DATE_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UP_TO_DATE_TEXT.png.sha1 new file mode 100644 index 0000000..1abc3aa --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_FIRMWARE_UP_TO_DATE_TEXT.png.sha1
@@ -0,0 +1 @@ +9c92a6bebf3322c3f093d75188aada094ff64c8f \ No newline at end of file
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index 312d283..641c144 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -117,9 +117,8 @@ // account-based storage when sync the transport is enabled. const base::Feature kAutofillEnableAccountWalletStorage { "AutofillEnableAccountWalletStorage", -#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_IOS) - // Wallet transport is only currently available on Win/Mac/Linux/Android. - // (Somehow, swapping this check makes iOS unhappy?) +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Wallet transport is currently unavailable on ChromeOS. base::FEATURE_DISABLED_BY_DEFAULT #else base::FEATURE_ENABLED_BY_DEFAULT
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index d1cb9020..e17f6790 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -90,13 +90,8 @@ // When enabled and user is signed in, a footer indicating user's e-mail address // and profile picture will appear at the bottom of SaveCardInfoBar. const base::Feature kAutofillEnableSaveCardInfoBarAccountIndicationFooter{ - "AutofillEnableSaveCardInfoBarAccountIndicationFooter", -#if defined(OS_IOS) - base::FEATURE_DISABLED_BY_DEFAULT -#else - base::FEATURE_ENABLED_BY_DEFAULT -#endif -}; + "AutofillEnableSaveCardInfoBarAccountIndicationFooter", + base::FEATURE_ENABLED_BY_DEFAULT}; // When enabled, if the user interacts with the manual fallback bottom sheet // on Android, it'll remain sticky until the user dismisses it.
diff --git a/components/policy/test_support/BUILD.gn b/components/policy/test_support/BUILD.gn index b8d7860..173d599 100644 --- a/components/policy/test_support/BUILD.gn +++ b/components/policy/test_support/BUILD.gn
@@ -5,7 +5,10 @@ static_library("test_support") { testonly = true - data = [ "policy_testserver.py" ] + data = [ + "asn1der.py", + "policy_testserver.py", + ] sources = [ "client_storage.cc",
diff --git a/components/policy/test_support/OWNERS b/components/policy/test_support/OWNERS index 76cec38b..a60e0da6 100644 --- a/components/policy/test_support/OWNERS +++ b/components/policy/test_support/OWNERS
@@ -1,3 +1,4 @@ # policy_testserver.py is used in tast and autotest integration tests. per-file policy_testserver.py=ftirelo@chromium.org, pmarko@chromium.org, vsavu@google.com +per-file asn1der.py=ftirelo@chromium.org, pmarko@chromium.org, vsavu@google.com
diff --git a/components/policy/test_support/asn1der.py b/components/policy/test_support/asn1der.py new file mode 100644 index 0000000..00aca5c --- /dev/null +++ b/components/policy/test_support/asn1der.py
@@ -0,0 +1,69 @@ +# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Helper module for ASN.1/DER encoding.""" + +import binascii +import struct + +# Tags as defined by ASN.1. +INTEGER = 2 +BIT_STRING = 3 +NULL = 5 +OBJECT_IDENTIFIER = 6 +SEQUENCE = 0x30 + +def Data(tag, data): + """Generic type-length-value encoder. + + Args: + tag: the tag. + data: the data for the given tag. + Returns: + encoded TLV value. + """ + if len(data) < 128: + return struct.pack(">BB", tag, len(data)) + data; + assert len(data) <= 0xffff; + return struct.pack(">BBH", tag, 0x82, len(data)) + data; + +def Integer(value): + """Encodes an integer. + + Args: + value: the long value. + Returns: + encoded TLV value. + """ + data = '%x' % value + if (len(data) % 2 == 1): + # Odd number of non-zero bytes - pad out our data to a full number of bytes. + data = '0' + data + + # If the high bit is set, need to prepend a null byte to denote a positive + # number. + if (int(data[0], 16) >= 8): + data = '00' + data + + return Data(INTEGER, binascii.unhexlify(data)) + +def Bitstring(value): + """Encodes a bit string. + + Args: + value: a string holding the binary data. + Returns: + encoded TLV value. + """ + return Data(BIT_STRING, b'\x00' + value) + +def Sequence(values): + """Encodes a sequence of other values. + + Args: + values: the list of values, must be strings holding already encoded data. + Returns: + encoded TLV value. + """ + return Data(SEQUENCE, b''.join(values))
diff --git a/components/policy/test_support/policy_testserver.py b/components/policy/test_support/policy_testserver.py index 06980ee..d123cbe0 100644 --- a/components/policy/test_support/policy_testserver.py +++ b/components/policy/test_support/policy_testserver.py
@@ -65,8 +65,6 @@ import base64 from six.moves import BaseHTTPServer -from cryptography.hazmat.primitives.asymmetric import padding, rsa -from cryptography.hazmat.primitives import hashes, serialization import glob import google.protobuf.text_format import hashlib @@ -78,10 +76,15 @@ import six import sys import time +import tlslite +import tlslite.api +import tlslite.utils +import tlslite.utils.cryptomath from six.moves import urllib from six.moves.urllib import request as urllib_request from six.moves.urllib import parse as urlparse +import asn1der import testserver_base import device_management_backend_pb2 as dm @@ -110,6 +113,9 @@ except ImportError: crypto = None +# ASN.1 object identifier for PKCS#1/RSA. +PKCS1_RSA_OID = b'\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01' + # List of machines that trigger the server to send kiosk enrollment response # for the register request. KIOSK_MACHINE_IDS = [ 'KIOSK' ] @@ -1336,8 +1342,8 @@ # Sign the serialized policy data if msg.signature_type == dm.PolicyFetchRequest.SHA1_RSA: - response.policy_data_signature = signing_key['private_key'].sign( - response.policy_data, padding.PKCS1v15(), hashes.SHA1()) + response.policy_data_signature = bytes( + signing_key['private_key'].hashAndSign(response.policy_data)) if msg.public_key_version != signing_key_version: response.new_public_key = signing_key['public_key'] @@ -1353,8 +1359,8 @@ verification_sig) if client_key is not None: - response.new_public_key_signature = client_key['private_key'].sign( - response.new_public_key, padding.PKCS1v15(), hashes.SHA1()) + response.new_public_key_signature = bytes( + client_key['private_key'].hashAndSign(response.new_public_key)) return (200, response.SerializeToString()) @@ -1556,14 +1562,15 @@ print('Failed to load private key from %s' % key_path) continue try: - key = serialization.load_pem_private_key(key_str, password=None) - except ValueError: - key = serialization.load_der_private_key(key_str, password=None) + # Decode with replacement characters to avoid decode errors if was + # actually DER. + key = tlslite.api.parsePEMKey(key_str.decode('utf-8', 'replace'), + private=True) + except SyntaxError: + key = tlslite.utils.python_rsakey.Python_RSAKey._parsePKCS8( + bytearray(key_str)) assert key is not None - if not isinstance(key, rsa.RSAPrivateKey): - raise TypeError('Unexpected key type') - key_info = { 'private_key' : key } # Now try to read in a signature, if one exists. @@ -1578,9 +1585,9 @@ # Use the canned private keys if none were passed from the command line. for signing_key in SIGNING_KEYS: decoded_key = base64.b64decode(signing_key['key']); - key = serialization.load_der_private_key(decoded_key, password=None) + key = tlslite.utils.python_rsakey.Python_RSAKey._parsePKCS8( + bytearray(decoded_key)) assert key is not None - assert isinstance(key, rsa.RSAPrivateKey) # Grab the signature dictionary for this key and decode all of the # signatures. signature_dict = signing_key['signatures'] @@ -1592,9 +1599,15 @@ # Derive the public keys from the private keys. for entry in self.keys: - entry['public_key'] = entry['private_key'].public_key().public_bytes( - encoding=serialization.Encoding.DER, - format=serialization.PublicFormat.SubjectPublicKeyInfo) + key = entry['private_key'] + + algorithm = asn1der.Sequence( + [ asn1der.Data(asn1der.OBJECT_IDENTIFIER, PKCS1_RSA_OID), + asn1der.Data(asn1der.NULL, b'') ]) + rsa_pubkey = asn1der.Sequence([ asn1der.Integer(key.n), + asn1der.Integer(key.e) ]) + pubkey = asn1der.Sequence([ algorithm, asn1der.Bitstring(rsa_pubkey) ]) + entry['public_key'] = pubkey try: self.ReadClientStateFile()
diff --git a/components/security_interstitials/content/origin_policy_interstitial_page.cc b/components/security_interstitials/content/origin_policy_interstitial_page.cc index d64ff95c..dc74b84f 100644 --- a/components/security_interstitials/content/origin_policy_interstitial_page.cc +++ b/components/security_interstitials/content/origin_policy_interstitial_page.cc
@@ -22,12 +22,14 @@ OriginPolicyInterstitialPage::OriginPolicyInterstitialPage( content::WebContents* web_contents, + content::StoragePartition* storage_partition, const GURL& request_url, std::unique_ptr<SecurityInterstitialControllerClient> controller, network::OriginPolicyState error_reason) : SecurityInterstitialPage(web_contents, request_url, std::move(controller)), + storage_partition_(storage_partition), error_reason_(error_reason) {} OriginPolicyInterstitialPage::~OriginPolicyInterstitialPage() = default; @@ -116,8 +118,7 @@ } void OriginPolicyInterstitialPage::Proceed() { - content::OriginPolicyAddExceptionFor(web_contents()->GetBrowserContext(), - request_url()); + content::OriginPolicyAddExceptionFor(storage_partition_, request_url()); web_contents()->GetController().Reload(content::ReloadType::NORMAL, true); }
diff --git a/components/security_interstitials/content/origin_policy_interstitial_page.h b/components/security_interstitials/content/origin_policy_interstitial_page.h index c36d436..12dddb4 100644 --- a/components/security_interstitials/content/origin_policy_interstitial_page.h +++ b/components/security_interstitials/content/origin_policy_interstitial_page.h
@@ -15,6 +15,7 @@ #include "url/gurl.h" namespace content { +class StoragePartition; class WebContents; } // namespace content @@ -25,6 +26,7 @@ public: OriginPolicyInterstitialPage( content::WebContents* web_contents, + content::StoragePartition* storage_partition, const GURL& request_url, std::unique_ptr<SecurityInterstitialControllerClient> controller, network::OriginPolicyState error_reason); @@ -43,6 +45,7 @@ void PopulateInterstitialStrings(base::Value*) override; private: + content::StoragePartition* storage_partition_; network::OriginPolicyState error_reason_; void Proceed();
diff --git a/components/security_interstitials/content/origin_policy_ui.cc b/components/security_interstitials/content/origin_policy_ui.cc index 241d2e4..343fd88 100644 --- a/components/security_interstitials/content/origin_policy_ui.cc +++ b/components/security_interstitials/content/origin_policy_ui.cc
@@ -12,7 +12,9 @@ #include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "components/security_interstitials/content/settings_page_helper.h" #include "components/security_interstitials/core/metrics_helper.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_handle.h" +#include "content/public/browser/storage_partition.h" #include "services/network/public/cpp/origin_policy.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" @@ -24,6 +26,7 @@ std::unique_ptr<SecurityInterstitialPage> GetErrorPageImpl( network::OriginPolicyState error_reason, content::WebContents* web_contents, + content::StoragePartition* storage_partition, const GURL& url) { MetricsHelper::ReportDetails report_details; report_details.metric_prefix = "origin_policy"; @@ -34,7 +37,8 @@ nullptr, /* pref service: can be null */ "", GURL(), /* settings_page_helper: not used */ nullptr); return std::make_unique<security_interstitials::OriginPolicyInterstitialPage>( - web_contents, url, std::move(controller), error_reason); + web_contents, storage_partition, url, std::move(controller), + error_reason); } } // namespace @@ -44,7 +48,8 @@ content::NavigationHandle* handle) { DCHECK(handle); std::unique_ptr<SecurityInterstitialPage> page(GetErrorPageImpl( - error_reason, handle->GetWebContents(), handle->GetURL())); + error_reason, handle->GetWebContents(), + handle->GetRenderFrameHost()->GetStoragePartition(), handle->GetURL())); std::string html = page->GetHTMLContents(); // The page object is "associated" with the web contents, and this is how @@ -59,7 +64,11 @@ network::OriginPolicyState error_reason, content::WebContents* web_contents, const GURL& url) { - return GetErrorPageImpl(error_reason, web_contents, url).release(); + return GetErrorPageImpl( + error_reason, web_contents, + web_contents->GetBrowserContext()->GetDefaultStoragePartition(), + url) + .release(); } } // namespace security_interstitials
diff --git a/components/viz/test/test_gpu_service_holder.cc b/components/viz/test/test_gpu_service_holder.cc index 71a9e395..42e39142 100644 --- a/components/viz/test/test_gpu_service_holder.cc +++ b/components/viz/test/test_gpu_service_holder.cc
@@ -33,6 +33,7 @@ #endif #if defined(USE_OZONE) +#include "ui/ozone/public/gpu_platform_support_host.h" #include "ui/ozone/public/ozone_platform.h" #endif @@ -40,6 +41,12 @@ namespace { +#if defined(USE_OZONE) && !defined(OS_FUCHSIA) +namespace { +constexpr int kGpuProcessHostId = 1; +} // namespace +#endif + base::Lock& GetLock() { static base::NoDestructor<base::Lock> lock; return *lock; @@ -160,9 +167,26 @@ base::BindOnce(&TestGpuServiceHolder::InitializeOnGpuThread, base::Unretained(this), gpu_preferences, &completion)); completion.Wait(); + +#if defined(USE_OZONE) && !defined(OS_FUCHSIA) + if (auto* gpu_platform_support_host = + ui::OzonePlatform::GetInstance()->GetGpuPlatformSupportHost()) { + auto interface_binder = base::BindRepeating( + &TestGpuServiceHolder::BindInterface, base::Unretained(this)); + gpu_platform_support_host->OnGpuServiceLaunched( + kGpuProcessHostId, interface_binder, base::DoNothing()); + } +#endif } TestGpuServiceHolder::~TestGpuServiceHolder() { +#if defined(USE_OZONE) && !defined(OS_FUCHSIA) + if (auto* gpu_platform_support_host = + ui::OzonePlatform::GetInstance()->GetGpuPlatformSupportHost()) { + gpu_platform_support_host->OnChannelDestroyed(kGpuProcessHostId); + } +#endif + // Ensure members created on GPU thread are destroyed there too. gpu_thread_.task_runner()->PostTask( FROM_HERE, base::BindOnce(&TestGpuServiceHolder::DeleteOnGpuThread, @@ -190,6 +214,10 @@ base::WaitableEvent* completion) { DCHECK(gpu_thread_.task_runner()->BelongsToCurrentThread()); +#if defined(USE_OZONE) && !defined(OS_FUCHSIA) + ui::OzonePlatform::GetInstance()->AddInterfaces(&binders_); +#endif + if (gpu_preferences.use_vulkan != gpu::VulkanImplementationName::kNone) { #if BUILDFLAG(ENABLE_VULKAN) bool use_swiftshader = gpu_preferences.use_vulkan == @@ -270,4 +298,27 @@ gpu_service_.reset(); } +#if defined(USE_OZONE) && !defined(OS_FUCHSIA) +void TestGpuServiceHolder::BindInterface( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) { + // The interfaces must be bound on the gpu to ensure the mojo calls happen + // on the correct sequence (same happens when the browser runs with a real + // gpu service). + gpu_thread_.task_runner()->PostTask( + FROM_HERE, base::BindOnce(&TestGpuServiceHolder::BindInterfaceOnGpuThread, + base::Unretained(this), interface_name, + std::move(interface_pipe))); +} + +void TestGpuServiceHolder::BindInterfaceOnGpuThread( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) { + mojo::GenericPendingReceiver receiver = + mojo::GenericPendingReceiver(interface_name, std::move(interface_pipe)); + CHECK(binders_.TryBind(&receiver)) + << "Unable to find mojo interface " << interface_name; +} +#endif // defined(USE_OZONE) && !defined(OS_FUCHSIA) + } // namespace viz
diff --git a/components/viz/test/test_gpu_service_holder.h b/components/viz/test/test_gpu_service_holder.h index 7b11108..6c32c617 100644 --- a/components/viz/test/test_gpu_service_holder.h +++ b/components/viz/test/test_gpu_service_holder.h
@@ -6,13 +6,19 @@ #define COMPONENTS_VIZ_TEST_TEST_GPU_SERVICE_HOLDER_H_ #include <memory> +#include <string> #include "base/feature_list.h" #include "base/memory/scoped_refptr.h" #include "base/threading/thread.h" +#include "build/build_config.h" #include "gpu/ipc/gpu_in_process_thread_service.h" #include "gpu/vulkan/buildflags.h" +#if defined(USE_OZONE) && !defined(OS_FUCHSIA) +#include "mojo/public/cpp/bindings/binder_map.h" +#endif + namespace gpu { class CommandBufferTaskExecutor; class SingleTaskSequence; @@ -95,6 +101,14 @@ base::WaitableEvent* completion); void DeleteOnGpuThread(); +// TODO(crbug.com/1267788): Fuchsia crashes. See details in the crbug. +#if defined(USE_OZONE) && !defined(OS_FUCHSIA) + void BindInterface(const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe); + void BindInterfaceOnGpuThread(const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe); +#endif + #if !defined(OS_CHROMEOS) // TODO(crbug.com/1241161): This is equally applicable to Chrome OS there are // just a number of tests that already override the feature list after it's no @@ -115,6 +129,11 @@ #if BUILDFLAG(ENABLE_VULKAN) std::unique_ptr<gpu::VulkanImplementation> vulkan_implementation_; #endif + +#if defined(USE_OZONE) && !defined(OS_FUCHSIA) + // Bound interfaces. + mojo::BinderMap binders_; +#endif }; } // namespace viz
diff --git a/content/browser/devtools/protocol/input_handler.cc b/content/browser/devtools/protocol/input_handler.cc index 7cc2fab0..18ccc68 100644 --- a/content/browser/devtools/protocol/input_handler.cc +++ b/content/browser/devtools/protocol/input_handler.cc
@@ -133,6 +133,7 @@ bool GetMouseEventButton(const std::string& button, blink::WebPointerProperties::Button* event_button, int* event_modifiers) { + *event_modifiers = blink::WebInputEvent::kFromDebugger; if (button.empty()) return true; @@ -140,19 +141,19 @@ *event_button = blink::WebMouseEvent::Button::kNoButton; } else if (button == Input::MouseButtonEnum::Left) { *event_button = blink::WebMouseEvent::Button::kLeft; - *event_modifiers = blink::WebInputEvent::kLeftButtonDown; + *event_modifiers |= blink::WebInputEvent::kLeftButtonDown; } else if (button == Input::MouseButtonEnum::Middle) { *event_button = blink::WebMouseEvent::Button::kMiddle; - *event_modifiers = blink::WebInputEvent::kMiddleButtonDown; + *event_modifiers |= blink::WebInputEvent::kMiddleButtonDown; } else if (button == Input::MouseButtonEnum::Right) { *event_button = blink::WebMouseEvent::Button::kRight; - *event_modifiers = blink::WebInputEvent::kRightButtonDown; + *event_modifiers |= blink::WebInputEvent::kRightButtonDown; } else if (button == Input::MouseButtonEnum::Back) { *event_button = blink::WebMouseEvent::Button::kBack; - *event_modifiers = blink::WebInputEvent::kBackButtonDown; + *event_modifiers |= blink::WebInputEvent::kBackButtonDown; } else if (button == Input::MouseButtonEnum::Forward) { *event_button = blink::WebMouseEvent::Button::kForward; - *event_modifiers = blink::WebInputEvent::kForwardButtonDown; + *event_modifiers |= blink::WebInputEvent::kForwardButtonDown; } else { return false; } @@ -1368,7 +1369,7 @@ if (!synthetic_pointer_driver_) { synthetic_pointer_driver_ = - SyntheticPointerDriver::Create(gesture_source_type); + SyntheticPointerDriver::Create(gesture_source_type, true); } std::unique_ptr<SyntheticPointerAction> synthetic_gesture = std::make_unique<SyntheticPointerAction>(action_list_params); @@ -1564,6 +1565,7 @@ SyntheticPinchGestureParams gesture_params; const int kDefaultRelativeSpeed = 800; + gesture_params.from_devtools_debugger = true; gesture_params.scale_factor = scale_factor; gesture_params.anchor = CssPixelsToPointF(x, y, page_scale_factor_); if (!PointIsWithinContents(gesture_params.anchor)) { @@ -1613,6 +1615,7 @@ } SyntheticSmoothScrollGestureParams gesture_params; + gesture_params.from_devtools_debugger = true; const bool kDefaultPreventFling = true; const int kDefaultSpeed = 800; @@ -1724,6 +1727,7 @@ const int kDefaultTapCount = 1; gesture_params.position = CssPixelsToPointF(x, y, page_scale_factor_); + gesture_params.from_devtools_debugger = true; if (!PointIsWithinContents(gesture_params.position)) { callback->sendFailure(Response::InvalidParams("Position out of bounds")); return;
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 4155f010..a3a918e 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -69,6 +69,7 @@ #include "net/cert/x509_util.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_inclusion_status.h" +#include "net/cookies/cookie_partition_key.h" #include "net/cookies/cookie_util.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" @@ -190,7 +191,17 @@ if (maybe_same_site) { devtools_cookie->SetSameSite(*maybe_same_site); } - + absl::optional<net::CookiePartitionKey> partition_key = cookie.PartitionKey(); + if (partition_key) { + std::string serialized_partition_key; + if (partition_key->IsSerializeable()) { + DCHECK(net::CookiePartitionKey::Serialize(partition_key, + serialized_partition_key)); + devtools_cookie->SetPartitionKey(serialized_partition_key); + } else { + devtools_cookie->SetPartitionKeyOpaque(true); + } + } return devtools_cookie; } @@ -199,13 +210,17 @@ public: static void Retrieve(network::mojom::CookieManager* cookie_manager, const std::vector<GURL> urls, + const net::NetworkIsolationKey& network_isolation_key, std::unique_ptr<GetCookiesCallback> callback) { scoped_refptr<CookieRetrieverNetworkService> self = new CookieRetrieverNetworkService(std::move(callback)); net::CookieOptions cookie_options = net::CookieOptions::MakeAllInclusive(); for (const auto& url : urls) { cookie_manager->GetCookieList( - url, cookie_options, net::CookiePartitionKeychain::Todo(), + url, cookie_options, + net::CookiePartitionKeychain::FromOptional( + net::CookiePartitionKey::FromNetworkIsolationKey( + network_isolation_key)), base::BindOnce(&CookieRetrieverNetworkService::GotCookies, self)); } } @@ -317,7 +332,8 @@ const std::string& priority, bool same_party, const Maybe<std::string>& source_scheme, - const Maybe<int>& source_port) { + const Maybe<int>& source_port, + const Maybe<std::string>& partition_key) { std::string normalized_domain = domain; if (url_spec.empty() && domain.empty()) { @@ -373,12 +389,24 @@ else if (priority == Network::CookiePriorityEnum::Low) cp = net::CookiePriority::COOKIE_PRIORITY_LOW; + absl::optional<net::CookiePartitionKey> deserialized_partition_key; + if (partition_key.isJust()) { + if (!base::FeatureList::IsEnabled(net::features::kPartitionedCookies)) { + return Response::InvalidParams( + "Partitioned cookies disabled. Cannot set cookie partition key"); + } + if (!net::CookiePartitionKey::Deserialize(partition_key.fromJust(), + deserialized_partition_key)) { + return Response::InvalidParams( + "Deserializing cookie partition key failed"); + } + } // TODO(crbug.com/1225444) Add Partitioned to DevTools cookie structures. std::unique_ptr<net::CanonicalCookie> cookie = net::CanonicalCookie::CreateSanitizedCookie( url, name, value, normalized_domain, path, base::Time(), expiration_date, base::Time(), secure, http_only, css, cp, same_party, - absl::nullopt); + deserialized_partition_key); if (!cookie) return Response::InvalidParams("Sanitizing cookie failed"); @@ -1418,7 +1446,7 @@ CookieRetrieverNetworkService::Retrieve( storage_partition_->GetCookieManagerForBrowserProcess(), urls, - std::move(callback)); + host_->GetNetworkIsolationKey(), std::move(callback)); } void NetworkHandler::GetAllCookies( @@ -1449,6 +1477,7 @@ Maybe<bool> same_party, Maybe<std::string> source_scheme, Maybe<int> source_port, + Maybe<std::string> partition_key, std::unique_ptr<SetCookieCallback> callback) { if (!storage_partition_) { callback->sendFailure(Response::InternalError()); @@ -1459,7 +1488,7 @@ name, value, url.fromMaybe(""), domain.fromMaybe(""), path.fromMaybe(""), secure.fromMaybe(false), http_only.fromMaybe(false), same_site.fromMaybe(""), expires.fromMaybe(-1), priority.fromMaybe(""), - same_party.fromMaybe(false), source_scheme, source_port); + same_party.fromMaybe(false), source_scheme, source_port, partition_key); if (absl::holds_alternative<Response>(cookie_or_error)) { callback->sendFailure(absl::get<Response>(std::move(cookie_or_error))); @@ -1497,13 +1526,17 @@ const Maybe<int> source_port = cookie->HasSourcePort() ? Maybe<int>(cookie->GetSourcePort(0)) : Maybe<int>(); + const Maybe<std::string> partition_key = + cookie->HasPartitionKey() + ? Maybe<std::string>(cookie->GetPartitionKey("")) + : Maybe<std::string>(); auto net_cookie_or_error = MakeCookieFromProtocolValues( cookie->GetName(), cookie->GetValue(), cookie->GetUrl(""), cookie->GetDomain(""), cookie->GetPath(""), cookie->GetSecure(false), cookie->GetHttpOnly(false), cookie->GetSameSite(""), cookie->GetExpires(-1), cookie->GetPriority(""), - cookie->GetSameParty(false), source_scheme, source_port); + cookie->GetSameParty(false), source_scheme, source_port, partition_key); if (absl::holds_alternative<Response>(net_cookie_or_error)) { // TODO: Investiage whether we can report the error as a protocol error // (this might be a breaking CDP change).
diff --git a/content/browser/devtools/protocol/network_handler.h b/content/browser/devtools/protocol/network_handler.h index 024402d..5798a54e 100644 --- a/content/browser/devtools/protocol/network_handler.h +++ b/content/browser/devtools/protocol/network_handler.h
@@ -145,6 +145,7 @@ Maybe<bool> same_party, Maybe<std::string> source_scheme, Maybe<int> source_port, + Maybe<std::string> partition_key, std::unique_ptr<SetCookieCallback> callback) override; void SetCookies( std::unique_ptr<protocol::Array<Network::CookieParam>> cookies,
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc index db6bbafc..c5848f1 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc +++ b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
@@ -63,12 +63,19 @@ aura::Window* window = GetWindow(); aura::WindowTreeHost* host = window->GetHost(); - for (const auto& event : events) { - event->ConvertLocationToTarget(window, host->window()); - ui::EventDispatchDetails details = - event_injector_.Inject(host, event.get()); - if (details.dispatcher_destroyed) - break; + for (auto& event : events) { + // Synthetic events from devtools debugger need to be dispatched explicitly + // to the target window. Otherwise they will end up in the active tab + // which might be different from the target. + if (web_touch.GetModifiers() & blink::WebInputEvent::kFromDebugger) { + window->delegate()->OnEvent(event.get()); + } else { + event->ConvertLocationToTarget(window, host->window()); + ui::EventDispatchDetails details = + event_injector_.Inject(host, event.get()); + if (details.dispatcher_destroyed) + break; + } } } @@ -97,11 +104,18 @@ wheel_precision_y_ = delta_y - wheel_event.y_offset(); aura::Window* window = GetWindow(); - wheel_event.ConvertLocationToTarget(window, window->GetRootWindow()); - ui::EventDispatchDetails details = - event_injector_.Inject(window->GetHost(), &wheel_event); - if (details.dispatcher_destroyed) - return; + // Synthetic events from devtools debugger need to be dispatched explicitly + // to the target window. Otherwise they will end up in the active tab + // which might be different from the target. + if (web_wheel.GetModifiers() & blink::WebInputEvent::kFromDebugger) { + window->delegate()->OnEvent(&wheel_event); + } else { + wheel_event.ConvertLocationToTarget(window, window->GetRootWindow()); + ui::EventDispatchDetails details = + event_injector_.Inject(window->GetHost(), &wheel_event); + if (details.dispatcher_destroyed) + return; + } } void SyntheticGestureTargetAura::DispatchWebGestureEventToPlatform( @@ -123,8 +137,15 @@ web_gesture.PositionInWidget().y(), flags, web_gesture.TimeStamp(), pinch_details); - pinch_event.ConvertLocationToTarget(window, window->GetRootWindow()); - event_injector_.Inject(window->GetHost(), &pinch_event); + // Synthetic events from devtools debugger need to be dispatched explicitly + // to the target window. Otherwise they will end up in the active tab + // which might be different from the target. + if (web_gesture.GetModifiers() & blink::WebInputEvent::kFromDebugger) { + window->delegate()->OnEvent(&pinch_event); + } else { + pinch_event.ConvertLocationToTarget(window, window->GetRootWindow()); + event_injector_.Inject(window->GetHost(), &pinch_event); + } return; } @@ -138,8 +159,15 @@ web_gesture.data.fling_start.velocity_x, web_gesture.data.fling_start.velocity_y, 0, 0, 2, momentum_phase, ui::ScrollEventPhase::kNone); - scroll_event.ConvertLocationToTarget(window, window->GetRootWindow()); - event_injector_.Inject(window->GetHost(), &scroll_event); + // Synthetic events from devtools debugger need to be dispatched explicitly + // to the target window. Otherwise they will end up in the active tab + // which might be different from the target. + if (web_gesture.GetModifiers() & blink::WebInputEvent::kFromDebugger) { + window->delegate()->OnEvent(&scroll_event); + } else { + scroll_event.ConvertLocationToTarget(window, window->GetRootWindow()); + event_injector_.Inject(window->GetHost(), &scroll_event); + } } void SyntheticGestureTargetAura::DispatchWebMouseEventToPlatform( @@ -164,12 +192,19 @@ changed_button_flags, pointer_details); aura::Window* window = GetWindow(); - mouse_event.ConvertLocationToTarget(window, window->GetRootWindow()); mouse_event.SetClickCount(web_mouse_event.click_count); - ui::EventDispatchDetails details = - event_injector_.Inject(window->GetHost(), &mouse_event); - if (details.dispatcher_destroyed) - return; + // Synthetic events from devtools debugger need to be dispatched explicitly + // to the target window. Otherwise they will end up in the active tab + // which might be different from the target. + if (web_mouse_event.GetModifiers() & blink::WebInputEvent::kFromDebugger) { + window->delegate()->OnEvent(&mouse_event); + } else { + mouse_event.ConvertLocationToTarget(window, window->GetRootWindow()); + ui::EventDispatchDetails details = + event_injector_.Inject(window->GetHost(), &mouse_event); + if (details.dispatcher_destroyed) + return; + } } content::mojom::GestureSourceType
diff --git a/content/browser/renderer_host/origin_policy_throttle.cc b/content/browser/renderer_host/origin_policy_throttle.cc index 044b6e2..f20b26d 100644 --- a/content/browser/renderer_host/origin_policy_throttle.cc +++ b/content/browser/renderer_host/origin_policy_throttle.cc
@@ -27,9 +27,9 @@ // Implement the public "API" from // content/public/browser/origin_policy_commands.h: -void OriginPolicyAddExceptionFor(BrowserContext* browser_context, +void OriginPolicyAddExceptionFor(StoragePartition* storage_partition, const GURL& url) { - OriginPolicyThrottle::AddExceptionFor(browser_context, url); + OriginPolicyThrottle::AddExceptionFor(storage_partition, url); } // static @@ -57,13 +57,12 @@ } // static -void OriginPolicyThrottle::AddExceptionFor(BrowserContext* browser_context, +void OriginPolicyThrottle::AddExceptionFor(StoragePartition* storage_partition, const GURL& url) { - DCHECK(browser_context); - StoragePartitionImpl* storage_partition = static_cast<StoragePartitionImpl*>( - browser_context->GetStoragePartitionForUrl(url)); + auto* storage_partition_impl = + static_cast<StoragePartitionImpl*>(storage_partition); network::mojom::OriginPolicyManager* origin_policy_manager = - storage_partition->GetOriginPolicyManagerForBrowserProcess(); + storage_partition_impl->GetOriginPolicyManagerForBrowserProcess(); origin_policy_manager->AddExceptionFor(url::Origin::Create(url)); }
diff --git a/content/browser/renderer_host/origin_policy_throttle.h b/content/browser/renderer_host/origin_policy_throttle.h index eb0cdd66..562afd3b 100644 --- a/content/browser/renderer_host/origin_policy_throttle.h +++ b/content/browser/renderer_host/origin_policy_throttle.h
@@ -8,7 +8,6 @@ #include <memory> #include "content/common/content_export.h" -#include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_throttle.h" #include "services/network/public/cpp/origin_policy.h" @@ -16,6 +15,7 @@ namespace content { class NavigationHandle; +class StoragePartition; // The OriginPolicyThrottle is responsible for deciding whether an origin // policy should be fetched, and doing so when that is positive. @@ -42,7 +42,8 @@ // otherwise invalid) policy. This is meant to be called by the security // interstitial. // This will exempt the entire origin, rather than only the given URL. - static void AddExceptionFor(BrowserContext* browser_context, const GURL& url); + static void AddExceptionFor(StoragePartition* storage_partition, + const GURL& url); OriginPolicyThrottle(const OriginPolicyThrottle&) = delete; OriginPolicyThrottle& operator=(const OriginPolicyThrottle&) = delete;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 91347ffe..bbd9798 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -6091,17 +6091,6 @@ delegate_->UnregisterProtocolHandler(source, protocol, url, user_gesture); } -void WebContentsImpl::OnAppCacheAccessed(const GURL& manifest_url, - bool blocked_by_policy) { - OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnAppCacheAccessed"); - // TODO(nick): Should we consider |source| here? Should we call FilterURL on - // |manifest_url|? - - // Notify observers about navigation. - observers_.NotifyObservers(&WebContentsObserver::AppCacheAccessed, - manifest_url, blocked_by_policy); -} - void WebContentsImpl::DomOperationResponse(const std::string& json_string) { OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DomOperationResponse", "json_string", json_string);
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 7fb0c54..25a4066 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -1226,10 +1226,6 @@ void DidActivatePortal(WebContentsImpl* predecessor_web_contents, base::TimeTicks activation_time); - // Notifies observers that AppCache was accessed. Public so AppCache code can - // call this directly. - void OnAppCacheAccessed(const GURL& manifest_url, bool blocked_by_policy); - void OnServiceWorkerAccessed(RenderFrameHost* render_frame_host, const GURL& scope, AllowServiceWorkerResult allowed);
diff --git a/content/public/browser/origin_policy_commands.h b/content/public/browser/origin_policy_commands.h index 7533193..b77cdf1 100644 --- a/content/public/browser/origin_policy_commands.h +++ b/content/public/browser/origin_policy_commands.h
@@ -11,14 +11,15 @@ namespace content { -class BrowserContext; +class StoragePartition; // Instruct the Origin Policy throttle to disregard errors for the given URL. // // Intended use: This should be called by the browser when the user selects // "proceed" on the security interstitial page for the given URL. -CONTENT_EXPORT void OriginPolicyAddExceptionFor(BrowserContext* browser_context, - const GURL& url); +CONTENT_EXPORT void OriginPolicyAddExceptionFor( + StoragePartition* storage_partition, + const GURL& url); } // namespace content
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h index f2cc589..1447272 100644 --- a/content/public/browser/web_contents_observer.h +++ b/content/public/browser/web_contents_observer.h
@@ -514,9 +514,6 @@ // NavigationEntry assigned to it. virtual void TitleWasSet(NavigationEntry* entry) {} - virtual void AppCacheAccessed(const GURL& manifest_url, - bool blocked_by_policy) {} - // These methods are invoked when a Pepper plugin instance is created/deleted // in the DOM. virtual void PepperInstanceCreated() {}
diff --git a/content/public/test/mock_web_contents_observer.h b/content/public/test/mock_web_contents_observer.h index 7e8bc6ed..53f17ed 100644 --- a/content/public/test/mock_web_contents_observer.h +++ b/content/public/test/mock_web_contents_observer.h
@@ -194,11 +194,7 @@ (RenderFrameHost* render_frame_host, const gfx::Size& frame_size), (override)); - MOCK_METHOD(void, TitleWasSet, (NavigationEntry* entry), (override)); - MOCK_METHOD(void, - AppCacheAccessed, - (const GURL& manifest_url, bool blocked_by_policy), - (override)); + MOCK_METHOD(void, TitleWasSet, (NavigationEntry * entry), (override)); MOCK_METHOD(void, PepperInstanceCreated, (), (override)); MOCK_METHOD(void, PepperInstanceDeleted, (), (override)); MOCK_METHOD(void,
diff --git a/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt index 17aff586..3f6cec8 100644 --- a/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt
@@ -113,7 +113,6 @@ # Flakily hits a DCHECK during shared image creation. crbug.com/1188437 [ linux intel display-server-wayland ] GpuProcess_webgl [ RetryOnFailure ] -crbug.com/1253917 [ linux intel display-server-wayland ] GpuProcess_disable_gpu [ RetryOnFailure ] # Flakey/slow tests using clang_rt. crbug.com/1261260 [ android android-nexus-5x ] GpuProcess_webgpu_iframe_removed [ Failure ]
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index ee34c1c0..20b4ce4 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1662,6 +1662,7 @@ WEB_AUTHENTICATION_PROXY_DETACH = 1599, FILEMANAGERPRIVATE_CANCELIOTASK = 1600, AUTOTESTPRIVATE_GETDISPLAYSMOOTHNESS = 1601, + AUTOTESTPRIVATE_RESETHOLDINGSPACE = 1602, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn index 3efbc39..0923a779 100644 --- a/extensions/common/BUILD.gn +++ b/extensions/common/BUILD.gn
@@ -635,4 +635,12 @@ "//base", ] } + + fuzzer_test("extension_csp_validator_fuzzer") { + sources = [ "csp_validator_fuzzer.cc" ] + deps = [ + ":common", + "//base", + ] + } } # enable_extensions
diff --git a/extensions/common/csp_validator_fuzzer.cc b/extensions/common/csp_validator_fuzzer.cc new file mode 100644 index 0000000..87907c9f --- /dev/null +++ b/extensions/common/csp_validator_fuzzer.cc
@@ -0,0 +1,42 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stddef.h> +#include <stdint.h> + +#include <string> +#include <vector> + +#include <fuzzer/FuzzedDataProvider.h> + +#include "extensions/common/csp_validator.h" +#include "extensions/common/install_warning.h" + +namespace extensions { + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + FuzzedDataProvider fuzzed_data_provider(data, size); + + const std::string content_security_policy = + fuzzed_data_provider.ConsumeRandomLengthString(); + const std::string manifest_key = + fuzzed_data_provider.ConsumeRandomLengthString(); + + std::vector<InstallWarning> install_warnings; + csp_validator::SanitizeContentSecurityPolicy( + content_security_policy, manifest_key, + /*options=*/fuzzed_data_provider.ConsumeIntegralInRange(0, 4), + &install_warnings); + + csp_validator::GetEffectiveSandoxedPageCSP(content_security_policy, + manifest_key, &install_warnings); + + std::u16string error; + csp_validator::DoesCSPDisallowRemoteCode(content_security_policy, + manifest_key, &error); + + return 0; +} + +} // namespace extensions
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm index a2051507..6bd6dd70 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -775,7 +775,8 @@ // Test to ensure that feed can be enabled/disabled and that feed header changes // accordingly. -- (void)testToggleFeedEnabled { +// TODO(crbug.com/1194106): Flaky on ios-simulator-noncq. +- (void)DISABLED_testToggleFeedEnabled { [self testNTPInitialPositionAndContent:[NewTabPageAppInterface collectionView]];
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index 5d75a81..1269b467 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -5da94496a6036476405ee112b4f21a3a8d4555d3 \ No newline at end of file +e8dac9ffd91084624d559f5fe177d4b06f23eee9 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index 204655d..87fde24 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -c0e7d6582b005f1c730439bf070359f66542ab31 \ No newline at end of file +d1b07f28175e9585551bc569ad4dadd70041ec43 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index 398a177..b0691b9 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -66566dbfa7fe4bf2f10e70ef43cdf953a7b21b39 \ No newline at end of file +6e4b73a34437bd9358edf6b0185d8f6f10a1632d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index f65c43f..3e2f5ff 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -3abdaac67d0fce6b572a1ee15ee5cfbea9f5b219 \ No newline at end of file +9d298ae0267f8a533f975c27c31f5b9a7fb7a7a8 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 index dbd40612..bb3c2177 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -07d6c0312262f7e652325da872cf56afd2fdacfc \ No newline at end of file +d0f13a96ae528b85783e001b82be8b27f3bbd107 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 index c4ebc88..f4b00f5 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -da303077ec667dcf8d9b7bd4e593385a2a8ea598 \ No newline at end of file +e957391a82885c99d392eadf4e0859c982e280c8 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index 2d80f60..c9e4a70 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -a84f6df2e29c716e8dde6065e28c9fdd34ddbecb \ No newline at end of file +60f355cfd35b1af0bf7c1a73224c2b144e1c800b \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 4a274940..63ff913e 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -bb3157a65d7dc145c7a663bfd10139eeafe68288 \ No newline at end of file +82bd1bde09f630d8f379811fa0eaa81e69b116f1 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index a29a1b0..1a669bb4 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -b719b20698427db4a2350b0ccf208a5657879101 \ No newline at end of file +826d8e147c7b1bfce295b132eaa8763221738e89 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index aa3109c..e4e04c7 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -07eea62c1cdc6f8f568862fdf976ac632cbb8c94 \ No newline at end of file +bac6df57a087e2692a151f1255b26387ced22a34 \ No newline at end of file
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc index 37cc281..427b54b 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -431,31 +431,35 @@ EncodePendingInputs(); } -void VaapiVideoEncodeAccelerator::TryToReturnBitstreamBuffer() { +void VaapiVideoEncodeAccelerator::TryToReturnBitstreamBuffers() { DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_sequence_checker_); if (state_ != kEncoding) return; - while (!pending_encode_results_.empty() && - pending_encode_results_.front() == nullptr) { - // A null job indicates a flush command. + TRACE_EVENT1("media,gpu", "VAVEA::TryToReturnBitstreamBuffers", + "pending encode results", pending_encode_results_.size()); + while (!pending_encode_results_.empty()) { + if (pending_encode_results_.front() == nullptr) { + // A null job indicates a flush command. + pending_encode_results_.pop(); + DVLOGF(2) << "FlushDone"; + DCHECK(flush_callback_); + child_task_runner_->PostTask( + FROM_HERE, base::BindOnce(std::move(flush_callback_), true)); + continue; + } + + if (available_bitstream_buffers_.empty()) + return; + + auto buffer = std::move(available_bitstream_buffers_.front()); + available_bitstream_buffers_.pop(); + auto encode_result = std::move(pending_encode_results_.front()); pending_encode_results_.pop(); - DVLOGF(2) << "FlushDone"; - DCHECK(flush_callback_); - child_task_runner_->PostTask( - FROM_HERE, base::BindOnce(std::move(flush_callback_), true)); + + ReturnBitstreamBuffer(std::move(encode_result), std::move(buffer)); } - - if (pending_encode_results_.empty() || available_bitstream_buffers_.empty()) - return; - - auto buffer = std::move(available_bitstream_buffers_.front()); - available_bitstream_buffers_.pop(); - auto encode_result = std::move(pending_encode_results_.front()); - pending_encode_results_.pop(); - - ReturnBitstreamBuffer(std::move(encode_result), std::move(buffer)); } void VaapiVideoEncodeAccelerator::ReturnBitstreamBuffer( @@ -568,7 +572,7 @@ } // Create input and reconstructed surfaces. - TRACE_EVENT1("media,gpu", "VAVEA::ConstructSurfaces", "the number of layers", + TRACE_EVENT1("media,gpu", "VAVEA::ConstructSurfaces", "layers", spatial_layer_resolutions.size()); input_surfaces->reserve(spatial_layer_resolutions.size()); reconstructed_surfaces->reserve(spatial_layer_resolutions.size()); @@ -823,10 +827,12 @@ // |pending_encode_results_| queue. pending_encode_results_.push(nullptr); input_queue_.pop(); - TryToReturnBitstreamBuffer(); + TryToReturnBitstreamBuffers(); continue; } + TRACE_EVENT0("media,gpu", + "VAVEA::EncodeOneInputFrameAndReturnEncodedChunks"); const size_t num_spatial_layers = spatial_layer_resolutions.size(); std::vector<scoped_refptr<VASurface>> input_surfaces; std::vector<scoped_refptr<VASurface>> reconstructed_surfaces; @@ -865,7 +871,7 @@ } for (auto&& job : jobs) { - TRACE_EVENT0("media,gpu", "VAVEA::FromEncodeToReturn"); + TRACE_EVENT0("media,gpu", "VAVEA::Encode"); std::unique_ptr<EncodeResult> result = encoder_->Encode(std::move(job)); if (!result) { NOTIFY_ERROR(kPlatformFailureError, "Failed encoding job"); @@ -873,9 +879,9 @@ } pending_encode_results_.push(std::move(result)); - TryToReturnBitstreamBuffer(); } + TryToReturnBitstreamBuffers(); input_queue_.pop(); } } @@ -910,7 +916,7 @@ } available_bitstream_buffers_.push(std::move(buffer_ref)); - TryToReturnBitstreamBuffer(); + TryToReturnBitstreamBuffers(); } void VaapiVideoEncodeAccelerator::RequestEncodingParametersChange(
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.h b/media/gpu/vaapi/vaapi_video_encode_accelerator.h index b7e1d90..8d77648 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator.h +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.h
@@ -186,10 +186,10 @@ scoped_refptr<VASurface> GetAvailableVASurfaceAsRefCounted( std::vector<std::unique_ptr<ScopedVASurface>>* va_surfaces); - // Returns a bitstream buffer to the client if we have both pending the + // Returns pending bitstream buffers to the client if we have both pending // encoded data to be completed and bitstream buffers available to download // the encoded data into. - void TryToReturnBitstreamBuffer(); + void TryToReturnBitstreamBuffers(); // Downloads encoded data produced as a result of running |encode_result| into // |buffer|, and returns it to the client.
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc index 16c23dd..132e27d6 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc
@@ -608,6 +608,7 @@ .WillOnce(Return(kEncodedChunkSize)); EXPECT_CALL(*mock_encoder_, BitrateControlUpdate(kEncodedChunkSize)) .WillOnce(Return()); + EXPECT_CALL(*mock_encoder_, GetMetadata(_, _)) .WillOnce( WithArgs<0, 1>([](const VaapiVideoEncoderDelegate::EncodeJob& job, @@ -620,6 +621,11 @@ ->metadata_for_encoding; return metadata; })); + } + + for (size_t i = 0; i < num_spatial_layers; ++i) { + const VABufferID kCodedBufferId = kCodedBufferIds[i]; + const uint64_t kEncodedChunkSize = kEncodedChunkSizes[i]; EXPECT_CALL( *mock_vaapi_wrapper_, DownloadFromVABuffer(kCodedBufferId, _, _, output_buffer_size_, _))
diff --git a/services/audio/sync_reader.cc b/services/audio/sync_reader.cc index 9a990353..acc5a8a 100644 --- a/services/audio/sync_reader.cc +++ b/services/audio/sync_reader.cc
@@ -12,7 +12,7 @@ #include "base/command_line.h" #include "base/format_macros.h" #include "base/logging.h" -#include "base/metrics/histogram_macros.h" +#include "base/metrics/histogram_functions.h" #include "base/numerics/safe_conversions.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" @@ -22,19 +22,68 @@ #include "media/base/audio_parameters.h" #include "media/base/media_switches.h" +using media::AudioLatency; + namespace { // Used to log if any audio glitches have been detected during an audio session. // Elements in this enum should not be added, deleted or rearranged. -enum AudioGlitchResult { - AUDIO_RENDERER_NO_AUDIO_GLITCHES = 0, - AUDIO_RENDERER_AUDIO_GLITCHES = 1, - AUDIO_RENDERER_AUDIO_GLITCHES_MAX = AUDIO_RENDERER_AUDIO_GLITCHES +enum class AudioGlitchResult { + kNoGlitches = 0, + kGlitches = 1, + kMaxValue = kGlitches }; -void LogAudioGlitchResult(AudioGlitchResult result) { - UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererAudioGlitches", result, - AUDIO_RENDERER_AUDIO_GLITCHES_MAX + 1); +void LogPerLatencyGlitchUma(AudioLatency::LatencyType latency, + int renderer_missed_callback_count, + int renderer_callback_count) { + DCHECK_LE(renderer_missed_callback_count, renderer_callback_count); + + auto LatencyToString = [](AudioLatency::LatencyType latency) { + switch (latency) { + case AudioLatency::LATENCY_EXACT_MS: + return "LatencyExactMs"; + case AudioLatency::LATENCY_INTERACTIVE: + return "LatencyInteractive"; + case AudioLatency::LATENCY_RTC: + return "LatencyRtc"; + case AudioLatency::LATENCY_PLAYBACK: + return "LatencyPlayback"; + default: + return "LatencyUnknown"; + } + }; + + const std::string suffix = LatencyToString(latency); + + base::UmaHistogramEnumeration("Media.AudioRendererAudioGlitches2." + suffix, + (renderer_missed_callback_count > 0) + ? AudioGlitchResult::kGlitches + : AudioGlitchResult::kNoGlitches); + + const int kPermilleScaling = 1000; + // 10%: if we have more that 10% of callbacks having issues, the details are + // not very interesting any more, so we just log all those cases together to + // have a better resolution for lower values. + const int kHistogramRange = kPermilleScaling / 10; + + // 30 s for 10 ms buffers (RTC streams)/ 1 minute for 20 ms buffers (media + // playback). + const int kShortStreamMaxCallbackCount = 3000; + + if (renderer_callback_count <= 0) + return; + + int missed_permille = std::ceil( + kPermilleScaling * static_cast<double>(renderer_missed_callback_count) / + renderer_callback_count); + + base::UmaHistogramCustomCounts( + ((renderer_callback_count < kShortStreamMaxCallbackCount) + ? "Media.AudioRendererMissedDeadline2.Short." + : "Media.AudioRendererMissedDeadline2.Long.") + + suffix, + std::min(missed_permille, kHistogramRange), 0, kHistogramRange + 1, 100); } } // namespace @@ -55,6 +104,7 @@ const media::AudioParameters& params, base::CancelableSyncSocket* foreign_socket) : log_callback_(std::move(log_callback)), + latency_tag_(params.latency_tag()), mute_audio_for_testing_(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kMuteAudio)), had_socket_error_(false), @@ -114,22 +164,22 @@ if (!renderer_callback_count_) return; - // Recording the percentage of deadline misses gives us a rough overview of - // how many users might be running into audio glitches. + base::UmaHistogramEnumeration("Media.AudioRendererAudioGlitches", + (renderer_missed_callback_count_ > 0) + ? AudioGlitchResult::kGlitches + : AudioGlitchResult::kNoGlitches); int percentage_missed = 100.0 * renderer_missed_callback_count_ / renderer_callback_count_; - UMA_HISTOGRAM_PERCENTAGE("Media.AudioRendererMissedDeadline", - percentage_missed); + + base::UmaHistogramPercentage("Media.AudioRendererMissedDeadline", + percentage_missed); + + LogPerLatencyGlitchUma(latency_tag_, renderer_missed_callback_count_, + renderer_callback_count_); TRACE_EVENT_INSTANT1("audio", "~SyncReader", TRACE_EVENT_SCOPE_THREAD, "Missed callback percentage", percentage_missed); - // Add more detailed information regarding detected audio glitches where - // a non-zero value of |renderer_missed_callback_count_| is added to the - // AUDIO_RENDERER_AUDIO_GLITCHES bin. - renderer_missed_callback_count_ > 0 - ? LogAudioGlitchResult(AUDIO_RENDERER_AUDIO_GLITCHES) - : LogAudioGlitchResult(AUDIO_RENDERER_NO_AUDIO_GLITCHES); log_callback_.Run(base::StringPrintf( "ASR: number of detected audio glitches: %" PRIuS " out of %" PRIuS, renderer_missed_callback_count_, renderer_callback_count_)); @@ -291,9 +341,9 @@ TRACE_EVENT_SCOPE_THREAD); base::TimeDelta time_since_start = base::TimeTicks::Now() - start_time; - UMA_HISTOGRAM_CUSTOM_TIMES("Media.AudioOutputControllerDataNotReady", - time_since_start, base::Milliseconds(1), - base::Milliseconds(1000), 50); + base::UmaHistogramCustomTimes("Media.AudioOutputControllerDataNotReady", + time_since_start, base::Milliseconds(1), + base::Milliseconds(1000), 50); return false; }
diff --git a/services/audio/sync_reader.h b/services/audio/sync_reader.h index 6f5c64d6..626c28ad 100644 --- a/services/audio/sync_reader.h +++ b/services/audio/sync_reader.h
@@ -18,6 +18,7 @@ #include "base/time/time.h" #include "build/build_config.h" #include "media/base/audio_bus.h" +#include "media/base/audio_latency.h" #include "services/audio/output_controller.h" #if defined(OS_POSIX) @@ -73,6 +74,8 @@ base::UnsafeSharedMemoryRegion shared_memory_region_; base::WritableSharedMemoryMapping shared_memory_mapping_; + const media::AudioLatency::LatencyType latency_tag_; + // Mutes all incoming samples. This is used to prevent audible sound // during automated testing. const bool mute_audio_for_testing_;
diff --git a/services/network/websocket.cc b/services/network/websocket.cc index 36abc985..7c6b9358 100644 --- a/services/network/websocket.cc +++ b/services/network/websocket.cc
@@ -273,6 +273,10 @@ if (payload.size() > 0) { impl_->pending_data_frames_.push(payload); } + if (impl_->incoming_frame_interceptor_ && + impl_->incoming_frame_interceptor_->IsFrameStarted()) { + return; + } impl_->SendPendingDataFrames(); } @@ -511,8 +515,11 @@ // Safe if ReadAndSendFromDataPipe() deletes |this| because this method is // only called from mojo. - if (!blocked_on_websocket_channel_) + if (!blocked_on_websocket_channel_ && + (!outgoing_frame_interceptor_ || + !outgoing_frame_interceptor_->IsFrameStarted())) { ReadAndSendFromDataPipe(); + } } void WebSocket::StartReceiving() { @@ -733,7 +740,10 @@ // Safe if ReadAndSendFromDataPipe() deletes |this| because this method is // only called from mojo. - ReadAndSendFromDataPipe(); + if (!outgoing_frame_interceptor_ || + !outgoing_frame_interceptor_->IsFrameStarted()) { + ReadAndSendFromDataPipe(); + } } void WebSocket::ReadAndSendFromDataPipe() {
diff --git a/services/network/websocket_interceptor.cc b/services/network/websocket_interceptor.cc index 8c34ef6d..3eb2ee4d 100644 --- a/services/network/websocket_interceptor.cc +++ b/services/network/websocket_interceptor.cc
@@ -44,13 +44,13 @@ if (!throttling_interceptor) return kContinue; - frame_started_ = true; throttling_interceptor->SetSuspendWhenOffline(true); int start_throttle_result = throttling_interceptor->StartThrottle( /*result=*/0, size, /*send_end=*/base::TimeTicks(), /*start=*/false, /*is_upload=*/direction_ == kOutgoing, throttle_callback_); if (start_throttle_result == net::ERR_IO_PENDING) { pending_callback_ = std::move(retry_callback); + frame_started_ = true; return kShouldWait; } return kContinue;
diff --git a/services/tracing/public/cpp/perfetto/trace_string_lookup.cc b/services/tracing/public/cpp/perfetto/trace_string_lookup.cc index 70d92a86..5a86991 100644 --- a/services/tracing/public/cpp/perfetto/trace_string_lookup.cc +++ b/services/tracing/public/cpp/perfetto/trace_string_lookup.cc
@@ -148,6 +148,7 @@ {"NetworkConfigWatcher", ChromeThreadDescriptor::THREAD_NETWORKCONFIGWATCHER}, {"wasapi_render_thread", ChromeThreadDescriptor::THREAD_WASAPI_RENDER}, + {"LoaderLockSampler", ChromeThreadDescriptor::THREAD_LOADER_LOCK_SAMPLER}, }; ChromeProcessDescriptor::ProcessType GetProcessType(const std::string& name) {
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc index 9f52786..84db81d 100644 --- a/storage/browser/quota/quota_database.cc +++ b/storage/browser/quota/quota_database.cc
@@ -129,13 +129,12 @@ } } -bool QuotaDatabase::GetHostQuota(const std::string& host, - StorageType type, - int64_t* quota) { +QuotaErrorOr<int64_t> QuotaDatabase::GetHostQuota(const std::string& host, + StorageType type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(quota); - if (EnsureOpened(EnsureOpenedMode::kFailIfNotFound) != QuotaError::kNone) - return false; + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound); + if (open_error != QuotaError::kNone) + return open_error; static constexpr char kSql[] = "SELECT quota FROM quota WHERE host = ? AND type = ?"; @@ -143,27 +142,36 @@ statement.BindString(0, host); statement.BindInt(1, static_cast<int>(type)); - if (!statement.Step()) - return false; - - *quota = statement.ColumnInt64(0); - return true; + if (!statement.Step()) { + return statement.Succeeded() ? QuotaError::kNotFound + : QuotaError::kDatabaseError; + } + return statement.ColumnInt64(0); } -bool QuotaDatabase::SetHostQuota(const std::string& host, - StorageType type, - int64_t quota) { +QuotaError QuotaDatabase::SetHostQuota(const std::string& host, + StorageType type, + int64_t quota) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_GE(quota, 0); - if (EnsureOpened(EnsureOpenedMode::kCreateIfNotFound) != QuotaError::kNone) - return false; + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kCreateIfNotFound); + if (open_error != QuotaError::kNone) + return open_error; if (quota == 0) return DeleteHostQuota(host, type); - if (!InsertOrReplaceHostQuota(host, type, quota)) - return false; + + static constexpr char kSql[] = + "INSERT OR REPLACE INTO quota(quota, host, type) VALUES (?, ?, ?)"; + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindInt64(0, quota); + statement.BindString(1, host); + statement.BindInt(2, static_cast<int>(type)); + if (!statement.Run()) + return QuotaError::kDatabaseError; + ScheduleCommit(); - return true; + return QuotaError::kNone; } QuotaErrorOr<BucketInfo> QuotaDatabase::GetOrCreateBucket( @@ -519,11 +527,12 @@ return true; } -bool QuotaDatabase::DeleteHostQuota( - const std::string& host, StorageType type) { +QuotaError QuotaDatabase::DeleteHostQuota(const std::string& host, + StorageType type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (EnsureOpened(EnsureOpenedMode::kFailIfNotFound) != QuotaError::kNone) - return false; + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound); + if (open_error != QuotaError::kNone) + return open_error; static constexpr char kSql[] = "DELETE FROM quota WHERE host = ? AND type = ?"; @@ -532,10 +541,10 @@ statement.BindInt(1, static_cast<int>(type)); if (!statement.Run()) - return false; + return QuotaError::kDatabaseError; ScheduleCommit(); - return true; + return QuotaError::kNone; } bool QuotaDatabase::DeleteStorageKeyInfo(const StorageKey& storage_key, @@ -892,23 +901,6 @@ return EnsureOpened(EnsureOpenedMode::kCreateIfNotFound) == QuotaError::kNone; } -bool QuotaDatabase::InsertOrReplaceHostQuota(const std::string& host, - StorageType type, - int64_t quota) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(db_.get()); - static constexpr char kSql[] = - // clang-format off - "INSERT OR REPLACE INTO quota(quota, host, type)" - "VALUES (?, ?, ?)"; - // clang-format on - sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindInt64(0, quota); - statement.BindString(1, host); - statement.BindInt(2, static_cast<int>(type)); - return statement.Run(); -} - QuotaError QuotaDatabase::DumpQuotaTable(const QuotaTableCallback& callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); QuotaError open_error = EnsureOpened(EnsureOpenedMode::kCreateIfNotFound);
diff --git a/storage/browser/quota/quota_database.h b/storage/browser/quota/quota_database.h index d54cb27..0c90bf4 100644 --- a/storage/browser/quota/quota_database.h +++ b/storage/browser/quota/quota_database.h
@@ -90,16 +90,17 @@ ~QuotaDatabase(); - // Returns whether the record could be found. - bool GetHostQuota(const std::string& host, - blink::mojom::StorageType type, - int64_t* quota); + // Returns quota if entry is found. Returns QuotaError::kNotFound no entry if + // found. + QuotaErrorOr<int64_t> GetHostQuota(const std::string& host, + blink::mojom::StorageType type); // Returns whether the operation succeeded. - bool SetHostQuota(const std::string& host, - blink::mojom::StorageType type, - int64_t quota); - bool DeleteHostQuota(const std::string& host, blink::mojom::StorageType type); + QuotaError SetHostQuota(const std::string& host, + blink::mojom::StorageType type, + int64_t quota); + QuotaError DeleteHostQuota(const std::string& host, + blink::mojom::StorageType type); // Gets the bucket with `bucket_name` for the `storage_key` for StorageType // kTemporary and returns the BucketInfo. If one doesn't exist, it creates @@ -262,9 +263,6 @@ bool EnsureDatabaseVersion(); bool ResetSchema(); bool UpgradeSchema(int current_version); - bool InsertOrReplaceHostQuota(const std::string& host, - blink::mojom::StorageType type, - int64_t quota); bool CreateSchema(); bool CreateTable(const TableSchema& table);
diff --git a/storage/browser/quota/quota_database_unittest.cc b/storage/browser/quota/quota_database_unittest.cc index 7fefcdf..7aa9ba16 100644 --- a/storage/browser/quota/quota_database_unittest.cc +++ b/storage/browser/quota/quota_database_unittest.cc
@@ -185,30 +185,41 @@ const int kQuota1 = 13579; const int kQuota2 = kQuota1 + 1024; - int64_t quota = -1; - EXPECT_FALSE(db.GetHostQuota(kHost, kTemp, "a)); - EXPECT_FALSE(db.GetHostQuota(kHost, kPerm, "a)); + QuotaErrorOr<int64_t> result = db.GetHostQuota(kHost, kTemp); + EXPECT_FALSE(result.ok()); + EXPECT_EQ(result.error(), QuotaError::kNotFound); + result = db.GetHostQuota(kHost, kPerm); + EXPECT_FALSE(result.ok()); + EXPECT_EQ(result.error(), QuotaError::kNotFound); // Insert quota for temporary. - EXPECT_TRUE(db.SetHostQuota(kHost, kTemp, kQuota1)); - EXPECT_TRUE(db.GetHostQuota(kHost, kTemp, "a)); - EXPECT_EQ(kQuota1, quota); + EXPECT_EQ(db.SetHostQuota(kHost, kTemp, kQuota1), QuotaError::kNone); + result = db.GetHostQuota(kHost, kTemp); + EXPECT_TRUE(result.ok()); + EXPECT_EQ(kQuota1, result.value()); // Update quota for temporary. - EXPECT_TRUE(db.SetHostQuota(kHost, kTemp, kQuota2)); - EXPECT_TRUE(db.GetHostQuota(kHost, kTemp, "a)); - EXPECT_EQ(kQuota2, quota); + EXPECT_EQ(db.SetHostQuota(kHost, kTemp, kQuota2), QuotaError::kNone); + result = db.GetHostQuota(kHost, kTemp); + EXPECT_TRUE(result.ok()); + EXPECT_EQ(kQuota2, result.value()); // Quota for persistent must not be updated. - EXPECT_FALSE(db.GetHostQuota(kHost, kPerm, "a)); + result = db.GetHostQuota(kHost, kPerm); + EXPECT_FALSE(result.ok()); + EXPECT_EQ(result.error(), QuotaError::kNotFound); // Delete temporary storage quota. - EXPECT_TRUE(db.DeleteHostQuota(kHost, kTemp)); - EXPECT_FALSE(db.GetHostQuota(kHost, kTemp, "a)); + EXPECT_EQ(db.DeleteHostQuota(kHost, kTemp), QuotaError::kNone); + result = db.GetHostQuota(kHost, kTemp); + EXPECT_FALSE(result.ok()); + EXPECT_EQ(result.error(), QuotaError::kNotFound); // Delete persistent quota by setting it to zero. - EXPECT_TRUE(db.SetHostQuota(kHost, kPerm, 0)); - EXPECT_FALSE(db.GetHostQuota(kHost, kPerm, "a)); + EXPECT_EQ(db.SetHostQuota(kHost, kPerm, 0), QuotaError::kNone); + result = db.GetHostQuota(kHost, kPerm); + EXPECT_FALSE(result.ok()); + EXPECT_EQ(result.error(), QuotaError::kNotFound); } TEST_P(QuotaDatabaseTest, GetOrCreateBucket) {
diff --git a/storage/browser/quota/quota_manager_impl.cc b/storage/browser/quota/quota_manager_impl.cc index 95e0559..42338ce 100644 --- a/storage/browser/quota/quota_manager_impl.cc +++ b/storage/browser/quota/quota_manager_impl.cc
@@ -159,22 +159,18 @@ return database->GetBucketsModifiedBetween(type, begin, end); } -bool GetPersistentHostQuotaOnDBThread(const std::string& host, - int64_t* quota, - QuotaDatabase* database) { +QuotaErrorOr<int64_t> GetPersistentHostQuotaOnDBThread( + const std::string& host, + QuotaDatabase* database) { DCHECK(database); - database->GetHostQuota(host, StorageType::kPersistent, quota); - return true; + return database->GetHostQuota(host, StorageType::kPersistent); } -bool SetPersistentHostQuotaOnDBThread(const std::string& host, - int64_t* new_quota, - QuotaDatabase* database) { +QuotaError SetPersistentHostQuotaOnDBThread(const std::string& host, + int64_t* new_quota, + QuotaDatabase* database) { DCHECK(database); - if (database->SetHostQuota(host, StorageType::kPersistent, *new_quota)) - return true; - *new_quota = 0; - return false; + return database->SetHostQuota(host, StorageType::kPersistent, *new_quota); } QuotaErrorOr<BucketLocator> GetLRUBucketOnDBThread( @@ -1381,13 +1377,10 @@ if (!persistent_host_quota_callbacks_.Add(host, std::move(callback))) return; - int64_t* quota_ptr = new int64_t(0); PostTaskAndReplyWithResultForDBThread( - FROM_HERE, - base::BindOnce(&GetPersistentHostQuotaOnDBThread, host, - base::Unretained(quota_ptr)), + base::BindOnce(&GetPersistentHostQuotaOnDBThread, host), base::BindOnce(&QuotaManagerImpl::DidGetPersistentHostQuota, - weak_factory_.GetWeakPtr(), host, base::Owned(quota_ptr))); + weak_factory_.GetWeakPtr(), host)); } void QuotaManagerImpl::SetPersistentHostQuota(const std::string& host, @@ -1419,7 +1412,6 @@ int64_t* new_quota_ptr = new int64_t(new_quota); PostTaskAndReplyWithResultForDBThread( - FROM_HERE, base::BindOnce(&SetPersistentHostQuotaOnDBThread, host, base::Unretained(new_quota_ptr)), base::BindOnce(&QuotaManagerImpl::DidSetPersistentHostQuota, @@ -2114,25 +2106,33 @@ } void QuotaManagerImpl::DidGetPersistentHostQuota(const std::string& host, - const int64_t* quota, - bool success) { + QuotaErrorOr<int64_t> result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DidDatabaseWork(success); + DidDatabaseWork(result.ok() || result.error() != QuotaError::kDatabaseError); + + if (!result.ok() && result.error() != QuotaError::kNotFound) { + persistent_host_quota_callbacks_.Run( + host, blink::mojom::QuotaStatusCode::kErrorInvalidAccess, /*quota=*/0); + return; + } persistent_host_quota_callbacks_.Run( host, blink::mojom::QuotaStatusCode::kOk, - std::min(*quota, kPerHostPersistentQuotaLimit)); + std::min(result.ok() ? result.value() : 0, kPerHostPersistentQuotaLimit)); } void QuotaManagerImpl::DidSetPersistentHostQuota(const std::string& host, QuotaCallback callback, const int64_t* new_quota, - bool success) { + QuotaError error) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DidDatabaseWork(success); - std::move(callback).Run( - success ? blink::mojom::QuotaStatusCode::kOk - : blink::mojom::QuotaStatusCode::kErrorInvalidAccess, - *new_quota); + DidDatabaseWork(error != QuotaError::kDatabaseError); + + if (error == QuotaError::kNone) { + std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk, *new_quota); + return; + } + std::move(callback).Run(blink::mojom::QuotaStatusCode::kErrorInvalidAccess, + /*new_quota=*/0); } void QuotaManagerImpl::DidGetLRUBucket(QuotaErrorOr<BucketLocator> result) {
diff --git a/storage/browser/quota/quota_manager_impl.h b/storage/browser/quota/quota_manager_impl.h index 266d392..3f3ecde2 100644 --- a/storage/browser/quota/quota_manager_impl.h +++ b/storage/browser/quota/quota_manager_impl.h
@@ -546,12 +546,11 @@ void GetLRUBucket(blink::mojom::StorageType type, GetBucketCallback callback); void DidGetPersistentHostQuota(const std::string& host, - const int64_t* quota, - bool success); + QuotaErrorOr<int64_t> result); void DidSetPersistentHostQuota(const std::string& host, QuotaCallback callback, const int64_t* new_quota, - bool success); + QuotaError error); void DidGetLRUBucket(QuotaErrorOr<BucketLocator> result); void GetQuotaSettings(QuotaSettingsCallback callback); void DidGetSettings(absl::optional<QuotaSettings> settings);
diff --git a/testing/scripts/run_performance_tests.py b/testing/scripts/run_performance_tests.py index 00a51f9..b687be8 100755 --- a/testing/scripts/run_performance_tests.py +++ b/testing/scripts/run_performance_tests.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env vpython3 # Copyright 2017 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/testing/test_env.py b/testing/test_env.py index 95f5741..8a65b1b 100755 --- a/testing/test_env.py +++ b/testing/test_env.py
@@ -204,12 +204,12 @@ stderr=subprocess.STDOUT) forward_signals([process]) while process.poll() is None: - sys.stdout.write(reader.read()) + sys.stdout.write(reader.read().decode('utf-8')) # This sleep is needed for signal propagation. See the # wait_with_signals() docstring. time.sleep(0.1) # Read the remaining. - sys.stdout.write(reader.read()) + sys.stdout.write(reader.read().decode('utf-8')) print('Command %r returned exit code %d' % (argv, process.returncode)) return process.returncode
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index a28d517..d298808b 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1762,24 +1762,6 @@ ] } ], - "ButterForPaymentsIOS": [ - { - "platforms": [ - "ios" - ], - "experiments": [ - { - "name": "Enabled_Butter_IndicationForAllUsers", - "enable_features": [ - "AutofillEnableAccountWalletStorage", - "AutofillEnableInfoBarAccountIndicationFooterForSingleAccountUsers", - "AutofillEnableInfoBarAccountIndicationFooterForSyncUsers", - "AutofillEnableSaveCardInfoBarAccountIndicationFooter" - ] - } - ] - } - ], "CPSS": [ { "platforms": [ @@ -6508,6 +6490,28 @@ ] } ], + "RTCDisallowPlanBOutsideDeprecationTrial": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RTCDisallowPlanBOutsideDeprecationTrial" + ] + } + ] + } + ], "RadioThrottleOnWeakSignalAndroid": [ { "platforms": [ @@ -9013,29 +9017,6 @@ ] } ], - "WebRTCDisallowPlanBOutsideDeprecationTrial": [ - { - "platforms": [ - "windows", - "mac", - "chromeos", - "chromeos_lacros", - "linux", - "ios", - "android", - "android_weblayer", - "android_webview" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "RTCDisallowPlanBOutsideDeprecationTrial" - ] - } - ] - } - ], "WebRtcDistinctWorkerThread": [ { "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 7c14f5e..12f353f 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -34,7 +34,7 @@ base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kCOLRV1Fonts{"COLRV1Fonts", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enable CSS Container Queries. Also implies LayoutNGGrid and CSSContainSize1D. const base::Feature kCSSContainerQueries{"CSSContainerQueries",
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index af319b2..f393dbbc 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -5117,6 +5117,11 @@ # An unspecified port value allows protocol clients to emulate legacy cookie scope for the port. # This is a temporary ability and it will be removed in the future. experimental integer sourcePort + # Cookie partition key. The site of the top-level URL the browser was visiting at the start + # of the request to the endpoint that set the cookie. + experimental optional string partitionKey + # True if cookie partition key is opaque. + experimental optional boolean partitionKeyOpaque # Types of reasons why a cookie may not be stored from a response. experimental type SetCookieBlockedReason extends string @@ -5275,6 +5280,10 @@ # An unspecified port value allows protocol clients to emulate legacy cookie scope for the port. # This is a temporary ability and it will be removed in the future. experimental optional integer sourcePort + # Cookie partition key. The site of the top-level URL the browser was visiting at the start + # of the request to the endpoint that set the cookie. + # If not set, the cookie will be set as not partitioned. + experimental optional string partitionKey # Authorization challenge for HTTP status code 401 or 407. experimental type AuthChallenge extends object @@ -5645,6 +5654,10 @@ # An unspecified port value allows protocol clients to emulate legacy cookie scope for the port. # This is a temporary ability and it will be removed in the future. experimental optional integer sourcePort + # Cookie partition key. The site of the top-level URL the browser was visiting at the start + # of the request to the endpoint that set the cookie. + # If not set, the cookie will be set as not partitioned. + experimental optional string partitionKey returns # Always set to true. If an error occurs, the response indicates protocol error. deprecated boolean success
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc index 4d9c9236..1baa74e 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
@@ -638,9 +638,15 @@ v8::MaybeLocal<v8::Value> V8ScriptRunner::CompileAndRunInternalScript( v8::Isolate* isolate, ScriptState* script_state, - const ScriptSourceCode& source_code) { + const ClassicScript& classic_script) { DCHECK_EQ(isolate, script_state->GetIsolate()); + const ScriptSourceCode& source_code = classic_script.GetScriptSourceCode(); + const ReferrerScriptInfo referrer_info(classic_script.BaseURL(), + classic_script.FetchOptions()); + v8::Local<v8::Data> host_defined_options = + referrer_info.ToV8HostDefinedOptions(isolate, source_code.Url()); + v8::ScriptCompiler::CompileOptions compile_options; V8CodeCache::ProduceCacheOptions produce_cache_options; v8::ScriptCompiler::NoCacheReason no_cache_reason; @@ -651,13 +657,9 @@ // produce cache for them. DCHECK_EQ(produce_cache_options, V8CodeCache::ProduceCacheOptions::kNoProduceCache); - v8::Local<v8::Data> host_defined_options; v8::Local<v8::Script> script; - // Use default ScriptReferrerInfo here: - // - nonce: empty for internal script, and - // - parser_state: always "not parser inserted" for internal scripts. if (!V8ScriptRunner::CompileScript( - script_state, source_code, SanitizeScriptErrors::kDoNotSanitize, + script_state, source_code, classic_script.GetSanitizeScriptErrors(), compile_options, no_cache_reason, host_defined_options) .ToLocal(&script)) return v8::MaybeLocal<v8::Value>();
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h index 64d830e..5438dc79 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h
@@ -127,10 +127,8 @@ ClassicScript*, ExecuteScriptPolicy, RethrowErrorsOption); - static v8::MaybeLocal<v8::Value> CompileAndRunInternalScript( - v8::Isolate*, - ScriptState*, - const ScriptSourceCode&); + static v8::MaybeLocal<v8::Value> + CompileAndRunInternalScript(v8::Isolate*, ScriptState*, const ClassicScript&); static v8::MaybeLocal<v8::Value> CallAsConstructor( v8::Isolate*, v8::Local<v8::Object>,
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/observable_array.py b/third_party/blink/renderer/bindings/scripts/bind_gen/observable_array.py index 1898c69..71ef0b7 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/observable_array.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/observable_array.py
@@ -209,9 +209,12 @@ bind_local_vars(body, cg_context) body.extend([ - T("static const void* kTemplateKey = &kTemplateKey;"), + T("// Make `template_key` unique for `FindV8Template`."), + T("static const char kTemplateKeyTag = 0;"), + T("const void* const template_key = &kTemplateKeyTag;"), + EmptyNode(), T("v8::Local<v8::Template> v8_template = " - "${per_isolate_data}->FindV8Template(${world}, kTemplateKey);"), + "${per_isolate_data}->FindV8Template(${world}, template_key);"), CxxLikelyIfNode( cond="!v8_template.IsEmpty()", body=T("return v8_template.As<v8::FunctionTemplate>();")), @@ -245,7 +248,7 @@ body.extend([ EmptyNode(), T("${per_isolate_data}->AddV8Template(" - "${world}, kTemplateKey, constructor_template);"), + "${world}, template_key, constructor_template);"), T("return constructor_template;"), ])
diff --git a/third_party/blink/renderer/core/css/style_recalc_test.cc b/third_party/blink/renderer/core/css/style_recalc_test.cc index 780f340..d5c7c72 100644 --- a/third_party/blink/renderer/core/css/style_recalc_test.cc +++ b/third_party/blink/renderer/core/css/style_recalc_test.cc
@@ -174,4 +174,37 @@ GetCSSPropertyColor())); } +TEST_F(StyleRecalcTest, SkipStyleRecalcForContainerCleanSubtree) { + ScopedCSSContainerQueriesForTest scoped_cq(true); + ScopedCSSContainerSkipStyleRecalcForTest scoped_skip(true); + + UpdateAllLifecyclePhasesForTest(); + + ASSERT_TRUE(GetDocument().body()); + + GetDocument().body()->setInnerHTML(R"HTML( + <style> + #container { container-type: inline-size; } + #container.narrow { width: 100px; } + @container (max-width: 100px) { + #affected { color: green; } + } + </style> + <div id="container"> + <span id="affected"></span> + </div> + )HTML", + ASSERT_NO_EXCEPTION); + + UpdateAllLifecyclePhasesForTest(); + + Element* container = GetDocument().getElementById("container"); + ASSERT_TRUE(container); + container->classList().Add("narrow"); + GetDocument().UpdateStyleAndLayoutTreeForThisDocument(); + + ASSERT_TRUE(container->GetContainerQueryData()); + EXPECT_FALSE(container->GetContainerQueryData()->SkippedStyleRecalc()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index be13f27..2dd8c127 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2890,6 +2890,12 @@ const ComputedStyle& style, const StyleRecalcChange& child_change) { DCHECK(RuntimeEnabledFeatures::CSSContainerSkipStyleRecalcEnabled()); + if (!child_change.TraversePseudoElements(*this)) { + // If none of the children or pseudo elements need to be traversed for style + // recalc, there is no point in marking the subtree as skipped. + DCHECK(!child_change.TraverseChildren(*this)); + return false; + } if (child_change.ReattachLayoutTree()) { if (!LayoutObjectIsNeeded(style) || style.Display() == EDisplay::kInline || style.IsDisplayTableType()) {
diff --git a/third_party/blink/renderer/core/html/forms/html_button_element.cc b/third_party/blink/renderer/core/html/forms/html_button_element.cc index 61135f0..2098d13 100644 --- a/third_party/blink/renderer/core/html/forms/html_button_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_button_element.cc
@@ -40,9 +40,7 @@ namespace blink { HTMLButtonElement::HTMLButtonElement(Document& document) - : HTMLFormControlElement(html_names::kButtonTag, document), - type_(SUBMIT), - is_activated_submit_(false) {} + : HTMLFormControlElement(html_names::kButtonTag, document) {} void HTMLButtonElement::setType(const AtomicString& type) { setAttribute(html_names::kTypeAttr, type); @@ -62,15 +60,15 @@ const AtomicString& HTMLButtonElement::FormControlType() const { switch (type_) { - case SUBMIT: { + case kSubmit: { DEFINE_STATIC_LOCAL(const AtomicString, submit, ("submit")); return submit; } - case BUTTON: { + case kButton: { DEFINE_STATIC_LOCAL(const AtomicString, button, ("button")); return button; } - case RESET: { + case kReset: { DEFINE_STATIC_LOCAL(const AtomicString, reset, ("reset")); return reset; } @@ -95,11 +93,11 @@ const AttributeModificationParams& params) { if (params.name == html_names::kTypeAttr) { if (EqualIgnoringASCIICase(params.new_value, "reset")) - type_ = RESET; + type_ = kReset; else if (EqualIgnoringASCIICase(params.new_value, "button")) - type_ = BUTTON; + type_ = kButton; else - type_ = SUBMIT; + type_ = kSubmit; UpdateWillValidateCache(); if (formOwner() && isConnected()) formOwner()->InvalidateDefaultButtonStyle(); @@ -118,11 +116,11 @@ To<HTMLPopupElement>(popupElement)->Invoke(this); } if (!IsDisabledFormControl()) { - if (Form() && type_ == SUBMIT) { + if (Form() && type_ == kSubmit) { Form()->PrepareForSubmission(&event, this); event.SetDefaultHandled(); } - if (Form() && type_ == RESET) { + if (Form() && type_ == kReset) { Form()->reset(); event.SetDefaultHandled(); } @@ -140,13 +138,14 @@ } bool HTMLButtonElement::WillRespondToMouseClickEvents() { - if (!IsDisabledFormControl() && Form() && (type_ == SUBMIT || type_ == RESET)) + if (!IsDisabledFormControl() && Form() && + (type_ == kSubmit || type_ == kReset)) return true; return HTMLFormControlElement::WillRespondToMouseClickEvents(); } bool HTMLButtonElement::CanBeSuccessfulSubmitButton() const { - return type_ == SUBMIT; + return type_ == kSubmit; } bool HTMLButtonElement::IsActivatedSubmit() const { @@ -158,7 +157,7 @@ } void HTMLButtonElement::AppendToFormData(FormData& form_data) { - if (type_ == SUBMIT && !GetName().IsEmpty() && is_activated_submit_) + if (type_ == kSubmit && !GetName().IsEmpty() && is_activated_submit_) form_data.AppendFromElement(GetName(), Value()); } @@ -178,7 +177,7 @@ } bool HTMLButtonElement::RecalcWillValidate() const { - return type_ == SUBMIT && HTMLFormControlElement::RecalcWillValidate(); + return type_ == kSubmit && HTMLFormControlElement::RecalcWillValidate(); } int HTMLButtonElement::DefaultTabIndex() const {
diff --git a/third_party/blink/renderer/core/html/forms/html_button_element.h b/third_party/blink/renderer/core/html/forms/html_button_element.h index 7080b9e..8d2b0948 100644 --- a/third_party/blink/renderer/core/html/forms/html_button_element.h +++ b/third_party/blink/renderer/core/html/forms/html_button_element.h
@@ -46,7 +46,7 @@ InputDeviceCapabilities*) override; private: - enum Type { SUBMIT, RESET, BUTTON }; + enum Type { kSubmit, kReset, kButton }; const AtomicString& FormControlType() const override; @@ -82,8 +82,8 @@ int DefaultTabIndex() const override; - Type type_; - bool is_activated_submit_; + Type type_ = kSubmit; + bool is_activated_submit_ = false; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc b/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc index cc50744..aadbd5f1 100644 --- a/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc +++ b/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc
@@ -75,7 +75,7 @@ } if (toggle_interstitial_timer_.IsActive()) toggle_interstitial_timer_.Stop(); - state_ = VISIBLE; + state_ = kVisible; RemoveInlineStyleProperty(CSSPropertyID::kDisplay); SetInlineStyleProperty(CSSPropertyID::kOpacity, 0, CSSPrimitiveValue::UnitType::kNumber); @@ -89,7 +89,7 @@ if (toggle_interstitial_timer_.IsActive()) toggle_interstitial_timer_.Stop(); if (error_code == WebMediaPlayerClient::kMediaRemotingStopNoText) { - state_ = HIDDEN; + state_ = kHidden; } else { String stop_text = GetVideoElement().GetLocale().QueryString(IDS_MEDIA_REMOTING_STOP_TEXT); @@ -98,7 +98,7 @@ stop_text; } toast_message_->setInnerText(stop_text, ASSERT_NO_EXCEPTION); - state_ = TOAST; + state_ = kToast; } SetInlineStyleProperty(CSSPropertyID::kOpacity, 0, CSSPrimitiveValue::UnitType::kNumber); @@ -117,7 +117,7 @@ SetInlineStyleProperty(CSSPropertyID::kBackgroundColor, CSSValueID::kBlack); SetInlineStyleProperty(CSSPropertyID::kOpacity, 1, CSSPrimitiveValue::UnitType::kNumber); - } else if (state_ == HIDDEN) { + } else if (state_ == kHidden) { SetInlineStyleProperty(CSSPropertyID::kDisplay, CSSValueID::kNone); toast_message_->setInnerText(WebString(), ASSERT_NO_EXCEPTION); } else { @@ -135,7 +135,7 @@ CSSValueID::kNone); toast_message_->SetInlineStyleProperty( CSSPropertyID::kOpacity, 1, CSSPrimitiveValue::UnitType::kNumber); - state_ = HIDDEN; + state_ = kHidden; toggle_interstitial_timer_.StartOneShot(kShowToastDuration, FROM_HERE); } }
diff --git a/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h b/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h index 466719b..24efeb3c 100644 --- a/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h +++ b/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h
@@ -43,7 +43,7 @@ void OnPosterImageChanged(); // Query for whether the remoting interstitial is visible. - bool IsVisible() const { return state_ == VISIBLE; } + bool IsVisible() const { return state_ == kVisible; } HTMLVideoElement& GetVideoElement() const { return *video_element_; } @@ -59,11 +59,11 @@ // Indicates whether the interstitial should be visible. It is set/changed // when Show()/Hide() is called. enum State { - HIDDEN, // The interstitial is currently not showing. - VISIBLE, // The interstitial is currently visible except the toast. - TOAST, // Only the toast is visible. + kHidden, // The interstitial is currently not showing. + kVisible, // The interstitial is currently visible except the toast. + kToast, // Only the toast is visible. }; - State state_ = HIDDEN; + State state_ = kHidden; HeapTaskRunnerTimer<MediaRemotingInterstitial> toggle_interstitial_timer_; Member<HTMLVideoElement> video_element_;
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc index 392759c2..15497e4 100644 --- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc +++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -664,17 +664,17 @@ HTMLDocumentParser::NextTokenStatus HTMLDocumentParser::CanTakeNextToken() { if (IsStopped()) - return NoTokens; + return kNoTokens; // If we're paused waiting for a script, we try to execute scripts before // continuing. - auto ret = HaveTokens; + auto ret = kHaveTokens; if (tree_builder_->HasParserBlockingScript()) { RunScriptsForPausedTreeBuilder(); - ret = HaveTokensAfterScript; + ret = kHaveTokensAfterScript; } if (IsStopped() || IsPaused()) - return NoTokens; + return kNoTokens; return ret; } @@ -1020,10 +1020,10 @@ unsigned tokens_parsed = 0; while (!should_yield) { const auto next_token_status = CanTakeNextToken(); - if (next_token_status == NoTokens) { + if (next_token_status == kNoTokens) { // No tokens left to process in this pump, so break break; - } else if (next_token_status == HaveTokensAfterScript && + } else if (next_token_status == kHaveTokensAfterScript && task_runner_state_->HaveExitedHeader()) { // Just executed a parser-blocking script in the body. We'd probably like // to yield at some point soon, especially if we're in "extended budget"
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.h b/third_party/blink/renderer/core/html/parser/html_document_parser.h index bbdfde4b..9ddb4f40 100644 --- a/third_party/blink/renderer/core/html/parser/html_document_parser.h +++ b/third_party/blink/renderer/core/html/parser/html_document_parser.h
@@ -166,7 +166,7 @@ ParserSynchronizationPolicy, ParserPrefetchPolicy); - enum NextTokenStatus { NoTokens, HaveTokens, HaveTokensAfterScript }; + enum NextTokenStatus { kNoTokens, kHaveTokens, kHaveTokensAfterScript }; // DocumentParser void Detach() final;
diff --git a/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc b/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc index a1e7cd7..54e29b4 100644 --- a/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc +++ b/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc
@@ -112,7 +112,7 @@ HTMLTreeBuilderSimulator::HTMLTreeBuilderSimulator( const HTMLParserOptions& options) : options_(options), in_select_insertion_mode_(false) { - namespace_stack_.push_back(HTML); + namespace_stack_.push_back(kHtml); } HTMLTreeBuilderSimulator::State HTMLTreeBuilderSimulator::StateFor( @@ -122,9 +122,9 @@ for (HTMLElementStack::ElementRecord* record = tree_builder->OpenElements()->TopRecord(); record; record = record->Next()) { - Namespace current_namespace = HTML; + Namespace current_namespace = kHtml; if (record->NamespaceURI() == svg_names::kNamespaceURI) - current_namespace = SVG; + current_namespace = kSvg; else if (record->NamespaceURI() == mathml_names::kNamespaceURI) current_namespace = kMathML; @@ -144,14 +144,14 @@ if (token.GetType() == HTMLToken::kStartTag) { const String& tag_name = token.Data(); if (ThreadSafeMatch(tag_name, svg_names::kSVGTag)) - namespace_stack_.push_back(SVG); + namespace_stack_.push_back(kSvg); if (ThreadSafeMatch(tag_name, mathml_names::kMathTag)) namespace_stack_.push_back(kMathML); if (InForeignContent() && TokenExitsForeignContent(token)) namespace_stack_.pop_back(); if (IsHTMLIntegrationPointForStartTag(token) || (namespace_stack_.back() == kMathML && TokenExitsMath(token))) { - namespace_stack_.push_back(HTML); + namespace_stack_.push_back(kHtml); } else if (!InForeignContent()) { // FIXME: This is just a copy of Tokenizer::updateStateFor which uses // threadSafeMatches. @@ -232,13 +232,13 @@ (token.GetType() == HTMLToken::kStartTag && token.SelfClosing() && InForeignContent())) { const String& tag_name = token.Data(); - if ((namespace_stack_.back() == SVG && + if ((namespace_stack_.back() == kSvg && ThreadSafeMatch(tag_name, svg_names::kSVGTag)) || (namespace_stack_.back() == kMathML && ThreadSafeMatch(tag_name, mathml_names::kMathTag)) || IsHTMLIntegrationPointForEndTag(token) || (namespace_stack_.Contains(kMathML) && - namespace_stack_.back() == HTML && TokenExitsMath(token))) { + namespace_stack_.back() == kHtml && TokenExitsMath(token))) { namespace_stack_.pop_back(); } if (ThreadSafeMatch(tag_name, html_names::kScriptTag)) { @@ -289,7 +289,7 @@ return EqualIgnoringASCIICase(encoding->Value(), "text/html") || EqualIgnoringASCIICase(encoding->Value(), "application/xhtml+xml"); } - } else if (tokens_ns == SVG) { + } else if (tokens_ns == kSvg) { // FIXME: It's very fragile that we special case foreignObject here to be // ASCII case-insensitive. if (EqualIgnoringASCIICase(tag_name, @@ -309,7 +309,7 @@ // If it's inside an HTML integration point, the top namespace is // HTML, and its next namespace is not HTML. - if (namespace_stack_.back() != HTML) + if (namespace_stack_.back() != kHtml) return false; if (namespace_stack_.size() < 2) return false; @@ -318,7 +318,7 @@ const String& tag_name = token.Data(); if (tokens_ns == kMathML) return ThreadSafeMatch(tag_name, mathml_names::kAnnotationXmlTag); - if (tokens_ns == SVG) { + if (tokens_ns == kSvg) { // FIXME: It's very fragile that we special case foreignObject here to be // ASCII case-insensitive. if (EqualIgnoringASCIICase(tag_name,
diff --git a/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.h b/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.h index 184f58f..ec0565d 100644 --- a/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.h +++ b/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.h
@@ -40,7 +40,7 @@ USING_FAST_MALLOC(HTMLTreeBuilderSimulator); private: - enum Namespace { HTML, SVG, kMathML }; + enum Namespace { kHtml, kSvg, kMathML }; enum class TemplateType { kRegular, kShadow }; @@ -67,7 +67,7 @@ SimulatedToken Simulate(const CompactHTMLToken&, HTMLTokenizer*); private: - bool InForeignContent() const { return namespace_stack_.back() != HTML; } + bool InForeignContent() const { return namespace_stack_.back() != kHtml; } bool IsHTMLIntegrationPointForStartTag(const CompactHTMLToken&) const; bool IsHTMLIntegrationPointForEndTag(const CompactHTMLToken&) const;
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_host.cc b/third_party/blink/renderer/core/inspector/dev_tools_host.cc index 244afef..090b8f0 100644 --- a/third_party/blink/renderer/core/inspector/dev_tools_host.cc +++ b/third_party/blink/renderer/core/inspector/dev_tools_host.cc
@@ -31,7 +31,6 @@ #include "base/json/json_reader.h" #include "third_party/blink/public/common/context_menu_data/menu_item_info.h" -#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h" #include "third_party/blink/renderer/core/clipboard/system_clipboard.h" @@ -49,6 +48,7 @@ #include "third_party/blink/renderer/core/page/context_menu_controller.h" #include "third_party/blink/renderer/core/page/context_menu_provider.h" #include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/core/script/classic_script.h" #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_error.h" @@ -126,11 +126,13 @@ ScriptState::Scope scope(script_state); v8::MicrotasksScope microtasks(script_state->GetIsolate(), v8::MicrotasksScope::kRunMicrotasks); - ScriptSourceCode source_code(expression, ScriptSourceLocationType::kInternal, - nullptr, KURL(), - TextPosition::MinimumPosition()); - V8ScriptRunner::CompileAndRunInternalScript(script_state->GetIsolate(), - script_state, source_code); + // `kDoNotSanitize` is used for internal scripts for keeping the existing + // behavior. + V8ScriptRunner::CompileAndRunInternalScript( + script_state->GetIsolate(), script_state, + *ClassicScript::CreateUnspecifiedScript( + ScriptSourceCode(expression, ScriptSourceLocationType::kInternal), + SanitizeScriptErrors::kDoNotSanitize)); } void DevToolsHost::DisconnectClient() {
diff --git a/third_party/blink/renderer/core/inspector/thread_debugger.cc b/third_party/blink/renderer/core/inspector/thread_debugger.cc index e1dc5b4..7e4372a 100644 --- a/third_party/blink/renderer/core/inspector/thread_debugger.cc +++ b/third_party/blink/renderer/core/inspector/thread_debugger.cc
@@ -8,7 +8,6 @@ #include "base/rand_util.h" #include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom-blink.h" -#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_blob.h" @@ -33,6 +32,7 @@ #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" #include "third_party/blink/renderer/core/inspector/v8_inspector_string.h" #include "third_party/blink/renderer/core/probe/core_probes.h" +#include "third_party/blink/renderer/core/script/classic_script.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_html.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_script.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h" @@ -361,12 +361,15 @@ v8::SideEffectType::kHasNoSideEffect); v8::Local<v8::Value> function_value; + // `kDoNotSanitize` is used for internal scripts for keeping the existing + // behavior. bool success = V8ScriptRunner::CompileAndRunInternalScript( isolate_, ScriptState::From(context), - ScriptSourceCode("(function(e) { console.log(e.type, e); })", - ScriptSourceLocationType::kInternal, nullptr, KURL(), - TextPosition::MinimumPosition())) + *ClassicScript::CreateUnspecifiedScript( + ScriptSourceCode("(function(e) { console.log(e.type, e); })", + ScriptSourceLocationType::kInternal), + SanitizeScriptErrors::kDoNotSanitize)) .ToLocal(&function_value) && function_value->IsFunction(); DCHECK(success);
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc index 843f857..71881b0 100644 --- a/third_party/blink/renderer/core/layout/layout_block.cc +++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -64,6 +64,7 @@ #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" +#include "third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.h" #include "third_party/blink/renderer/core/layout/text_autosizer.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h" @@ -118,6 +119,16 @@ return *map; } +// This map keeps track of SVG <text> descendants. +// LayoutNGSVGText needs to do re-layout on transform changes of any ancestor +// because LayoutNGSVGText's layout result depends on scaling factors computed +// with ancestor transforms. +TrackedDescendantsMap& GetSvgTextDescendantsMap() { + DEFINE_STATIC_LOCAL(Persistent<TrackedDescendantsMap>, map, + (MakeGarbageCollected<TrackedDescendantsMap>())); + return *map; +} + LayoutBlock::LayoutBlock(ContainerNode* node) : LayoutBox(node), has_margin_before_quirk_(false), @@ -129,6 +140,7 @@ descendants_with_floats_marked_for_layout_(false), has_positioned_objects_(false), has_percent_height_descendants_(false), + has_svg_text_descendants_(false), pagination_state_changed_(false), is_legacy_initiated_out_of_flow_layout_(false) { if (node) @@ -163,6 +175,10 @@ descendant->SetPercentHeightContainer(nullptr); } } + if (has_svg_text_descendants_) { + GetSvgTextDescendantsMap().erase(this); + has_svg_text_descendants_ = false; + } } void LayoutBlock::WillBeDestroyed() { @@ -259,6 +275,14 @@ old_style && diff.NeedsFullLayout() && NeedsLayout() && BorderOrPaddingLogicalDimensionChanged(*old_style, new_style, kLogicalHeight); + + if (diff.TransformChanged() && has_svg_text_descendants_) { + for (LayoutBox* box : *GetSvgTextDescendantsMap().at(this)) { + box->SetNeedsLayout(layout_invalidation_reason::kStyleChange, + kMarkContainerChain); + To<LayoutNGSVGText>(box)->SetNeedsTextMetricsUpdate(); + } + } } void LayoutBlock::UpdateFromStyle() { @@ -1227,6 +1251,33 @@ } } +void LayoutBlock::AddSvgTextDescendant(LayoutBox& svg_text) { + NOT_DESTROYED(); + DCHECK(IsA<LayoutNGSVGText>(svg_text)); + auto result = GetSvgTextDescendantsMap().insert(this, nullptr); + if (result.is_new_entry) { + result.stored_value->value = + MakeGarbageCollected<TrackedLayoutBoxLinkedHashSet>(); + } + result.stored_value->value->insert(&svg_text); + has_svg_text_descendants_ = true; +} + +void LayoutBlock::RemoveSvgTextDescendant(LayoutBox& svg_text) { + NOT_DESTROYED(); + DCHECK(IsA<LayoutNGSVGText>(svg_text)); + TrackedDescendantsMap& map = GetSvgTextDescendantsMap(); + auto it = map.find(this); + if (it == map.end()) + return; + TrackedLayoutBoxLinkedHashSet* descendants = &*it->value; + descendants->erase(&svg_text); + if (descendants->IsEmpty()) { + map.erase(this); + has_svg_text_descendants_ = false; + } +} + TrackedLayoutBoxLinkedHashSet* LayoutBlock::PercentHeightDescendantsInternal() const { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/layout_block.h b/third_party/blink/renderer/core/layout/layout_block.h index 4ef5517..0f0eaeb 100644 --- a/third_party/blink/renderer/core/layout/layout_block.h +++ b/third_party/blink/renderer/core/layout/layout_block.h
@@ -212,6 +212,9 @@ return has_percent_height_descendants_; } + void AddSvgTextDescendant(LayoutBox& svg_text); + void RemoveSvgTextDescendant(LayoutBox& svg_text); + void NotifyScrollbarThicknessChanged() { NOT_DESTROYED(); width_available_to_children_changed_ = true; @@ -633,6 +636,7 @@ unsigned has_positioned_objects_ : 1; unsigned has_percent_height_descendants_ : 1; + unsigned has_svg_text_descendants_ : 1; // When an object ceases to establish a fragmentation context (e.g. the // LayoutView when we're no longer printing), we need a deep layout
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h index f58efaa..599babb 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
@@ -123,13 +123,14 @@ void SetSvgLineLocalRect(const PhysicalRect& unscaled_rect); // A sequence number of fragments generated from a |LayoutObject|. - // For line boxes, please see |kInitialLineFragmentId|. + // For line boxes, this is a sequence number for the containing + // |LayoutBlockFlow|, starting at |kInitialLineFragmentId|. wtf_size_t FragmentId() const { - DCHECK_NE(Type(), kLine); + DCHECK(Type() != kLine || fragment_id_ >= kInitialLineFragmentId); return fragment_id_; } void SetFragmentId(wtf_size_t id) const { - DCHECK_NE(Type(), kLine); + DCHECK(Type() != kLine || id >= kInitialLineFragmentId); fragment_id_ = id; } // The initial framgent_id for line boxes. @@ -137,8 +138,6 @@ // its |LayoutBlockFlow| as their |DisplayItemClient|, but multicol also uses // fragment id for |LayoutBlockFlow| today. The plan is to make |FragmentData| // a |DisplayItemClient| instead. - // TODO(kojii): The fragment id for line boxes must be unique across NG block - // fragmentation. This is not implemented yet. static constexpr wtf_size_t kInitialLineFragmentId = 0x80000000; // Return true if this is the first fragment generated from a node.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc index 982c01c..b9f09f9 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc
@@ -428,6 +428,41 @@ EXPECT_TRUE(cursor.Current()->IsLastForNode()); } +TEST_F(NGFragmentItemTest, LineFragmentId) { + ScopedLayoutNGBlockFragmentationForTest ng_block_frag(true); + SetBodyInnerHTML(R"HTML( + <style> + #columns { + columns: 2; + column-fill: auto; + line-height: 1em; + height: 3em; + } + </style> + <body> + <div id="columns"> + <div id="target"> + 1<br> + 2<br> + 3<br> + 4<br> + 5<br> + 6 + </div> + </div> + </body> + )HTML"); + auto* target = To<LayoutBlockFlow>(GetLayoutObjectByElementId("target")); + NGInlineCursor cursor(*target); + wtf_size_t line_index = 0; + for (cursor.MoveToFirstLine(); cursor; + cursor.MoveToNextLineIncludingFragmentainer(), ++line_index) { + EXPECT_EQ(cursor.Current()->FragmentId(), + line_index + NGFragmentItem::kInitialLineFragmentId); + } + EXPECT_EQ(line_index, 6u); +} + // Various nodes/elements to test insertions. using CreateNode = Node* (*)(Document&); static CreateNode node_creators[] = {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc index fe29950..8b8696e 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
@@ -99,6 +99,7 @@ ClearCollectionScope<HeapHashMap<Member<const LayoutObject>, LastItem>> clear_scope(&last_items); wtf_size_t item_index = 0; + wtf_size_t line_fragment_id = NGFragmentItem::kInitialLineFragmentId; for (const auto& result : results) { const auto& fragment = To<NGPhysicalBoxFragment>(result->PhysicalFragment()); @@ -112,6 +113,7 @@ ++item_index; if (item.Type() == NGFragmentItem::kLine) { DCHECK_EQ(item.DeltaToNextForSameLayoutObject(), 0u); + item.SetFragmentId(line_fragment_id++); continue; } LayoutObject* const layout_object = item.GetMutableLayoutObject();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc index 48a63f2..3cde28f9 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
@@ -1192,6 +1192,15 @@ NOTREACHED(); } +void NGInlineCursor::MoveToNextLineIncludingFragmentainer() { + MoveToNextLine(); + if (!Current() && max_fragment_index_ && CanMoveAcrossFragmentainer()) { + MoveToNextFragmentainer(); + if (Current() && !Current().IsLineBox()) + MoveToFirstLine(); + } +} + void NGInlineCursor::MoveToPreviousInlineLeaf() { if (Current() && Current().IsInlineLeaf()) MoveToPrevious();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h index 82b938a..a1374d79 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
@@ -451,6 +451,7 @@ // Move the current position to next line. It is error to call other than line // box. void MoveToNextLine(); + void MoveToNextLineIncludingFragmentainer(); // Same as |MoveToNext| except that this skips children even if they exist. void MoveToNextSkippingChildren();
diff --git a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc index 20ed0861..ec880117 100644 --- a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc +++ b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
@@ -83,6 +83,20 @@ LayoutSVGBlock::RemoveChild(child); } +void LayoutNGSVGText::InsertedIntoTree() { + NOT_DESTROYED(); + LayoutNGBlockFlowMixin<LayoutSVGBlock>::InsertedIntoTree(); + for (LayoutBlock* cb = ContainingBlock(); cb; cb = cb->ContainingBlock()) + cb->AddSvgTextDescendant(*this); +} + +void LayoutNGSVGText::WillBeRemovedFromTree() { + NOT_DESTROYED(); + for (LayoutBlock* cb = ContainingBlock(); cb; cb = cb->ContainingBlock()) + cb->RemoveSvgTextDescendant(*this); + LayoutNGBlockFlowMixin<LayoutSVGBlock>::WillBeRemovedFromTree(); +} + void LayoutNGSVGText::SubtreeStructureChanged( LayoutInvalidationReasonForTracing) { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.h b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.h index d59ee38..6534a7eb 100644 --- a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.h +++ b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.h
@@ -34,6 +34,8 @@ bool IsChildAllowed(LayoutObject* child, const ComputedStyle&) const override; void AddChild(LayoutObject* child, LayoutObject* before_child) override; void RemoveChild(LayoutObject* child) override; + void InsertedIntoTree() override; + void WillBeRemovedFromTree() override; gfx::RectF ObjectBoundingBox() const override; gfx::RectF StrokeBoundingBox() const override; gfx::RectF VisualRectInLocalSVGCoordinates() const override;
diff --git a/third_party/blink/renderer/core/loader/mixed_content_checker.cc b/third_party/blink/renderer/core/loader/mixed_content_checker.cc index 040dadd..0713299 100644 --- a/third_party/blink/renderer/core/loader/mixed_content_checker.cc +++ b/third_party/blink/renderer/core/loader/mixed_content_checker.cc
@@ -234,7 +234,7 @@ source->GetDocument(), WebFeature::kMixedContentInNonHTTPSFrameThatRestrictsMixedContent); } - } else if (network::IsUrlPotentiallyTrustworthy(url) && + } else if (!network::IsUrlPotentiallyTrustworthy(url) && base::Contains(url::GetSecureSchemes(), origin->Protocol().Ascii())) { UseCounter::Count(
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index fae49fa..515992e 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -1472,7 +1472,6 @@ const NGPhysicalFragment& line_box_fragment, const DisplayItemClient& display_item_client, const NGFragmentItem& line_box_item, - wtf_size_t line_fragment_id, const PaintInfo& paint_info, const PhysicalOffset& child_offset) { if (paint_info.phase != PaintPhase::kForeground) @@ -1481,6 +1480,8 @@ PhysicalRect border_box = line_box_fragment.LocalRect(); border_box.offset += child_offset; absl::optional<ScopedDisplayItemFragment> display_item_fragment; + const wtf_size_t line_fragment_id = line_box_item.FragmentId(); + DCHECK_GE(line_fragment_id, NGFragmentItem::kInitialLineFragmentId); if (ShouldRecordHitTestData(paint_info)) { display_item_fragment.emplace(paint_info.context, line_fragment_id); paint_info.context.GetPaintController().RecordHitTestData( @@ -1556,7 +1557,6 @@ const PaintInfo& paint_info, const PhysicalOffset& paint_offset) { const bool is_horizontal = box_fragment_.Style().IsHorizontalWritingMode(); - wtf_size_t line_fragment_id = NGFragmentItem::kInitialLineFragmentId; for (; *children; children->MoveToNextSkippingChildren()) { const NGFragmentItem* child_item = children->CurrentItem(); DCHECK(child_item); @@ -1586,7 +1586,7 @@ child_item->LineBoxFragment(); DCHECK(line_box_fragment); PaintLineBox(*line_box_fragment, *child_item->GetDisplayItemClient(), - *child_item, line_fragment_id++, paint_info, child_offset); + *child_item, paint_info, child_offset); NGInlineCursor line_box_cursor = children->CursorForDescendants(); PaintInlineItems(paint_info, paint_offset, child_item->OffsetInContainerFragment(),
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h index 365be0f..0a32869 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
@@ -142,7 +142,6 @@ void PaintLineBox(const NGPhysicalFragment& line_box_fragment, const DisplayItemClient& display_item_client, const NGFragmentItem& line_box_item, - wtf_size_t line_fragment_id, const PaintInfo&, const PhysicalOffset& paint_offset); void PaintBackplate(NGInlineCursor* descendants,
diff --git a/third_party/blink/renderer/core/scroll/DEPS b/third_party/blink/renderer/core/scroll/DEPS new file mode 100644 index 0000000..7f381c0 --- /dev/null +++ b/third_party/blink/renderer/core/scroll/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "mac_scrollbar_animator_impl.h": [ + "+ui/native_theme/scrollbar_animator_mac.h", + ], +}
diff --git a/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.h b/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.h index 84971bb..1d95cf34 100644 --- a/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.h +++ b/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.h
@@ -15,6 +15,7 @@ #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" #include "third_party/blink/renderer/platform/timer.h" #include "ui/gfx/geometry/point_f.h" +#include "ui/native_theme/scrollbar_animator_mac.h" @class BlinkScrollbarObserver; @class BlinkScrollbarPainterControllerDelegate; @@ -27,7 +28,7 @@ class ScrollbarThemeMac; -class PLATFORM_EXPORT MacScrollbarImpl : public MacScrollbar { +class CORE_EXPORT MacScrollbarImpl : public MacScrollbar { public: MacScrollbarImpl(Scrollbar&, base::scoped_nsobject<ScrollbarPainterController>, @@ -111,7 +112,7 @@ // If the scroller is composited, the opacity value stored on the scrollbar // painter is subsequently read out through ScrollbarThemeMac::ThumbOpacity and // plumbed into PaintedScrollbarLayerImpl::thumb_opacity_. -class PLATFORM_EXPORT MacScrollbarAnimatorImpl : public MacScrollbarAnimator { +class CORE_EXPORT MacScrollbarAnimatorImpl : public MacScrollbarAnimator { public: MacScrollbarAnimatorImpl(ScrollableArea*); virtual ~MacScrollbarAnimatorImpl() = default; @@ -168,6 +169,80 @@ Member<ScrollableArea> scrollable_area_; }; +// Implementation of the MacScrollbarV2::Client interface to talk to a Scrollbar +// instance (the only other implementations are mocks for testing). +class CORE_EXPORT MacScrollbarImplV2 + : public ui::OverlayScrollbarAnimatorMac::Client, + public MacScrollbar { + public: + MacScrollbarImplV2(Scrollbar& scrollbar, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + ~MacScrollbarImplV2() override; + + // Return true if `this` is the animator for `scrollbar`. + bool IsAnimatorFor(Scrollbar& scrollbar) const; + + // Function to call upon interaction with this scrollbar. + void MouseDidEnter(); + void MouseDidExit(); + void DidScroll(); + + // MacScrollbar: + void SetEnabled(bool) final {} + void SetOverlayColorTheme(ScrollbarOverlayColorTheme) final {} + float GetKnobAlpha() final; + float GetTrackAlpha() final; + int GetTrackBoxWidth() final; + + // ui::OverlayScrollbarAnimatorMac::Client: + bool IsMouseInScrollbarFrameRect() const override; + void SetHidden(bool hidden) override; + void SetThumbNeedsDisplay() override; + void SetTrackNeedsDisplay() override; + + private: + std::unique_ptr<ui::OverlayScrollbarAnimatorMac> overlay_animator_; + Persistent<Scrollbar> scrollbar_; +}; + +// A non-Cocoa-based implementation of the MacScrollbarAnimator interface. +class CORE_EXPORT MacScrollbarAnimatorV2 : public MacScrollbarAnimator { + public: + MacScrollbarAnimatorV2(ScrollableArea*); + virtual ~MacScrollbarAnimatorV2(); + + // MacScrollbarAnimator: + void Trace(Visitor* visitor) const final { + MacScrollbarAnimator::Trace(visitor); + } + void ContentAreaWillPaint() const final {} + void MouseEnteredContentArea() const final {} + void MouseExitedContentArea() const final {} + void MouseMovedInContentArea() const final {} + void MouseEnteredScrollbar(Scrollbar&) const final; + void MouseExitedScrollbar(Scrollbar&) const final; + void ContentsResized() const final {} + void DidAddVerticalScrollbar(Scrollbar&) final; + void WillRemoveVerticalScrollbar(Scrollbar&) final; + void DidAddHorizontalScrollbar(Scrollbar&) final; + void WillRemoveHorizontalScrollbar(Scrollbar&) final; + bool SetScrollbarsVisibleForTesting(bool) final { return true; } + void DidChangeUserVisibleScrollOffset(const ScrollOffset&) final; + void UpdateScrollerStyle() final { NOTREACHED(); } + bool ScrollbarPaintTimerIsActive() const final { + NOTREACHED(); + return false; + } + void StartScrollbarPaintTimer() final { NOTREACHED(); } + void StopScrollbarPaintTimer() final { NOTREACHED(); } + void Dispose() final; + + private: + std::unique_ptr<MacScrollbarImplV2> horizontal_scrollbar_; + std::unique_ptr<MacScrollbarImplV2> vertical_scrollbar_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_MAC_SCROLLBAR_ANIMATOR_IMPL_H_
diff --git a/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.mm b/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.mm index d69bfe84..bd61947 100644 --- a/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.mm +++ b/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.mm
@@ -6,6 +6,7 @@ #import <AppKit/AppKit.h> +#include "base/feature_list.h" #include "base/mac/scoped_nsobject.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/core/scroll/ns_scroller_imp_details.h" @@ -28,6 +29,15 @@ return *map; } +typedef HeapHashMap<WeakMember<const Scrollbar>, MacScrollbarImplV2*> + ScrollbarToAnimatorV2Map; + +ScrollbarToAnimatorV2Map& GetScrollbarToAnimatorV2Map() { + DEFINE_STATIC_LOCAL(Persistent<ScrollbarToAnimatorV2Map>, map, + (MakeGarbageCollected<ScrollbarToAnimatorV2Map>())); + return *map; +} + } // namespace } // namespace blink @@ -82,6 +92,9 @@ } // namespace +/////////////////////////////////////////////////////////////////////////////// +// BlinkScrollbarObserver + @interface BlinkScrollbarObserver : NSObject { blink::Scrollbar* _scrollbar; base::scoped_nsobject<ScrollbarPainter> _scrollbarPainter; @@ -149,6 +162,9 @@ @end +/////////////////////////////////////////////////////////////////////////////// +// BlinkScrollbarPainterControllerDelegate +// // This class is a delegator of ScrollbarPainterController to ScrollableArea // that has the scrollbars of a ScrollbarPainter. @interface BlinkScrollbarPainterControllerDelegate : NSObject { @@ -257,73 +273,12 @@ }; @class BlinkScrollbarPartAnimation; -namespace blink { -// This class is used to drive the animation timer for -// BlinkScrollbarPartAnimation -// objects. This is used instead of NSAnimation because CoreAnimation -// establishes connections to the WindowServer, which should not be done in a -// sandboxed renderer process. -class BlinkScrollbarPartAnimationTimer { - public: - BlinkScrollbarPartAnimationTimer( - BlinkScrollbarPartAnimation* animation, - CFTimeInterval duration, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : timer_(std::move(task_runner), - this, - &BlinkScrollbarPartAnimationTimer::TimerFired), - start_time_(0.0), - duration_(duration), - animation_(animation), - timing_function_(CubicBezierTimingFunction::Preset( - CubicBezierTimingFunction::EaseType::EASE_IN_OUT)) {} - - ~BlinkScrollbarPartAnimationTimer() {} - - void Start() { - start_time_ = base::Time::Now().ToDoubleT(); - // Set the framerate of the animation. NSAnimation uses a default - // framerate of 60 Hz, so use that here. - timer_.StartRepeating(base::Seconds(1.0 / 60.0), FROM_HERE); - } - - void Stop() { timer_.Stop(); } - - void SetDuration(CFTimeInterval duration) { duration_ = duration; } - - private: - void TimerFired(TimerBase*) { - double current_time = base::Time::Now().ToDoubleT(); - double delta = current_time - start_time_; - - if (delta >= duration_) - timer_.Stop(); - - double fraction = delta / duration_; - fraction = ClampTo(fraction, 0.0, 1.0); - double progress = timing_function_->Evaluate(fraction); - // In some scenarios, animation_ gets released during the call to - // setCurrentProgress. Because BlinkScrollbarPartAnimationTimer is a - // member variable of BlinkScrollbarPartAnimation animation_ the timer - // gets freed at the same time with animation_. In that case, it will - // not be safe to call any other code after animation_ setCurrentProgress. - [animation_ setCurrentProgress:progress]; - } - - TaskRunnerTimer<BlinkScrollbarPartAnimationTimer> timer_; - double start_time_; // In seconds. - double duration_; // In seconds. - BlinkScrollbarPartAnimation* animation_; // Weak, owns this. - scoped_refptr<CubicBezierTimingFunction> timing_function_; -}; - -} // namespace blink // This class handles the animation of a |_featureToAnimate| part of // |_scrollbar|. @interface BlinkScrollbarPartAnimation : NSObject { blink::Scrollbar* _scrollbar; - std::unique_ptr<blink::BlinkScrollbarPartAnimationTimer> _timer; + std::unique_ptr<ui::ScrollbarAnimationTimerMac> _timer; base::scoped_nsobject<ScrollbarPainter> _scrollbarPainter; FeatureToAnimate _featureToAnimate; CGFloat _startValue; @@ -351,8 +306,14 @@ if (!self) return nil; - _timer = std::make_unique<blink::BlinkScrollbarPartAnimationTimer>( - self, duration, std::move(taskRunner)); + base::scoped_nsobject<BlinkScrollbarPartAnimation> scoped_self( + self, base::scoped_policy::RETAIN); + auto animation_callback = WTF::BindRepeating( + [](base::scoped_nsobject<BlinkScrollbarPartAnimation> animation, + double progress) { [animation setCurrentProgress:progress]; }, + std::move(scoped_self)); + _timer = std::make_unique<ui::ScrollbarAnimationTimerMac>( + std::move(animation_callback), duration, std::move(taskRunner)); _scrollbar = scrollbar; _featureToAnimate = featureToAnimate; _startValue = startValue; @@ -433,6 +394,9 @@ } @end +/////////////////////////////////////////////////////////////////////////////// +// BlinkScrollbarPainterDelegate +// // This class is a delegator of ScrollbarPainter to the 4 types of animation // it can run. The animations are run through BlinkScrollbarPartAnimation. @interface BlinkScrollbarPainterDelegate : NSObject <NSAnimationDelegate> { @@ -692,6 +656,9 @@ namespace blink { +/////////////////////////////////////////////////////////////////////////////// +// MacScrollbarImpl + MacScrollbarImpl::MacScrollbarImpl( Scrollbar& scrollbar, base::scoped_nsobject<ScrollbarPainterController> painter_controller, @@ -839,6 +806,9 @@ return [observer_ painter]; } +/////////////////////////////////////////////////////////////////////////////// +// MacScrollbarAnimatorImpl + MacScrollbarAnimatorImpl::MacScrollbarAnimatorImpl( ScrollableArea* scrollable_area) : task_runner_(scrollable_area->GetCompositorTaskRunner()), @@ -1060,18 +1030,189 @@ [scrollbar_painter_controller_ contentAreaScrolled]; } +/////////////////////////////////////////////////////////////////////////////// +// MacScrollbarImplV2 + +MacScrollbarImplV2::MacScrollbarImplV2( + Scrollbar& scrollbar, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : scrollbar_(scrollbar) { + if (ScrollbarThemeMac::PreferOverlayScrollerStyle()) { + int track_box_width_expanded = 0; + int track_box_width_unexpanded = 0; + switch (scrollbar_->CSSScrollbarWidth()) { + case EScrollbarWidth::kNone: + break; + case EScrollbarWidth::kThin: + track_box_width_expanded = 14; + track_box_width_unexpanded = 10; + break; + case EScrollbarWidth::kAuto: + track_box_width_expanded = 16; + track_box_width_unexpanded = 12; + break; + } + overlay_animator_ = std::make_unique<ui::OverlayScrollbarAnimatorMac>( + this, track_box_width_expanded, track_box_width_unexpanded, + task_runner); + } + GetScrollbarToAnimatorV2Map().Set(scrollbar_, this); +} + +MacScrollbarImplV2::~MacScrollbarImplV2() { + auto it = GetScrollbarToAnimatorV2Map().find(scrollbar_); + GetScrollbarToAnimatorV2Map().erase(it); +} + +bool MacScrollbarImplV2::IsAnimatorFor(Scrollbar& scrollbar) const { + return &scrollbar == scrollbar_; +} + +void MacScrollbarImplV2::MouseDidEnter() { + if (overlay_animator_) + overlay_animator_->MouseDidEnter(); +} +void MacScrollbarImplV2::MouseDidExit() { + if (overlay_animator_) + overlay_animator_->MouseDidExit(); +} + +void MacScrollbarImplV2::DidScroll() { + if (overlay_animator_) + overlay_animator_->DidScroll(); +} + +float MacScrollbarImplV2::GetKnobAlpha() { + if (overlay_animator_) + return overlay_animator_->GetThumbAlpha(); + return 1.f; +} + +float MacScrollbarImplV2::GetTrackAlpha() { + if (overlay_animator_) + return overlay_animator_->GetTrackAlpha(); + return 1.f; +} + +int MacScrollbarImplV2::GetTrackBoxWidth() { + if (overlay_animator_) + return overlay_animator_->GetThumbWidth(); + + switch (scrollbar_->CSSScrollbarWidth()) { + case EScrollbarWidth::kNone: + return 0; + case EScrollbarWidth::kThin: + return 11; + case EScrollbarWidth::kAuto: + return 15; + } +} + +bool MacScrollbarImplV2::IsMouseInScrollbarFrameRect() const { + if (auto* area = scrollbar_->GetScrollableArea()) + return scrollbar_->FrameRect().Contains(area->LastKnownMousePosition()); + return false; +} +void MacScrollbarImplV2::SetHidden(bool hidden) { + scrollbar_->SetScrollbarsHiddenFromExternalAnimator(hidden); +} +void MacScrollbarImplV2::SetThumbNeedsDisplay() { + scrollbar_->SetNeedsPaintInvalidation(kThumbPart); +} +void MacScrollbarImplV2::SetTrackNeedsDisplay() { + scrollbar_->SetNeedsPaintInvalidation(kTrackBGPart); +} + +/////////////////////////////////////////////////////////////////////////////// +// MacScrollbarAnimatorV2 + +MacScrollbarAnimatorV2::MacScrollbarAnimatorV2(ScrollableArea* scrollable_area) + : task_runner_(scrollable_area->GetCompositorTaskRunner()) {} +MacScrollbarAnimatorV2::~MacScrollbarAnimatorV2() = default; + +void MacScrollbarAnimatorV2::MouseEnteredScrollbar(Scrollbar& scrollbar) const { + if (horizontal_scrollbar_ && horizontal_scrollbar_->IsAnimatorFor(scrollbar)) + horizontal_scrollbar_->MouseDidEnter(); + if (vertical_scrollbar_ && vertical_scrollbar_->IsAnimatorFor(scrollbar)) + vertical_scrollbar_->MouseDidEnter(); +} + +void MacScrollbarAnimatorV2::MouseExitedScrollbar(Scrollbar& scrollbar) const { + if (horizontal_scrollbar_ && horizontal_scrollbar_->IsAnimatorFor(scrollbar)) + horizontal_scrollbar_->MouseDidExit(); + if (vertical_scrollbar_ && vertical_scrollbar_->IsAnimatorFor(scrollbar)) + vertical_scrollbar_->MouseDidExit(); +} + +void MacScrollbarAnimatorV2::DidAddVerticalScrollbar(Scrollbar& scrollbar) { + if (!IsScrollbarRegistered(scrollbar)) + return; + DCHECK(!vertical_scrollbar_); + vertical_scrollbar_ = + std::make_unique<MacScrollbarImplV2>(scrollbar, task_runner_); +} + +void MacScrollbarAnimatorV2::WillRemoveVerticalScrollbar(Scrollbar& scrollbar) { + vertical_scrollbar_.reset(); +} + +void MacScrollbarAnimatorV2::DidAddHorizontalScrollbar(Scrollbar& scrollbar) { + if (!IsScrollbarRegistered(scrollbar)) + return; + DCHECK(!horizontal_scrollbar_); + horizontal_scrollbar_ = + std::make_unique<MacScrollbarImplV2>(scrollbar, task_runner_); +} + +void MacScrollbarAnimatorV2::WillRemoveHorizontalScrollbar( + Scrollbar& scrollbar) { + horizontal_scrollbar_.reset(); +} + +void MacScrollbarAnimatorV2::DidChangeUserVisibleScrollOffset( + const ScrollOffset& new_offset) { + if (horizontal_scrollbar_ && new_offset.width() != 0) + horizontal_scrollbar_->DidScroll(); + if (vertical_scrollbar_ && new_offset.height() != 0) + vertical_scrollbar_->DidScroll(); +} + +void MacScrollbarAnimatorV2::Dispose() { + vertical_scrollbar_.reset(); + horizontal_scrollbar_.reset(); +} + +/////////////////////////////////////////////////////////////////////////////// +// MacScrollbarAnimator + +const base::Feature kMacScrollbarsV2{"MacScrollbarsV2", + base::FEATURE_ENABLED_BY_DEFAULT}; + // static MacScrollbarAnimator* MacScrollbarAnimator::Create( ScrollableArea* scrollable_area) { + if (base::FeatureList::IsEnabled(kMacScrollbarsV2)) { + return MakeGarbageCollected<MacScrollbarAnimatorV2>( + const_cast<ScrollableArea*>(scrollable_area)); + } return MakeGarbageCollected<MacScrollbarAnimatorImpl>( const_cast<ScrollableArea*>(scrollable_area)); } +/////////////////////////////////////////////////////////////////////////////// +// MacScrollbar + // static MacScrollbar* MacScrollbar::GetForScrollbar(const Scrollbar& scrollbar) { - auto it = GetScrollbarToAnimatorMap().find(&scrollbar); - if (it != GetScrollbarToAnimatorMap().end()) - return it->value; + if (base::FeatureList::IsEnabled(kMacScrollbarsV2)) { + auto found = GetScrollbarToAnimatorV2Map().find(&scrollbar); + if (found != GetScrollbarToAnimatorV2Map().end()) + return found->value; + } else { + auto found = GetScrollbarToAnimatorMap().find(&scrollbar); + if (found != GetScrollbarToAnimatorMap().end()) + return found->value; + } return nullptr; }
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.cc b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.cc index 0f82f19..17cc3cf 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.cc +++ b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.cc
@@ -87,6 +87,7 @@ : legacy_regular_values; } } + const NSScrollerImpValues& GetScrollbarPainterValues( const Scrollbar& scrollbar) { return GetScrollbarPainterValues(
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.cc b/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.cc index d12f85cf..7d428e3 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.cc
@@ -222,10 +222,12 @@ MediaStreamAudioProcessor::MediaStreamAudioProcessor( DeliverProcessedAudioCallback deliver_processed_audio_callback, + LogCallback log_callback, const AudioProcessingProperties& properties, bool use_capture_multi_channel_processing, scoped_refptr<WebRtcAudioDeviceImpl> playout_data_source) : deliver_processed_audio_callback_(deliver_processed_audio_callback), + log_callback_(log_callback), render_delay_(base::TimeDelta()), audio_delay_stats_reporter_(kBuffersPerSecond), playout_data_source_(std::move(playout_data_source)), @@ -235,12 +237,14 @@ stopped_(false), use_capture_multi_channel_processing_( use_capture_multi_channel_processing) { + DCHECK(deliver_processed_audio_callback_); + DCHECK(log_callback_); DCHECK(main_thread_runner_); DETACH_FROM_THREAD(capture_thread_checker_); DETACH_FROM_THREAD(render_thread_checker_); - SendLogMessage( - String::Format("%s({use_capture_multi_channel_processing=%s})", __func__, - use_capture_multi_channel_processing ? "true" : "false")); + SendLogMessage(base::StringPrintf( + "%s({use_capture_multi_channel_processing=%s})", __func__, + use_capture_multi_channel_processing ? "true" : "false")); InitializeAudioProcessingModule(properties); } @@ -346,7 +350,7 @@ DCHECK(base::FeatureList::IsEnabled( features::kMinimizeAudioProcessingForUnusedOutput)); SendLogMessage( - String::Format("%s({muted=%s})", __func__, muted ? "true" : "false")); + base::StringPrintf("%s({muted=%s})", __func__, muted ? "true" : "false")); if (audio_processing_) { audio_processing_->set_output_will_be_muted(muted); } @@ -482,7 +486,7 @@ const AudioProcessingProperties& properties) { DCHECK(main_thread_runner_->BelongsToCurrentThread()); DCHECK(!audio_processing_); - SendLogMessage(String::Format("%s()", __func__)); + SendLogMessage(base::StringPrintf("%s()", __func__)); // Note: The audio mirroring constraint (i.e., swap left and right channels) // is handled within this MediaStreamAudioProcessor and does not, by itself, @@ -526,8 +530,9 @@ const media::AudioParameters& input_format) { DCHECK(main_thread_runner_->BelongsToCurrentThread()); DCHECK(input_format.IsValid()); - SendLogMessage(String::Format("%s({input_format=[%s]})", __func__, - input_format.AsHumanReadableString().c_str())); + SendLogMessage( + base::StringPrintf("%s({input_format=[%s]})", __func__, + input_format.AsHumanReadableString().c_str())); input_format_ = input_format; @@ -610,11 +615,11 @@ output_format_.set_channels_for_discrete(input_format.channels()); } SendLogMessage( - String::Format("%s => (output_format=[%s])", __func__, - output_format_.AsHumanReadableString().c_str())); - SendLogMessage( - String::Format("%s => (FIFO: processing_frames=%d, output_channels=%d)", - __func__, processing_frames, fifo_output_channels)); + base::StringPrintf("%s => (output_format=[%s])", __func__, + output_format_.AsHumanReadableString().c_str())); + SendLogMessage(base::StringPrintf( + "%s => (FIFO: processing_frames=%d, output_channels=%d)", __func__, + processing_frames, fifo_output_channels)); capture_fifo_ = std::make_unique<MediaStreamAudioFifo>( input_format.channels(), fifo_output_channels, @@ -743,11 +748,10 @@ DCHECK(main_thread_runner_->BelongsToCurrentThread()); } -void MediaStreamAudioProcessor::SendLogMessage(const WTF::String& message) { - WebRtcLogMessage(String::Format("MSAP::%s [this=0x%" PRIXPTR "]", - message.Utf8().c_str(), - reinterpret_cast<uintptr_t>(this)) - .Utf8()); +void MediaStreamAudioProcessor::SendLogMessage(const std::string& message) { + log_callback_.Run(base::StringPrintf("MSAP::%s [this=0x%" PRIXPTR "]", + message.c_str(), + reinterpret_cast<uintptr_t>(this))); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.h b/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.h index 6301273..1234555 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.h +++ b/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.h
@@ -56,16 +56,24 @@ base::TimeTicks audio_capture_time, absl::optional<double> new_volume)>; + using LogCallback = base::RepeatingCallback<void(const std::string&)>; + // |deliver_processed_audio_callback| is used to deliver frames of processed // capture audio, from ProcessCapturedAudio(), and has to be valid until - // Stop() is called. |playout_data_source| is used to register this class as a - // sink to the WebRtc playout data for processing AEC. If clients do not - // enable AEC, |playout_data_source| won't be used. + // Stop() is called. |log_callback| is used for logging messages. + // |playout_data_source| is used to register this class as a sink to the + // WebRtc playout data for processing AEC. If clients do not enable AEC, + // |playout_data_source| won't be used. + + // |playout_data_source| is used to register this class as a sink to the + // WebRtc playout data for processing AEC. If clients do not enable AEC, + // |playout_data_source| won't be used. // // Threading note: The constructor assumes it is being run on the main render // thread. MediaStreamAudioProcessor( DeliverProcessedAudioCallback deliver_processed_audio_callback, + LogCallback log_callback, const AudioProcessingProperties& properties, bool use_capture_multi_channel_processing, scoped_refptr<WebRtcAudioDeviceImpl> playout_data_source); @@ -195,11 +203,14 @@ // Update AEC stats. Called on the main render thread. void UpdateAecStats(); - void SendLogMessage(const WTF::String& message); + void SendLogMessage(const std::string& message); // Consumer of processed capture audio in ProcessCapturedAudio(). DeliverProcessedAudioCallback deliver_processed_audio_callback_; + // Used by SendLogMessage. + LogCallback log_callback_; + // Cached value for the render delay latency. This member is accessed by // both the capture audio thread and the render audio thread. std::atomic<base::TimeDelta> render_delay_;
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor_test.cc index d6f1aff..4cdd2ce 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor_test.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor_test.cc
@@ -69,6 +69,11 @@ DCHECK(data_file_size64 > length); } +MediaStreamAudioProcessor::LogCallback LogCallbackForTest() { + return base::BindRepeating( + [](const std::string& message) { VLOG(1) << message; }); +} + } // namespace class MediaStreamAudioProcessorTest : public ::testing::Test { @@ -205,8 +210,8 @@ blink::AudioProcessingProperties properties; scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - mock_capture_callback_.Get(), properties, use_multichannel_processing, - webrtc_audio_device)); + mock_capture_callback_.Get(), LogCallbackForTest(), properties, + use_multichannel_processing, webrtc_audio_device)); EXPECT_TRUE(audio_processor->has_audio_processing()); audio_processor->OnCaptureFormatChanged(params_); VerifyDefaultComponents(*audio_processor); @@ -231,7 +236,7 @@ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>()); scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - mock_capture_callback_.Get(), properties, + mock_capture_callback_.Get(), LogCallbackForTest(), properties, /*use_capture_multi_channel_processing=*/true, webrtc_audio_device)); EXPECT_FALSE(audio_processor->has_audio_processing()); audio_processor->OnCaptureFormatChanged(params_); @@ -258,8 +263,8 @@ blink::AudioProcessingProperties properties; scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - mock_capture_callback_.Get(), properties, use_multichannel_processing, - webrtc_audio_device)); + mock_capture_callback_.Get(), LogCallbackForTest(), properties, + use_multichannel_processing, webrtc_audio_device)); EXPECT_TRUE(audio_processor->has_audio_processing()); static const int kSupportedSampleRates[] = { @@ -313,7 +318,7 @@ { scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - mock_capture_callback_.Get(), properties, + mock_capture_callback_.Get(), LogCallbackForTest(), properties, /*use_capture_multi_channel_processing=*/true, webrtc_audio_device)); @@ -378,7 +383,7 @@ properties.goog_audio_mirroring = true; scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - mock_capture_callback_.Get(), properties, + mock_capture_callback_.Get(), LogCallbackForTest(), properties, use_multichannel_processing, webrtc_audio_device)); EXPECT_EQ(audio_processor->has_audio_processing(), use_apm); audio_processor->OnCaptureFormatChanged(source_params); @@ -449,8 +454,8 @@ blink::AudioProcessingProperties properties; scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - mock_capture_callback_.Get(), properties, use_multichannel_processing, - webrtc_audio_device)); + mock_capture_callback_.Get(), LogCallbackForTest(), properties, + use_multichannel_processing, webrtc_audio_device)); EXPECT_TRUE(audio_processor->has_audio_processing()); media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, @@ -479,7 +484,7 @@ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>()); scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - mock_capture_callback_.Get(), properties, + mock_capture_callback_.Get(), LogCallbackForTest(), properties, /*use_capture_multi_channel_processing=*/true, webrtc_audio_device)); EXPECT_TRUE(audio_processor->has_audio_processing()); @@ -508,7 +513,7 @@ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>()); scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - mock_capture_callback.Get(), properties, + mock_capture_callback.Get(), LogCallbackForTest(), properties, /*use_capture_multi_channel_processing=*/true, webrtc_audio_device)); ASSERT_TRUE(audio_processor->has_audio_processing()); @@ -565,7 +570,7 @@ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>()); scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - mock_capture_callback.Get(), properties, + mock_capture_callback.Get(), LogCallbackForTest(), properties, /*use_capture_multi_channel_processing=*/true, webrtc_audio_device)); ASSERT_TRUE(audio_processor->has_audio_processing()); @@ -612,7 +617,7 @@ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>()); scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - mock_capture_callback.Get(), properties, + mock_capture_callback.Get(), LogCallbackForTest(), properties, /*use_capture_multi_channel_processing=*/true, webrtc_audio_device)); ASSERT_FALSE(audio_processor->has_audio_processing()); @@ -656,7 +661,7 @@ new rtc::RefCountedObject<WebRtcAudioDeviceImpl>()); scoped_refptr<MediaStreamAudioProcessor> audio_processor( new rtc::RefCountedObject<MediaStreamAudioProcessor>( - mock_capture_callback.Get(), properties, + mock_capture_callback.Get(), LogCallbackForTest(), properties, /*use_capture_multi_channel_processing=*/true, webrtc_audio_device)); ASSERT_FALSE(audio_processor->has_audio_processing());
diff --git a/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc b/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc index b8b6ccb..81d6e34 100644 --- a/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc +++ b/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc
@@ -380,9 +380,13 @@ ConvertToBaseRepeatingCallback(CrossThreadBindRepeating( &ProcessedLocalAudioSource::DeliverProcessedAudio, CrossThreadUnretained(this))); + MediaStreamAudioProcessor::LogCallback log_callback = + ConvertToBaseRepeatingCallback( + CrossThreadBindRepeating(&WebRtcLogMessage)); audio_processor_ = new rtc::RefCountedObject<MediaStreamAudioProcessor>( - std::move(processing_callback), audio_processing_properties_, - use_multichannel_processing, rtc_audio_device); + std::move(processing_callback), std::move(log_callback), + audio_processing_properties_, use_multichannel_processing, + rtc_audio_device); params.set_frames_per_buffer(GetBufferSize(device().input.sample_rate())); audio_processor_->OnCaptureFormatChanged(params); SetFormat(audio_processor_->OutputFormat());
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 4cae866..b2bd2b6b 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -404,7 +404,7 @@ }, { name: "COLRV1Fonts", - status: "experimental", + status: "stable", }, { name: "CompositeBGColorAnimation",
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index 59574aa2..e27bf06 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -1410,6 +1410,16 @@ }, { 'paths': [ + 'third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.h', + 'third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.mm', + ], + 'allowed': [ + 'ui::ScrollbarAnimationTimerMac', + 'ui::OverlayScrollbarAnimatorMac', + ], + }, + { + 'paths': [ 'third_party/blink/renderer/modules/crypto/', ], 'allowed': ['crypto::.+'],
diff --git a/third_party/blink/web_tests/LeakExpectations b/third_party/blink/web_tests/LeakExpectations index 2a9d6da..657079a 100644 --- a/third_party/blink/web_tests/LeakExpectations +++ b/third_party/blink/web_tests/LeakExpectations
@@ -161,6 +161,9 @@ crbug.com/1219915 [ Linux ] touchadjustment/focusout-on-touch.html [ Failure ] crbug.com/1219915 [ Linux ] touchadjustment/touch-links-longpress.html [ Failure ] +# Sheriff 2021-11-18 +crbug.com/1271392 [ Linux ] external/wpt/service-workers/service-worker/navigation-headers.https.html [ Failure Pass ] + ########################################################################### # WARNING: Memory leaks must be fixed asap. Sheriff is expected to revert # # culprit CLs instead of suppressing the leaks. If you have any question, #
diff --git a/third_party/blink/web_tests/MSANExpectations b/third_party/blink/web_tests/MSANExpectations index bdd9c1e..ee94cf4c 100644 --- a/third_party/blink/web_tests/MSANExpectations +++ b/third_party/blink/web_tests/MSANExpectations
@@ -116,7 +116,6 @@ crbug.com/856601 [ Linux ] external/wpt/IndexedDB/nested-cloning-large.any.sharedworker.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/IndexedDB/nested-cloning-large.any.worker.html [ Pass Timeout ] crbug.com/856601 [ Linux ] external/wpt/IndexedDB/nested-cloning-small.any.serviceworker.html [ Pass Timeout ] -crbug.com/856601 [ Linux ] http/tests/devtools/a11y-axe-core/console/console-a11y-test.js [ Pass Timeout ] # Sheriff 2019-06-28 crbug.com/856601 [ Linux ] http/tests/devtools/indexeddb/live-update-indexeddb-content.js [ Pass Timeout ] @@ -171,9 +170,6 @@ crbug.com/1179829 [ Linux ] http/tests/devtools/console/console-viewport-stick-to-bottom-onload.js [ Pass Timeout ] crbug.com/1179829 [ Linux ] http/tests/devtools/isolated-code-cache/stale-revalidation-test.js [ Pass Timeout ] -# Sheriff 2021-03-23 -crbug.com/1179829 [ Linux ] http/tests/devtools/console/viewport-testing/console-stick-to-bottom-with-large-prompt.js [ Pass Timeout ] - # Sheriff 2021-04-22 crbug.com/1201807 [ Linux ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 8b508c1..34a26f0 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -1687,17 +1687,6 @@ virtual/not-site-per-process/external/wpt/app-history/navigate-event/cross-window/submit-samedocument-crossorigin-sameorigindomain.sub.html [ Pass ] virtual/wasm-module-sharing-enabled-not-site-per-process/external/wpt/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html [ Pass ] virtual/wasm-module-sharing-enabled-not-site-per-process/external/wpt/wasm/serialization/module/window-domain-success.sub.html [ Pass ] -# -------------------- origin-vs-url in console messages ----------------- -# Process hosting https://foo.example.com should not get any data from -# https://bar.other-site-example.com. This includes things like cookies -# and localStorage, but also full URLs (which may include some "secrets" -# and [unlike origins] are not exposed to other origins through web APIs). -# To properly enforce security boundary described above, console messages -# cannot include full cross-origin URLs (i.e. the messages need to strip -# cross-origin URLs down to just the origin - for example, -# https://foo.example.com/path?token=secret needs to be replaced with just -# https://foo.example.com). -crbug.com/669083 http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ Skip ] # ----------------------- origin-keyed agent clusters -------------------- # Origin-keyed agent clusters web platform tests are for the feature at # https://html.spec.whatwg.org/#origin-keyed-agent-clusters. It doesn't make
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 42eb496..6ebe2d0a 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -536,6 +536,7 @@ crbug.com/898394 virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top.html [ Failure Timeout ] +crbug.com/1024151 http/tests/devtools/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.js [ Failure Pass ] # Subpixel rounding differences that are incorrect. crbug.com/997202 compositing/overflow/scaled-overflow.html [ Failure ] @@ -3000,6 +3001,7 @@ crbug.com/626703 virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Mac10.15 ] virtual/without-coep-for-shared-worker/external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Skip Timeout ] crbug.com/626703 [ Mac10.15 ] external/wpt/media-capabilities/encodingInfo.any.worker.html [ Crash ] crbug.com/626703 [ Mac11 ] virtual/css-calc-infinity-and-nan-disabled/external/wpt/css/css-transforms/crashtests/w-negative-002.html [ Timeout ] crbug.com/626703 [ Mac11 ] virtual/dialogfocus-old-behavior/external/wpt/html/semantics/interactive-elements/the-dialog-element/backdrop-does-not-inherit.html [ Timeout ] @@ -3446,8 +3448,6 @@ crbug.com/626703 [ Mac11 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-iceRestart.html [ Skip Timeout ] crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCDtlsTransport-state.html [ Timeout ] crbug.com/626703 [ Mac11 ] external/wpt/webrtc/RTCDtlsTransport-state.html [ Timeout ] -crbug.com/626703 [ Mac10.14 ] external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https.html [ Timeout ] -crbug.com/626703 [ Mac11-arm64 ] external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https.html [ Failure Pass Timeout ] crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html [ Timeout ] crbug.com/626703 [ Mac11 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html [ Timeout ] crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCIceTransport.html [ Timeout ] @@ -4053,6 +4053,7 @@ crbug.com/614667 external/wpt/css/css-break/grid/grid-item-fragmentation-029.html [ Failure ] crbug.com/614667 external/wpt/css/css-break/grid/grid-item-fragmentation-030.html [ Failure ] crbug.com/614667 external/wpt/css/css-break/grid/grid-item-fragmentation-031.html [ Failure ] +crbug.com/1066629 external/wpt/css/css-break/hit-test-transformed.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/monolithic-with-overflow-lr.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/monolithic-with-overflow-rl.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/monolithic-with-overflow.html [ Failure ] @@ -6806,7 +6807,6 @@ crbug.com/1230534 external/wpt/webrtc/simulcast/getStats.https.html [ Failure Pass Skip Timeout ] # Sheriff 2021-08-10 -crbug.com/1233840 external/wpt/html/cross-origin-opener-policy/historical/coep-navigate-popup-unsafe-inherit.https.html [ Pass Skip Timeout ] crbug.com/1230534 external/wpt/webrtc/simulcast/basic.https.html [ Pass Skip Timeout ] crbug.com/1230534 external/wpt/webrtc/simulcast/setParameters-active.https.html [ Failure Pass Skip Timeout ] @@ -7164,9 +7164,7 @@ crbug.com/1222126 http/tests/devtools/domdebugger/domdebugger-getEventListeners.js [ Skip ] crbug.com/1222126 http/tests/devtools/cache-storage/cache-live-update-list.js [ Skip ] crbug.com/1222126 http/tests/devtools/runtime/evaluate-timeout.js [ Skip ] -crbug.com/1222126 http/tests/devtools/resource-har-headers.js [ Skip ] crbug.com/1222126 http/tests/devtools/resource-har-conversion.js [ Skip ] -crbug.com/1222126 http/tests/devtools/network/network-choose-preview-view.js [ Skip ] crbug.com/1222126 http/tests/devtools/network/json-preview.js [ Skip ] crbug.com/1215072 http/tests/devtools/elements/copy-styles.js [ Skip ] @@ -7300,3 +7298,5 @@ # Security OWP fixit week crbug.com/1270355 external/wpt/html/browsers/browsing-the-web/navigating-across-documents/009.html [ Timeout ] +# Sheriff 2021-11-18 +crbug.com/1180993 external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https.html [ Failure Pass Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index d115ce0..a99a9ea 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -961,7 +961,7 @@ }, { "prefix": "partitioned-cookies", - "bases": ["external/wpt/cookies/partitioned-cookies/"], + "bases": ["external/wpt/cookies/partitioned-cookies/", "http/tests/inspector-protocol/network/"], "args": ["--enable-features=PartitionedCookies"] }, {
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 5d84259..cf43388 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
@@ -214623,6 +214623,19 @@ {} ] ], + "transform-dynamic-change.html": [ + "964a7d31f69397ecc5a06cac4cf0e4efd890ebeb", + [ + null, + [ + [ + "/svg/text/reftests/transform-dynamic-change-ref.html", + "==" + ] + ], + {} + ] + ], "tspan-opacity-mixed-direction.svg": [ "fa153250e79ab6a60bf167c659b4e2d777609a30", [ @@ -303993,6 +304006,10 @@ "0e2008c328aeb06071efa6086786a273c6cafe7d", [] ], + "transform-dynamic-change-ref.html": [ + "c7e238d2bf957491c5a1f041db0b0c19bd8269bd", + [] + ], "tspan-opacity-mixed-direction-ref.svg": [ "f07911627fed87722b41ddb7a006eb1b7a65a63a", [] @@ -477950,6 +477967,13 @@ } ] ], + "prompt-in-detached-iframe.html": [ + "501471755ab8130e0799a9c2c82960eb096ae5a3", + [ + null, + {} + ] + ], "watch-availability-initial-callback.html": [ "352321b06ae66c5a3e31c1d3d7cf40a5e3b4c460", [ @@ -500049,7 +500073,7 @@ ] ], "request-video-frame-callback-dom.html": [ - "0277d7297883c4cd4f472b08c4399806280fe8eb", + "c1804b4edd0c986aa161dfc13179983c04ace404", [ null, {} @@ -500063,14 +500087,14 @@ ] ], "request-video-frame-callback-parallel.html": [ - "14c5de1adf55ba0016ab9985776c568e49f5956d", + "682fd0ac8f6a22006e015c2f9b621da84fe53e04", [ null, {} ] ], "request-video-frame-callback-repeating.html": [ - "e637a0872cb0d0c151e0a80a6a569449fd222a1b", + "38e4abafd4afe963232ec7427afa5cbd57bc734d", [ null, {} @@ -500084,7 +500108,7 @@ ] ], "request-video-frame-callback.html": [ - "a4404143fa408ebbb8f49cc3180e065d200ffa4a", + "256216e8fc098482baf267d95fc5f2ceca430c53", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/hit-test-transformed.html b/third_party/blink/web_tests/external/wpt/css/css-break/hit-test-transformed.html new file mode 100644 index 0000000..99365c9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/hit-test-transformed.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<link rel="help" href="https://www.w3.org/TR/css-break-3/#transforms"> +<style> + body { margin: 0; } + *:hover { background: lime !important; } +</style> +<div id="multicol" style="columns:4; column-gap:0; column-fill:auto; width:400px; height:100px; background: yellow"> + <div id="before" style="height: 50px; background: gray"></div> + <div id="transform" style="transform: translateY(20px)"> + <div id="target1" style="height: 100px; background: green"></div> + <div id="target2" style="height: 200px; background: blue"></div> + </div> + <div id="after" style="height: 50px; background: gray"></div> +</div> +<div id="log" style="margin-top:100px;"></div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + test(()=> { assert_equals(document.elementFromPoint(50, 40), before); }, "before"); + test(()=> { assert_equals(document.elementFromPoint(50, 60), multicol); }, "between before and transform"); + test(()=> { assert_equals(document.elementFromPoint(50, 80), target1); }, "target1"); + test(()=> { assert_equals(document.elementFromPoint(50, 110), target1); }, "target1 overflow"); + test(()=> { assert_equals(document.elementFromPoint(150, 10), multicol); }, "top gap in column 2"); + test(()=> { assert_equals(document.elementFromPoint(150, 30), target1); }, "target1 in column 2 top"); + test(()=> { assert_equals(document.elementFromPoint(150, 60), target1); }, "target1 in column 2 bottom"); + test(()=> { assert_equals(document.elementFromPoint(150, 80), target2); }, "target2 in column 2"); + test(()=> { assert_equals(document.elementFromPoint(150, 110), target2); }, "target2 in column 2 overflow"); + test(()=> { assert_equals(document.elementFromPoint(250, 10), multicol); }, "top gap in column 3"); + test(()=> { assert_equals(document.elementFromPoint(250, 30), target2); }, "target2 in column 3 top"); + test(()=> { assert_equals(document.elementFromPoint(250, 110), target2); }, "target2 in column 3 bottom"); + test(()=> { assert_equals(document.elementFromPoint(350, 10), multicol); }, "top gap in column 4"); + test(()=> { assert_equals(document.elementFromPoint(350, 30), target2); }, "target2 in column 4 top"); + test(()=> { assert_equals(document.elementFromPoint(350, 60), target2); }, "target2 in column 4 bottom"); + test(()=> { assert_equals(document.elementFromPoint(350, 80), after); }, "after"); + test(()=> { assert_equals(document.elementFromPoint(350, 110), document.documentElement); }, "below"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/cross-origin-top-navigation-with-user-activation-in-parent.window.js b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/cross-origin-top-navigation-with-user-activation-in-parent.window.js new file mode 100644 index 0000000..8dbe667 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/cross-origin-top-navigation-with-user-activation-in-parent.window.js
@@ -0,0 +1,11 @@ +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.js + +async_test(t => { + addEventListener('message', t.step_func_done(e => { + assert_equals(e.data, 'Denied'); + })); + const w = open("resources/page-with-top-navigating-iframe.html?parent_user_gesture=true"); + t.add_cleanup(() => {w.close()}); + +}, "Cross-origin top navigation is blocked without user activation, even if the parent has user activation");
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/cross-origin-top-navigation-without-user-activation.window.js b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/cross-origin-top-navigation-without-user-activation.window.js new file mode 100644 index 0000000..bd7140f4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/cross-origin-top-navigation-without-user-activation.window.js
@@ -0,0 +1,11 @@ +// META: script=/resources/testharness.js +// META: script=/resources/testharnessreport.js + +async_test(t => { + addEventListener('message', t.step_func_done(e => { + assert_equals(e.data, 'Denied'); + })); + const w = open("resources/page-with-top-navigating-iframe.html"); + t.add_cleanup(() => {w.close()}); + +}, "Cross-origin top navigation is blocked without user activation");
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/resources/page-that-post-message-to-opener.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/resources/page-that-post-message-to-opener.html new file mode 100644 index 0000000..65a0c82 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/resources/page-that-post-message-to-opener.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Page that postMessage to its opener</title> +<script> + opener.postMessage('Allowed', '*'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/resources/page-with-top-navigating-iframe.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/resources/page-with-top-navigating-iframe.html new file mode 100644 index 0000000..568e442 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/resources/page-with-top-navigating-iframe.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src=/common/get-host-info.sub.js></script> +<script src=/resources/testdriver.js></script> +<script src=/resources/testdriver-vendor.js></script> +<title>Page that embeds an iframe that navigates its top</title> +<script> +function addIframe() { + const iframe = document.createElement('iframe'); + const path = new URL("top-navigating-page.html", window.location).pathname; + iframe.src = get_host_info().HTTP_NOTSAMESITE_ORIGIN + path; + document.body.appendChild(iframe); +} + +addEventListener('load', () => { + const urlParams = new URLSearchParams(location.search); + const parentUserGesture = urlParams.get('parent_user_gesture') === 'true'; + if (parentUserGesture) + test_driver.bless("Giving parent frame user activation").then(addIframe); + else + addIframe(); +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/resources/top-navigating-page.html b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/resources/top-navigating-page.html new file mode 100644 index 0000000..557f408 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/navigating-across-documents/resources/top-navigating-page.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Page that navigates its top</title> +<script src=/common/get-host-info.sub.js></script> +<script> + +let path = new URL("page-that-post-message-to-opener.html", window.location).pathname; +let fullUrl = get_host_info().HTTP_NOTSAMESITE_ORIGIN + path; +try { + top.location = fullUrl; +} catch { + top.opener.postMessage('Denied', '*'); +} + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/historical/coep-navigate-popup-unsafe-inherit.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/historical/coep-navigate-popup-unsafe-inherit.https.html index 21feef73..8756cb6 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/historical/coep-navigate-popup-unsafe-inherit.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/historical/coep-navigate-popup-unsafe-inherit.https.html
@@ -1,10 +1,15 @@ <!doctype html> <title>Historical: Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy: a navigating popup</title> <meta name=timeout content=long> +<meta name=variant content=?0-0> +<meta name=variant content=?1-1> +<meta name=variant content=?2-2> +<meta name=variant content=?3-3> <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> <script src="/common/get-host-info.sub.js"></script> <script src="../resources/common.js"></script> +<script src="/common/subset-tests.js"></script> <script> [ { @@ -19,8 +24,13 @@ "coep": "", "opener": false } -].forEach(variant => { - ["same-origin", "same-site"].forEach(site => { +].forEach((variant, i) => { + ["same-origin", "same-site"].forEach((site, j) => { + + // Only run specified variants + if (!shouldRunSubTest(2*i + j)) { + return; + } const title = `Popup navigating to ${site} with ${variant.title}`; const channel = title.replace(/ /g,"-"); const navigateHost = site === "same-origin" ? SAME_ORIGIN : SAME_SITE;
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/transform-dynamic-change-ref.html b/third_party/blink/web_tests/external/wpt/svg/text/reftests/transform-dynamic-change-ref.html new file mode 100644 index 0000000..c7e238d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/transform-dynamic-change-ref.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> +<body> +<div style="position:absolute; transform-origin: 0px 0px; transform: matrix(0.9, 0, 0, 0.9, -210, -777);"> + <svg width="2384" height="1684" style="position:absolute; left:0; top:0;"> + <circle cx="475" cy="975" r="40" stroke="black" stroke-width="2" fill="none" /> + <text fill="red" style="font-size: 40px;" transform="matrix(1, 0, 0, 1, 468, 988)">A</text> + </svg> +</div> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/transform-dynamic-change.html b/third_party/blink/web_tests/external/wpt/svg/text/reftests/transform-dynamic-change.html new file mode 100644 index 0000000..964a7d31 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/transform-dynamic-change.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1270713"> +<link rel="match" href="transform-dynamic-change-ref.html"> +<body> + +<div id="moveme" style="position:absolute; transform-origin: 0px 0px; transform: matrix(0.3, 0, 0, 0.3, 136, 13);"> + <svg width="2384" height="1684" style="position:absolute; left:0; top:0;"> + <circle cx="475" cy="975" r="40" stroke="black" stroke-width="2" fill="none" /> + <text id="txt" style="font-size: 40px;" transform="matrix(1, 0, 0, 1, 468, 988)">A</text> + </svg> +</div> + +<script> +requestAnimationFrame(() => { + requestAnimationFrame(() => { + document.getElementById('moveme').style.transform = 'matrix(0.9, 0, 0, 0.9, -210, -777)'; + document.getElementById('txt').style.fill = 'red'; + document.documentElement.classList.remove('reftest-wait'); + }); +}); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-dom.html b/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-dom.html index 0277d72..c1804b4 100644 --- a/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-dom.html +++ b/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-dom.html
@@ -13,17 +13,24 @@ width: 320, } -async_test(function(t) { +promise_test(async function(t) { + let done; + const promise = new Promise(resolve => done = resolve); + let video = document.createElement('video'); - video.requestVideoFrameCallback(t.step_func_done()); + video.requestVideoFrameCallback(done); video.src = testVideo.url; - video.play(); + await video.play(); + return promise; }, 'Test a video outside of the DOM can still use video.rVFC.'); function rvfcStyleTest(applyStyle, description) { - async_test(function(t) { + promise_test(async function(t) { + let done; + const promise = new Promise(resolve => done = resolve); + let video = document.createElement('video'); document.body.appendChild(video); applyStyle(video); @@ -31,12 +38,14 @@ video.requestVideoFrameCallback( t.step_func( _ => { // Make sure we can receive more than one callback. - video.requestVideoFrameCallback(t.step_func_done()); + video.requestVideoFrameCallback(done); }) ); video.src = testVideo.url; - video.play(); + await video.play(); + + return promise; }, description); }
diff --git a/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-parallel.html b/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-parallel.html index 14c5de1..682fd0a 100644 --- a/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-parallel.html +++ b/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-parallel.html
@@ -7,7 +7,10 @@ <script src="/common/media.js"></script> <script> -async_test(function(t) { +promise_test(async function(t) { + let done; + const promise = new Promise(resolve => done = resolve); + let video = document.createElement('video'); document.body.appendChild(video); @@ -19,17 +22,22 @@ firstMetadata = metadata; })); - video.requestVideoFrameCallback(t.step_func_done((time, metadata) => { + video.requestVideoFrameCallback(t.step_func((time, metadata) => { assert_equals(firstTime, time); assert_object_equals(firstMetadata, metadata); + done(); })); video.src = getVideoURI('/media/movie_5'); video.play(); + return promise; }, 'Test callbacks get the same information.'); -async_test(function(t) { +promise_test(async function(t) { + let done; + const promise = new Promise(resolve => done = resolve); + let video = document.createElement('video'); document.body.appendChild(video); @@ -46,12 +54,12 @@ ); // NOTE: This callback should be executed last. - video.requestVideoFrameCallback( - t.step_func_done() - ); + video.requestVideoFrameCallback(done); video.src = getVideoURI('/media/movie_5'); video.play(); + + return promise; }, 'Test we can cancel callbacks from callbacks.'); </script> </html>
diff --git a/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-repeating.html b/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-repeating.html index e637a08..38e4aba 100644 --- a/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-repeating.html +++ b/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback-repeating.html
@@ -7,7 +7,10 @@ <script src="/common/media.js"></script> <script> -async_test(function(t) { +promise_test(async function(t) { + let done; + const promise = new Promise(resolve => done = resolve); + let video = document.createElement('video'); document.body.appendChild(video); @@ -24,18 +27,23 @@ // Queue up a second callback, and make sure it's called at the same time // as the one we just queued up. - video.requestVideoFrameCallback(t.step_func_done((time) => { + video.requestVideoFrameCallback(t.step_func((time) => { assert_equals(time, secondTime, "Callbacks queued together should be called at the same time"); + done(); })) })); video.src = getVideoURI('/media/movie_5'); - video.play(); + await video.play(); + return promise; }, 'Test new callbacks are only called on the next frame.'); -async_test(function(t) { +promise_test(async function(t) { + let done; + const promise = new Promise(resolve => done = resolve); + let video = document.createElement('video'); document.body.appendChild(video); @@ -64,7 +72,7 @@ lastMetadata = metadata; if (++currentCallNumber > maxNumberOfCalls) { - t.done() + done() } else { video.requestVideoFrameCallback(t.step_func(repeatingCallback)); } @@ -73,8 +81,9 @@ video.requestVideoFrameCallback(t.step_func(repeatingCallback)); video.src = getVideoURI('/media/movie_5'); - video.play(); + await video.play(); + return promise; }, 'Test chaining calls to video.rVFC, and verify the required parameters.'); </script> </html>
diff --git a/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback.html b/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback.html index a4404143..256216e 100644 --- a/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback.html +++ b/third_party/blink/web_tests/external/wpt/video-rvfc/request-video-frame-callback.html
@@ -18,26 +18,34 @@ width: 320, } -async_test(function(t) { +promise_test(async function(t) { + let done; + const promise = new Promise(resolve => done = resolve); + let video = document.createElement('video'); document.body.appendChild(video); let id = video.requestVideoFrameCallback( - t.step_func_done((time, metadata) => { + t.step_func((time, metadata) => { assert_true(time > 0); assert_equals(metadata.height, testVideo.height); assert_equals(metadata.width, testVideo.width); + done(); }) ); assert_true(id > 0); video.src = testVideo.url; - video.play(); + await video.play(); + return promise; }, 'Test we can register a video.rVFC callback.'); -async_test(function(t) { +promise_test(async function(t) { + let done; + const promise = new Promise(resolve => done = resolve); + let video = document.createElement('video'); document.body.appendChild(video); @@ -45,19 +53,24 @@ t.step_func(video_now => { // Queue a call to window.rAF, and make sure it is executed within the // same turn of the event loop (with the same 'time' parameter). - window.requestAnimationFrame( t.step_func_done( window_now => { + window.requestAnimationFrame( t.step_func( window_now => { assert_equals(video_now, window_now); + done(); })); }) ); video.src = testVideo.url; - video.play(); + await video.play(); + return promise; }, 'Test video.rVFC callbacks run before window.rAF callbacks.'); -async_test(function(t) { +promise_test(async function(t) { + let done; + const promise = new Promise(resolve => done = resolve); + let video = document.createElement('video'); document.body.appendChild(video); @@ -74,12 +87,14 @@ // At this point, the other callback shouldn't have fired, but // give it some more time and really make sure it doesn't, by going // throught the event loop once more. - t.step_timeout(() => { t.done(); }, 0); + t.step_timeout(() => { done(); }, 0); }) ); video.src = testVideo.url; - video.play(); + await video.play(); + + return promise; }, 'Test we can cancel a video.rVFC request.'); test(function(t) { @@ -105,6 +120,7 @@ promise_test(async function(t) { let video = document.createElement('video'); + video.autoplay = true; document.body.appendChild(video); let first_width = 0;
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/text-antialias/colrv1-samples-visual-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/text-antialias/colrv1-samples-visual-expected.png new file mode 100644 index 0000000..000c60e --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/text-antialias/colrv1-samples-visual-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-a11y-test-expected.txt b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-a11y-test-expected.txt deleted file mode 100644 index 41fdf3b..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-a11y-test-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -Tests accessibility in the console using the axe-core linter. -aXe violations: [] - -
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-a11y-test.js b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-a11y-test.js deleted file mode 100644 index 0ac4fce..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-a11y-test.js +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - await TestRunner.loadTestModule('axe_core_test_runner'); - TestRunner.addResult( - 'Tests accessibility in the console using the axe-core linter.'); - - await UI.viewManager.showView('console'); - const widget = await UI.viewManager.view('console').widget(); - - await AxeCoreTestRunner.runValidation(widget.element); - TestRunner.completeTest(); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-error-a11y-test-expected.txt b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-error-a11y-test-expected.txt deleted file mode 100644 index d4398902..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-error-a11y-test-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -Tests accessibility of console containing an error message using the axe-core linter. -invalidVar123 -VM:1 Uncaught ReferenceError: invalidVar123 is not defined - at <anonymous>:1:1 -(anonymous) @ VM:1 -aXe violations: [] - -
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-error-a11y-test.js b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-error-a11y-test.js deleted file mode 100644 index 3297c72..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console/console-error-a11y-test.js +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - await TestRunner.loadTestModule('axe_core_test_runner'); - TestRunner.addResult( - 'Tests accessibility of console containing an error message using the axe-core linter.'); - - await TestRunner.loadLegacyModule('console'); await TestRunner.loadTestModule('console_test_runner'); - await TestRunner.showPanel('console'); - const widget = await UI.viewManager.view('console').widget(); - - async function callback() { - ConsoleTestRunner.dumpConsoleMessages(); - await AxeCoreTestRunner.runValidation(widget.element); - TestRunner.completeTest(); - } - - ConsoleTestRunner.evaluateInConsole('invalidVar123', callback); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/argument-hints-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/argument-hints-expected.txt deleted file mode 100644 index 49ba4e1..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/argument-hints-expected.txt +++ /dev/null
@@ -1,113 +0,0 @@ -Tests function argument hints. - -open( -?url,?target,?features - -Math.log( -x - -console.log(1, -...data - -const process = window.setTimeout( -callback,ms,...args - -document.body.addEventListener( -type,listener,?options - -boundAddClickListener(x => x, -listener,?options - -userFunctionWithDestructuring( -obj,arr - -originalFunction(a,b,c,d,e,f,g, -a,b,c,...more - -secondFunction( -b,c,...more - -thirdFunction( -c,...more - -fourthFunction( -...more - -fifthFunction( -...more - -aLotBound( -...more - -boundMathLog( -x - -CSS.supports( -null - -Uint8Array.from( -arrayLike,?mapfn,?thisArg - -ctx.drawImage(image, x, y, -image,x,y,?width,?height -image,sx,sy,sw,sh,dx,dy,dw,dh - -window.open(document.getElementsByName(|)); -elementName - -window.open(|document.getElementsByName()); -?url,?target,?features - -"asdf".indexOf( -searchString,?position - -[].indexOf( -searchElement,?fromIndex - -new Thing( -initialValue - -(new Thing).setT( -t - -(x => x)( -x - -(function(y){})( -y - -Thing.myStaticMethod( -a,b,c - -aString.toString( -null - -aNumber.toString( -?radix - -[1,2,3].splice( -start,?deleteCount,...items - -URL.createObjectURL( -blob -source - -(() => window)().URL["revokeObjectURL"]( -url - -var notInAfunction -null - -some gibberish $@#)(*^@# -null - -Date.parse( -s - -JSON.parse( -text,?reviver - -CSSNumericValue.parse( -cssText - -
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/argument-hints.js b/third_party/blink/web_tests/http/tests/devtools/console/argument-hints.js deleted file mode 100644 index 27f4341e..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/argument-hints.js +++ /dev/null
@@ -1,129 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - TestRunner.addResult(`Tests function argument hints.\n`); - - await TestRunner.loadLegacyModule('console'); await TestRunner.loadTestModule('console_test_runner'); - await TestRunner.showPanel('console'); - - await TestRunner.evaluateInPagePromise(` - const boundAddClickListener = document.addEventListener.bind(document, 'click'); - function userFunctionWithDefault(required, notRequired = 5) { - - } - - function userFunctionWithDestructuring({something1}, [sommething2, something3]) { - - } - - function originalFunction(a,b,c,...more) { - - } - - const secondFunction = originalFunction.bind(null, 'a'); - const thirdFunction = secondFunction.bind(null, 'b'); - const fourthFunction = thirdFunction.bind(null, 'c'); - const fifthFunction = fourthFunction.bind(null, 'more'); - const aLotBound = originalFunction.bind(null, 'a','b','c','d','e','f'); - - const ctx = document.createElement('canvas').getContext('2d'); - const boundMathLog = Math.log.bind(Math); - - class Thing { - constructor(initialValue) { - - } - - static myStaticMethod(a,b,c) { - - } - - setT(t) { - - } - } - - const aString = "aString"; - const aNumber = 4; - `); - const consoleEditor = await ConsoleTestRunner.waitUntilConsoleEditorLoaded(); - await testHints('open('); - await testHints('Math.log('); - await testHints('console.log(1,'); - await testHints('const process = window.setTimeout('); - await testHints('document.body.addEventListener('); - await testHints('boundAddClickListener(x => x,'); - await testHints('userFunctionWithDestructuring('); - await testHints('originalFunction(a,b,c,d,e,f,g,'); - await testHints('secondFunction('); - await testHints('thirdFunction('); - await testHints('fourthFunction('); - await testHints('fifthFunction('); - await testHints('aLotBound('); - await testHints('boundMathLog('); - await testHints('CSS.supports('); - await testHints('Uint8Array.from('); - await testHints('ctx.drawImage(image, x, y,'); - await testHints('window.open(document.getElementsByName(|));'); - await testHints('window.open(|document.getElementsByName());'); - await testHints('"asdf".indexOf('); - await testHints('[].indexOf('); - await testHints('new Thing('); - await testHints('(new Thing).setT('); - await testHints('(x => x)('); - await testHints('(function(y){})('); - await testHints('Thing.myStaticMethod('); - await testHints('aString.toString('); - await testHints('aNumber.toString('); - await testHints('[1,2,3].splice('); - await testHints('URL.createObjectURL('); - await testHints('(() => window)().URL["revokeObjectURL"]('); - await testHints('var notInAfunction'); - await testHints('some gibberish $@#)(*^@#'); - await testHints('Date.parse('); - await testHints('JSON.parse('); - await testHints('CSSNumericValue.parse('); - TestRunner.completeTest(); - - /** - * @param {string} text - * @param {!Array<string>} expected - */ - async function testHints(text, expected) { - var cursorPosition = text.indexOf('|'); - - if (cursorPosition < 0) - cursorPosition = Infinity; - - consoleEditor.setText(text.replace('|', '')); - consoleEditor.setSelection( - TextUtils.TextRange.createFromLocation(0, cursorPosition)); - const signaturesPromise = new Promise( - x => TestRunner.addSniffer( - ObjectUI.javaScriptAutocomplete, 'argumentsHint', - (text, retVal) => x(retVal))); - consoleEditor.autocompleteController.onCursorActivity(); - var message = 'Checking \'' + +'\''; - - const signatures = await signaturesPromise; - TestRunner.addResult(`${ - text.replace('\n', '\\n').replace('\r', '\\r') - }\n${printSignatures()}`); - TestRunner.addResult(''); - function printSignatures() { - if (!signatures) - return 'null'; - return signatures.args - .map(args => { - return args - .map((arg, index) => { - return arg; - }) - .join(','); - }) - .join('\n') - } - } -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-focus-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-focus-expected.txt deleted file mode 100644 index be43b83e..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-focus-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -Tests that interacting with the console gives appropriate focus. - -Message count: 2 - -Running: testClickingWithSelectedTextShouldNotFocusPrompt -Prompt has focus: false -Viewport scrolled to top: true -Clicking message 0 -Prompt has focus: false -Viewport scrolled to top: true - -Running: testKeypressWithFocusedMessageShouldFocusPrompt -Prompt has focus: false -Viewport scrolled to top: true -Clicking message 0 -Prompt has focus: true -Viewport scrolled to top: false - -Running: testClickOutsideMessageListShouldFocusPromptAndMoveCaretToEnd -Prompt has focus: false -Viewport scrolled to top: true -Selection before: {"startLine":0,"startColumn":1,"endLine":0,"endColumn":1} -Clicking on container -Prompt has focus: true -Viewport scrolled to top: false -Selection after: {"startLine":0,"startColumn":6,"endLine":0,"endColumn":6} -
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-focus.js b/third_party/blink/web_tests/http/tests/devtools/console/console-focus.js deleted file mode 100644 index 3e47d443f..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-focus.js +++ /dev/null
@@ -1,94 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - TestRunner.addResult(`Tests that interacting with the console gives appropriate focus.\n`); - - await TestRunner.loadLegacyModule('console'); await TestRunner.loadTestModule('console_test_runner'); - await TestRunner.showPanel('console'); - - var consoleView = Console.ConsoleView.instance(); - var viewport = consoleView.viewport; - var prompt = consoleView.prompt; - var consoleEditor; - ConsoleTestRunner.waitUntilConsoleEditorLoaded().then(e => consoleEditor = e).then(logMessages); - - // Ensure that the body is focusable. - document.body.tabIndex = -1; - function resetAndDumpFocusAndScrollTop() { - document.body.focus(); - viewport.element.scrollTop = 0; - dumpFocusAndScrollInfo(); - } - - function logMessages() { - ConsoleTestRunner.waitForConsoleMessages(2, async () => { - await ConsoleTestRunner.waitForPendingViewportUpdates(); - TestRunner.runTestSuite(testSuite); - }); - ConsoleTestRunner.evaluateInConsole( - '\'foo ' + - '\n'.repeat(50) + 'bar\''); - } - - var testSuite = [ - function testClickingWithSelectedTextShouldNotFocusPrompt(next) { - resetAndDumpFocusAndScrollTop(); - - // Make a selection. - var messageElement = consoleView.itemElement(0).element(); - var firstTextNode = messageElement.traverseNextTextNode(); - window.getSelection().setBaseAndExtent(firstTextNode, 0, firstTextNode, 1); - - focusMessage(0); - dumpFocusAndScrollInfo(); - window.getSelection().removeAllRanges(); - next(); - }, - - function testKeypressWithFocusedMessageShouldFocusPrompt(next) { - resetAndDumpFocusAndScrollTop(); - - focusMessage(0); - - eventSender.keyDown('A'); - dumpFocusAndScrollInfo(); - next(); - }, - - function testClickOutsideMessageListShouldFocusPromptAndMoveCaretToEnd(next) { - prompt.setText('foobar'); - consoleEditor.setSelection(TextUtils.TextRange.createFromLocation(0, 1)); - resetAndDumpFocusAndScrollTop(); - TestRunner.addResult('Selection before: ' + consoleEditor.selection().toString()); - - TestRunner.addResult('Clicking on container'); - consoleView.messagesElement.click(); - - dumpFocusAndScrollInfo(); - TestRunner.addResult('Selection after: ' + consoleEditor.selection().toString()); - next(); - } - ]; - - function focusMessage(index) { - var previewElement = consoleView.visibleViewMessages[index].element().querySelector('.source-code'); - var previewRect = previewElement.getBoundingClientRect(); - var clientX = previewRect.left + previewRect.width / 2; - var clientY = previewRect.top + previewRect.height / 2; - - TestRunner.addResult('Clicking message ' + index); - previewElement.dispatchEvent(new MouseEvent('click', {clientX: clientX, clientY: clientY, bubbles: true})); - consoleView.visibleViewMessages[index].element().focus(); - } - - function dumpFocusAndScrollInfo() { - var focusedElement = document.deepActiveElement(); - if (focusedElement) - TestRunner.addResult('Prompt has focus: ' + consoleView.prompt.hasFocus()); - else - TestRunner.addResult('No focus'); - TestRunner.addResult('Viewport scrolled to top: ' + String(viewport.element.scrollTop === 0)); - } -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-prompt-keyboard-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-prompt-keyboard-expected.txt deleted file mode 100644 index 5456d37..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-prompt-keyboard-expected.txt +++ /dev/null
@@ -1,39 +0,0 @@ -Tests that console prompt keyboard events work. - -Adding first message: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb -Setting prompt text: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy - -Test that arrow Up stays in the same command -{"startLine":1,"startColumn":0,"endLine":1,"endColumn":0} -Prompt is displaying SECOND message - -Test that ArrowUp+shift stays in the same command -{"startLine":0,"startColumn":0,"endLine":0,"endColumn":1} -Prompt is displaying SECOND message - -Test that arrow Up on the first line, second visual row stays in the same command -{"startLine":0,"startColumn":100,"endLine":0,"endColumn":100} -Prompt is displaying SECOND message - -Test that arrow Up from the first line loads previous command -{"startLine":0,"startColumn":0,"endLine":0,"endColumn":0} -Prompt is displaying FIRST message - -Test that arrow Down stays in the same command -{"startLine":0,"startColumn":0,"endLine":0,"endColumn":0} -Prompt is displaying FIRST message - -Test that ArrowDown+shift stays in the same command -{"startLine":1,"startColumn":0,"endLine":1,"endColumn":1} -Prompt is displaying FIRST message - -Test that arrow Down on the last line, first visual row stays in the same command -{"startLine":1,"startColumn":0,"endLine":1,"endColumn":0} -Prompt is displaying FIRST message - -Test that arrow Down from the first line loads next command -{"startLine":1,"startColumn":100,"endLine":1,"endColumn":100} -Prompt is displaying SECOND message -
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-prompt-keyboard.js b/third_party/blink/web_tests/http/tests/devtools/console/console-prompt-keyboard.js deleted file mode 100644 index 907c8f5..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-prompt-keyboard.js +++ /dev/null
@@ -1,109 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - TestRunner.addResult('Tests that console prompt keyboard events work.\n'); - - await TestRunner.loadLegacyModule('console'); await TestRunner.loadTestModule('console_test_runner'); - await TestRunner.showPanel('console'); - await ConsoleTestRunner.waitUntilConsoleEditorLoaded(); - // Make sure that `singleLineCharCount` wraps onto multiple lines. - var singleLineCharCount = 100; - ConsoleTestRunner.fixConsoleViewportDimensions(300, 200); - - var firstCommand = 'a'.repeat(singleLineCharCount) + '\n' + 'b'.repeat(singleLineCharCount); - TestRunner.addResult('Adding first message: ' + firstCommand); - await ConsoleTestRunner.evaluateInConsolePromise(firstCommand); - - var secondCommand = 'x'.repeat(singleLineCharCount) + '\n' + 'y'.repeat(singleLineCharCount); - TestRunner.addResult('Setting prompt text: ' + secondCommand); - var prompt = Console.ConsoleView.instance().prompt; - prompt.setText(secondCommand); - - TestRunner.addResult('\nTest that arrow Up stays in the same command'); - prompt.editor.setSelection(TextUtils.TextRange.createFromLocation(1, 0)); - dumpSelection(); - sendKeyUpToPrompt(); - printSelectedCommand(); - - TestRunner.addResult('\nTest that ArrowUp+shift stays in the same command'); - prompt.editor.setSelection(new TextUtils.TextRange(0, 0, 0, 1)); - dumpSelection(); - sendKeyUpToPrompt(true); - printSelectedCommand(); - - TestRunner.addResult('\nTest that arrow Up on the first line, second visual row stays in the same command'); - prompt.editor.setSelection(TextUtils.TextRange.createFromLocation(0, singleLineCharCount)); - dumpSelection(); - sendKeyUpToPrompt(); - printSelectedCommand(); - - TestRunner.addResult('\nTest that arrow Up from the first line loads previous command'); - prompt.editor.setSelection(TextUtils.TextRange.createFromLocation(0, 0)); - dumpSelection(); - sendKeyUpToPrompt(); - printSelectedCommand(); - - - TestRunner.addResult('\nTest that arrow Down stays in the same command'); - prompt.editor.setSelection(TextUtils.TextRange.createFromLocation(0, 0)); - dumpSelection(); - sendKeyDownToPrompt(); - printSelectedCommand(); - - TestRunner.addResult('\nTest that ArrowDown+shift stays in the same command'); - prompt.editor.setSelection(new TextUtils.TextRange(1, 0, 1, 1)); - dumpSelection(); - sendKeyDownToPrompt(true); - printSelectedCommand(); - - TestRunner.addResult('\nTest that arrow Down on the last line, first visual row stays in the same command'); - prompt.editor.setSelection(TextUtils.TextRange.createFromLocation(1, 0)); - dumpSelection(); - sendKeyDownToPrompt(); - printSelectedCommand(); - - TestRunner.addResult('\nTest that arrow Down from the first line loads next command'); - prompt.editor.setSelection(TextUtils.TextRange.createFromLocation(1, singleLineCharCount)); - dumpSelection(); - sendKeyDownToPrompt(); - printSelectedCommand(); - - TestRunner.completeTest(); - - function printSelectedCommand() { - if (prompt.text().startsWith('a')) - TestRunner.addResult('Prompt is displaying FIRST message'); - else if (prompt.text().startsWith('x')) - TestRunner.addResult('Prompt is displaying SECOND message'); - else - TestRunner.addResult('TEST FAILURE'); - } - - /** - * @param {boolean} shiftKey - */ - function sendKeyUpToPrompt(shiftKey) { - prompt.editor.element.focus(); - if (shiftKey) - eventSender.keyDown('ArrowUp', ['shiftKey']); - else - eventSender.keyDown('ArrowUp'); - } - - /** - * @param {boolean} shiftKey - */ - function sendKeyDownToPrompt(shiftKey) { - prompt.editor.element.focus(); - if (shiftKey) - eventSender.keyDown('ArrowDown', ['shiftKey']); - else - eventSender.keyDown('ArrowDown'); - } - - function dumpSelection() { - TestRunner.addResult(JSON.stringify(prompt.editor.selection())); - } -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-retain-autocomplete-on-typing-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-retain-autocomplete-on-typing-expected.txt deleted file mode 100644 index bb1ad6b..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-retain-autocomplete-on-typing-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -Verify that console does not hide autocomplete during typing. - - -Running: testSummonSuggestBox -Suggestions shown. - -Running: testTypeText -SUCCESS: suggestbox is not hidden during typing. -
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-retain-autocomplete-on-typing.js b/third_party/blink/web_tests/http/tests/devtools/console/console-retain-autocomplete-on-typing.js deleted file mode 100644 index 9dd3a6d..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-retain-autocomplete-on-typing.js +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - TestRunner.addResult(`Verify that console does not hide autocomplete during typing.\n`); - await TestRunner.loadLegacyModule('console'); await TestRunner.loadTestModule('console_test_runner'); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); - await TestRunner.loadLegacyModule('text_editor'); - await TestRunner.showPanel('console'); - await TestRunner.evaluateInPagePromise(` - window.foobar = "foobar"; - window.foobaz = "foobaz"; - `); - - ConsoleTestRunner.waitUntilConsoleEditorLoaded().then(onConsoleEditorLoaded); - - var consoleEditor; - function onConsoleEditorLoaded(editor) { - consoleEditor = editor; - TestRunner.runTestSuite(testSuite); - } - - var testSuite = [ - function testSummonSuggestBox(next) { - TestRunner.addSniffer( - TextEditor.TextEditorAutocompleteController.prototype, 'onSuggestionsShownForTest', onSuggestionsShown); - SourcesTestRunner.typeIn(consoleEditor, 'f'); - - function onSuggestionsShown() { - TestRunner.addResult('Suggestions shown.'); - next(); - } - }, - - function testTypeText(next) { - TestRunner.addSniffer( - TextEditor.TextEditorAutocompleteController.prototype, 'onSuggestionsHiddenForTest', onSuggestionsHidden); - TestRunner.addSniffer( - TextEditor.TextEditorAutocompleteController.prototype, 'onCursorActivityHandledForTest', - onCursorActivityHandled); - SourcesTestRunner.typeIn(consoleEditor, 'o'); - - var activityHandled = false; - - function onSuggestionsHidden() { - if (activityHandled) - return; - TestRunner.addResult('FAIL: suggestbox is hidden during typing.'); - TestRunner.completeTest(); - } - - function onCursorActivityHandled() { - TestRunner.addResult('SUCCESS: suggestbox is not hidden during typing.'); - activityHandled = true; - next(); - } - } - ]; -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-smart-enter-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-smart-enter-expected.txt deleted file mode 100644 index 6001ba2..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-smart-enter-expected.txt +++ /dev/null
@@ -1,128 +0,0 @@ -Tests that the console enters a newline instead of running a command if the command is incomplete. - -Text Before Enter: -window -Text After Enter: -<empty> - -Text Before Enter: -window. -Text After Enter: -window. - - -Text Before Enter: -if.(1.===.2) -Text After Enter: -if.(1.===.2) -.... - -Text Before Enter: -if.(1.===.2).{ -Text After Enter: -if.(1.===.2).{ -.... - -Text Before Enter: -if.(1.===.2).{} -Text After Enter: -<empty> - -Text Before Enter: -[1,2, -Text After Enter: -[1,2, -. - -Text Before Enter: -[1,2,3] -Text After Enter: -<empty> - -Text Before Enter: -{abc: -Text After Enter: -{abc: -. - -Text Before Enter: -{abc:123} -Text After Enter: -<empty> - -Text Before Enter: -function.incomplete().{ -....if.(1) -........5; -Text After Enter: -function.incomplete().{ -....if.(1) -........5; -.... - -Text Before Enter: -function.bad().{ -....if.(1) -} -Text After Enter: -<empty> - -Text Before Enter: -function.good().{ -....if.(1).{ -........5; -....} -} -Text After Enter: -<empty> - -Text Before Enter: -1, -Text After Enter: -1, -.... - -Text Before Enter: -label: -Text After Enter: -label: - - -Text Before Enter: -for.(var.i.=.0;.i.<.100;.i++) -Text After Enter: -for.(var.i.=.0;.i.<.100;.i++) -.... - -Text Before Enter: -for.(var.i.=.0;.i.<.100;.i++).i -Text After Enter: -<empty> - -Text Before Enter: -var.templateStr.=.` -Text After Enter: -var.templateStr.=.` - - -Text Before Enter: -var.templateStr.=.`str` -Text After Enter: -<empty> - -Text Before Enter: -var.doubleQ.=." -Text After Enter: -<empty> - -Text Before Enter: -var.singleQ.=.' -Text After Enter: -<empty> - -Text Before Enter: -var.singleQ.=.'str' -Text After Enter: -<empty> - -
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-smart-enter.js b/third_party/blink/web_tests/http/tests/devtools/console/console-smart-enter.js deleted file mode 100644 index a71a237..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-smart-enter.js +++ /dev/null
@@ -1,74 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - TestRunner.addResult( - `Tests that the console enters a newline instead of running a command if the command is incomplete.\n`); - await TestRunner.loadLegacyModule('console'); await TestRunner.loadTestModule('console_test_runner'); - await TestRunner.showPanel('console'); - - var prompt = Console.ConsoleView.instance().prompt; - ConsoleTestRunner.waitUntilConsoleEditorLoaded().then(step1); - - function step1() { - sequential([ - () => pressEnterAfter('window'), - () => pressEnterAfter('window.'), - () => pressEnterAfter('if (1 === 2)'), - () => pressEnterAfter('if (1 === 2) {'), - () => pressEnterAfter('if (1 === 2) {}'), - () => pressEnterAfter('[1,2,'), - () => pressEnterAfter('[1,2,3]'), - () => pressEnterAfter('{abc:'), - () => pressEnterAfter('{abc:123}'), - () => pressEnterAfter(`function incomplete() { - if (1) - 5;`), - () => pressEnterAfter(`function bad() { - if (1) -}`), - () => pressEnterAfter(`function good() { - if (1) { - 5; - } -}`), - () => pressEnterAfter('1,'), - () => pressEnterAfter('label:'), - () => pressEnterAfter('for (var i = 0; i < 100; i++)'), - () => pressEnterAfter('for (var i = 0; i < 100; i++) i'), - () => pressEnterAfter('var templateStr = `'), - () => pressEnterAfter('var templateStr = `str`'), - () => pressEnterAfter('var doubleQ = "'), - () => pressEnterAfter('var singleQ = \''), - () => pressEnterAfter('var singleQ = \'str\'') - ]).then(TestRunner.completeTest); - } - - function sequential(tests) { - var promise = Promise.resolve(); - for (var i = 0; i < tests.length; i++) - promise = promise.then(tests[i]); - return promise; - } - - function pressEnterAfter(text) { - var fulfill; - var promise = new Promise(x => fulfill = x); - TestRunner.addSniffer(Console.ConsolePrompt.prototype, 'enterProcessedForTest', enterProcessed); - - prompt.setText(text); - prompt.moveCaretToEndOfPrompt(); - prompt.enterKeyPressed(TestRunner.createKeyEvent('Enter')); - return promise; - - function enterProcessed() { - TestRunner.addResult('Text Before Enter:'); - TestRunner.addResult(text.replace(/ /g, '.')); - TestRunner.addResult('Text After Enter:'); - TestRunner.addResult(prompt.text().replace(/ /g, '.') || '<empty>'); - TestRunner.addResult(''); - fulfill(); - } - } -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-expand-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-expand-expected.txt deleted file mode 100644 index 6dfcc8aa..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-expand-expected.txt +++ /dev/null
@@ -1,322 +0,0 @@ -Tests that console artifacts can be expanded, collapsed via keyboard. - - -Running: testExpandingTraces -Evaluating: console.warn("warning") -Message count: 1 - -Force selecting index 0 -Viewport virtual selection: 0 -Is trace expanded: NO - -ArrowRight: -Viewport virtual selection: 0 -Is trace expanded: YES - -ArrowLeft: -Viewport virtual selection: 0 -Is trace expanded: NO - -Running: testExpandingGroups -Evaluating: console.group("group"); console.log("log child"); -Message count: 2 - -Force selecting index 0 -Viewport virtual selection: 0 -Is group expanded: YES -console-key-expand.js:35 group -console-key-expand.js:35 log child - -ArrowLeft: -Viewport virtual selection: 0 -Is group expanded: NO -console-key-expand.js:35 group - -ArrowRight: -Viewport virtual selection: 0 -Is group expanded: YES -console-key-expand.js:35 group -console-key-expand.js:35 log child - -Running: testNavigateBetweenObjectsAndLogs -Evaluating: console.log("before");console.log("text", obj1, obj2);console.log("after"); -Message count: 3 - -Force selecting index 1 -Viewport virtual selection: 1 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:51 text {x: 1} {y: 2} - -ArrowRight: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {x: 1} - -ArrowDown: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {y: 2} - -ArrowDown: -Viewport virtual selection: 1 -activeElement: SPAN.devtools-link -active text: console-key-expand.js:51 - -ArrowDown: -Viewport virtual selection: 2 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:51 after - -ArrowUp: -Viewport virtual selection: 1 -activeElement: SPAN.devtools-link -active text: console-key-expand.js:51 - -ArrowUp: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {y: 2} - -ArrowLeft: -Viewport virtual selection: 1 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:51 text {x: 1} {y: 2} - -Running: testExpandingObjects -Evaluating: console.log("before");console.log("text", obj1, obj2);console.log("after"); -Message count: 3 - -Force selecting index 1 -Viewport virtual selection: 1 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:74 text {x: 1} {y: 2} - -ArrowRight: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {x: 1} - -ArrowRight: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected.expanded -active text: {x: 1} - -ArrowDown: -Viewport virtual selection: 1 -activeElement: LI.selected -active text: x: 1 - -ArrowDown: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {y: 2} - -ArrowRight: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected.expanded -active text: {y: 2} - -ArrowDown: - -ArrowDown: - -ArrowDown: -Viewport virtual selection: 2 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:74 after - -ArrowUp: - -ArrowUp: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.expanded.selected -active text: {y: 2} - -ArrowLeft: -Viewport virtual selection: 1 -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {y: 2} - -ArrowLeft: -Viewport virtual selection: 1 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:74 text {x: 1}x: 1 {y: 2}y: 2 - -Running: testExpandingObjectInTrace -Evaluating: console.log("before");console.warn("warning", obj1);console.log("after"); -Message count: 3 - -Force selecting index 1 -Viewport virtual selection: 1 -Has object: collapsed -Is trace expanded: NO -activeElement: DIV.console-message-wrapper.console-from-api.console-warning-level.console-selected -active text: console-key-expand.js:117 warning {x: 1} -(anonymous) @ console-key-expand.js:117 - -ArrowRight: -Viewport virtual selection: 1 -Has object: collapsed -Is trace expanded: YES -activeElement: DIV.console-message-wrapper.console-from-api.console-warning-level.console-selected -active text: console-key-expand.js:117 warning {x: 1} -(anonymous) @ console-key-expand.js:117 - -ArrowRight: -Viewport virtual selection: 1 -Has object: collapsed -Is trace expanded: YES -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {x: 1} - -ArrowRight: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: YES -activeElement: LI.parent.object-properties-section-root-element.selected.expanded -active text: {x: 1} - -ArrowDown: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: YES -activeElement: LI.selected -active text: x: 1 - -ArrowDown: - -ArrowDown: - -ArrowDown: -Viewport virtual selection: 2 -Has object: expanded -Is trace expanded: YES -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:117 after - -ArrowUp: - -ArrowUp: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: YES -activeElement: SPAN.devtools-link -active text: console-key-expand.js:117 - -ArrowUp: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: YES -activeElement: LI.parent.object-properties-section-root-element.expanded.selected -active text: {x: 1} - -ArrowUp: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: YES -activeElement: DIV.console-message-wrapper.console-from-api.console-warning-level.console-selected -active text: console-key-expand.js:117 warning {x: 1}x: 1 -(anonymous) @ console-key-expand.js:117 - -ArrowLeft: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: NO -activeElement: DIV.console-message-wrapper.console-from-api.console-warning-level.console-selected -active text: console-key-expand.js:117 warning {x: 1}x: 1 -(anonymous) @ console-key-expand.js:117 - -ArrowLeft: -Viewport virtual selection: 1 -Has object: expanded -Is trace expanded: NO -activeElement: DIV.console-message-wrapper.console-from-api.console-warning-level.console-selected -active text: console-key-expand.js:117 warning {x: 1}x: 1 -(anonymous) @ console-key-expand.js:117 - -Running: testExpandingElement -Evaluating: console.log("before");console.log(el);console.log("after"); -Message count: 3 - -Force selecting index 1 -Viewport virtual selection: 1 -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:167 <div>​…​</div>​ - -ArrowDown: - -ArrowDown: -Viewport virtual selection: 1 -activeElement: LI.parent.selected -active text: <div>​…​</div>​ - -ArrowRight: -Viewport virtual selection: 1 -activeElement: LI.parent.selected.expanded -active text: <div>​ - -Running: testShiftTabShouldSelectLastObject -Evaluating: console.log("before");console.log(obj1); -Message count: 2 -Setting focus in prompt: - -Shift+Tab: - -ArrowUp: -Viewport virtual selection: 1 -Has object: collapsed -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {x: 1} - -ArrowRight: -Viewport virtual selection: 1 -Has object: expanded -activeElement: LI.parent.object-properties-section-root-element.selected.expanded -active text: {x: 1} - -Running: testArrowUpToFirstVisibleMessageShouldSelectLastObject -Evaluating: console.log(obj1);console.log("after"); -Message count: 2 -Setting focus in prompt: - -Shift+Tab: - -ArrowUp: -Viewport virtual selection: 1 -Has object: collapsed -activeElement: DIV.console-message-wrapper.console-from-api.console-info-level.console-selected -active text: console-key-expand.js:199 after - -ArrowUp: - -ArrowUp: -Viewport virtual selection: 0 -Has object: collapsed -activeElement: LI.parent.object-properties-section-root-element.selected -active text: {x: 1} - -Running: testFocusLastChildInBigObjectShouldScrollIntoView -Evaluating: console.log(bigObj); -Message count: 1 -Setting focus in prompt: - -Shift+Tab: - -ArrowUp: - -ArrowRight: - -Tab: -Viewport virtual selection: -1 -Has object: expanded -activeElement: TEXTAREA - -Shift+Tab: - -ArrowUp: -Viewport virtual selection: 0 -Has object: expanded -activeElement: LI.parent.object-properties-section-root-element.expanded.selected -active text: {a0: 0, a1: 1, a2: 2, a3: 3, a4: 4, …} -Is at bottom: false, should stick: false -
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-expand.js b/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-expand.js deleted file mode 100644 index 37c5b0e8..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-expand.js +++ /dev/null
@@ -1,328 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - TestRunner.addResult(`Tests that console artifacts can be expanded, collapsed via keyboard.\n`); - await TestRunner.loadLegacyModule('console'); await TestRunner.loadTestModule('console_test_runner'); - await TestRunner.showPanel('console'); - ConsoleTestRunner.fixConsoleViewportDimensions(600, 200); - await ConsoleTestRunner.waitUntilConsoleEditorLoaded(); - - const consoleView = Console.ConsoleView.instance(); - const viewport = consoleView.viewport; - const prompt = consoleView.prompt; - - await TestRunner.evaluateInPagePromise(` - var obj1 = Object.create(null); - obj1.x = 1; - - var obj2 = Object.create(null); - obj2.y = 2; - `); - - TestRunner.runTestSuite([ - async function testExpandingTraces(next) { - await clearAndLog(`console.warn("warning")`); - forceSelect(0); - - await dumpFocus(); - press('ArrowRight'); - await dumpFocus(); - press('ArrowLeft'); - await dumpFocus(); - - next(); - }, - - async function testExpandingGroups(next) { - await clearAndLog(`console.group("group"); console.log("log child");`, 2); - forceSelect(0); - - await dumpFocus(); - await ConsoleTestRunner.dumpConsoleMessages(); - press('ArrowLeft'); - await dumpFocus(); - await ConsoleTestRunner.dumpConsoleMessages(); - press('ArrowRight'); - await dumpFocus(); - await ConsoleTestRunner.dumpConsoleMessages(); - - next(); - }, - - async function testNavigateBetweenObjectsAndLogs(next) { - await clearAndLog(`console.log("before");console.log("text", obj1, obj2);console.log("after");`, 3); - forceSelect(1); - - await dumpFocus(true, 1, true /* skipObjectCheck */); - press('ArrowRight'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - press('ArrowDown'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - press('ArrowDown'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - press('ArrowDown'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - press('ArrowUp'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - press('ArrowUp'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - press('ArrowLeft'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - - next(); - }, - - // Note: During this test expanded objects - // do not include the __proto__ property. - async function testExpandingObjects(next) { - await clearAndLog(`console.log("before");console.log("text", obj1, obj2);console.log("after");`, 3); - forceSelect(1); - - await dumpFocus(true, 1, true /* skipObjectCheck */); - press('ArrowRight'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - - // Expand obj1. - press('ArrowRight'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - await ConsoleTestRunner.waitForRemoteObjectsConsoleMessagesPromise(); - press('ArrowDown'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - press('ArrowDown'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - - // Expand obj2. - press('ArrowRight'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - await ConsoleTestRunner.waitForRemoteObjectsConsoleMessagesPromise(); - press('ArrowDown'); - press('ArrowDown'); - press('ArrowDown'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - - press('ArrowUp'); - press('ArrowUp'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - - // Collapse object. - press('ArrowLeft'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - - // Select message. - press('ArrowLeft'); - await dumpFocus(true, 1, true /* skipObjectCheck */); - - next(); - }, - - async function testExpandingObjectInTrace(next) { - await clearAndLog(`console.log("before");console.warn("warning", obj1);console.log("after");`, 3); - forceSelect(1); - - await dumpFocus(true, 1); - press('ArrowRight'); - await dumpFocus(true, 1); - press('ArrowRight'); - await dumpFocus(true, 1); - - // Expand object. - press('ArrowRight'); - await dumpFocus(true, 1); - await ConsoleTestRunner.waitForRemoteObjectsConsoleMessagesPromise(); - press('ArrowDown'); - await dumpFocus(true, 1); - press('ArrowDown'); - press('ArrowDown'); - press('ArrowDown'); - await dumpFocus(true, 1); - - press('ArrowUp'); - press('ArrowUp'); - await dumpFocus(true, 1); - press('ArrowUp'); - await dumpFocus(true, 1); - press('ArrowUp'); - await dumpFocus(true, 1); - - // Collapse trace. - press('ArrowLeft'); - await dumpFocus(true, 1); - - // ArrowLeft on message does not collapse object. - press('ArrowLeft'); - await dumpFocus(true, 1); - - next(); - }, - - async function testExpandingElement(next) { - await TestRunner.evaluateInPagePromise(` - var el = document.createElement('div'); - var child = document.createElement('span'); - el.appendChild(child); undefined; - `); - const nodePromise = TestRunner.addSnifferPromise(Console.ConsoleViewMessage.prototype, 'formattedParameterAsNodeForTest'); - await clearAndLog(`console.log("before");console.log(el);console.log("after");`, 3); - await nodePromise; - forceSelect(1); - - await dumpFocus(true, 1); - press('ArrowDown'); - press('ArrowDown'); - await dumpFocus(true, 1); - - // Expand object. - press('ArrowRight'); - await ConsoleTestRunner.waitForRemoteObjectsConsoleMessagesPromise(); - await dumpFocus(true, 1); - - next(); - }, - - async function testShiftTabShouldSelectLastObject(next) { - await clearAndLog(`console.log("before");console.log(obj1);`, 2); - await ConsoleTestRunner.waitForRemoteObjectsConsoleMessagesPromise(); - - TestRunner.addResult(`Setting focus in prompt:`); - prompt.focus(); - shiftPress('Tab'); - press('ArrowUp'); // Move from source link to object. - await dumpFocus(true, 1); - - // Expand object. - press('ArrowRight'); - await ConsoleTestRunner.waitForRemoteObjectsConsoleMessagesPromise(); - await dumpFocus(true, 1); - - next(); - }, - - async function testArrowUpToFirstVisibleMessageShouldSelectLastObject( - next) { - await clearAndLog(`console.log(obj1);console.log("after");`, 2); - await ConsoleTestRunner.waitForRemoteObjectsConsoleMessagesPromise(); - - TestRunner.addResult(`Setting focus in prompt:`); - prompt.focus(); - shiftPress('Tab'); - press('ArrowUp'); // Move from source link to "after". - await dumpFocus(true); - - press('ArrowUp'); // Move from source link to object. - press('ArrowUp'); - await dumpFocus(true); - - next(); - }, - - async function testFocusLastChildInBigObjectShouldScrollIntoView(next) { - await TestRunner.evaluateInPagePromise(` - var bigObj = Object.create(null); - for (var i = 0; i < 100; i++) - bigObj['a' + i] = i; - `); - await clearAndLog(`console.log(bigObj);`, 1); - await ConsoleTestRunner.waitForRemoteObjectsConsoleMessagesPromise(); - - TestRunner.addResult(`Setting focus in prompt:`); - prompt.focus(); - shiftPress('Tab'); - press('ArrowUp'); // Move from source link to object. - press('ArrowRight'); - await ConsoleTestRunner.waitForRemoteObjectsConsoleMessagesPromise(); - press('Tab'); - - await dumpFocus(true); - shiftPress('Tab'); - press('ArrowUp'); // Move from source link to object. - - await dumpFocus(true); - dumpScrollInfo(); - - next(); - }, - ]); - - - // Utilities. - async function clearAndLog(expression, expectedCount = 1) { - consoleView.consoleCleared(); - TestRunner.addResult(`Evaluating: ${expression}`); - await TestRunner.evaluateInPagePromise(expression); - await ConsoleTestRunner.waitForConsoleMessagesPromise(expectedCount); - await ConsoleTestRunner.waitForPendingViewportUpdates(); - } - - function forceSelect(index) { - TestRunner.addResult(`\nForce selecting index ${index}`); - viewport.virtualSelectedIndex = index; - viewport.contentElement().focus(); - viewport.updateFocusedItem(); - } - - function press(key) { - TestRunner.addResult(`\n${key}:`); - eventSender.keyDown(key); - } - - function shiftPress(key) { - TestRunner.addResult(`\nShift+${key}:`); - eventSender.keyDown(key, ['shiftKey']); - } - - function dumpScrollInfo() { - viewport.refresh(); - let infoText = - 'Is at bottom: ' + TestRunner.isScrolledToBottom(viewport.element) + ', should stick: ' + viewport.stickToBottom(); - TestRunner.addResult(infoText); - } - - async function dumpFocus(activeElement, messageIndex = 0, skipObjectCheck) { - const firstMessage = consoleView.visibleViewMessages[messageIndex] - // Ordering here is important. Retrieving the element triggers the creation of a LiveLocation. - // Wait for pending updates to settle as updates usually cause more rendering. - const firstMessageElement = firstMessage.element(); - await TestRunner.waitForPendingLiveLocationUpdates(); - - const hasTrace = !!firstMessageElement.querySelector('.console-message-stack-trace-toggle'); - const hasHiddenStackTrace = firstMessageElement.querySelector('.console-message-stack-trace-wrapper > div.hidden'); - const hasCollapsedObject = firstMessageElement.querySelector('.console-view-object-properties-section:not(.expanded)'); - const hasExpandedObject = firstMessageElement.querySelector('.console-view-object-properties-section.expanded'); - - TestRunner.addResult(`Viewport virtual selection: ${viewport.virtualSelectedIndex}`); - - if (!skipObjectCheck) { - if (hasCollapsedObject) { - TestRunner.addResult(`Has object: collapsed`); - } else if (hasExpandedObject) { - TestRunner.addResult(`Has object: expanded`); - } - } - - if (hasTrace) { - TestRunner.addResult(`Is trace expanded: ${!hasHiddenStackTrace ? 'YES' : 'NO'}`); - } - if (firstMessage instanceof Console.ConsoleGroupViewMessage) { - const expanded = !firstMessage.collapsed(); - TestRunner.addResult(`Is group expanded: ${expanded ? 'YES' : 'NO'}`); - } - - if (!activeElement) - return; - var element = document.deepActiveElement(); - if (!element) { - TestRunner.addResult('null'); - return; - } - var name = `activeElement: ${element.tagName}`; - if (element.id) - name += '#' + element.id; - else if (element.className) - name += '.' + element.className.split(' ').join('.'); - if (element.deepTextContent()) - name += '\nactive text: ' + element.deepTextContent(); - TestRunner.addResult(name); - } -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-runtime-result-below-prompt-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-runtime-result-below-prompt-expected.txt deleted file mode 100644 index 5735d66..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-runtime-result-below-prompt-expected.txt +++ /dev/null
@@ -1,60 +0,0 @@ -Tests that console fills the empty element below the prompt editor. - - -Running: testUnsafeExpressions -Expression: "var should_not_be_defined" yielded preview: "" -Expression: "window.prop_should_not_be_set = 1" yielded preview: "" -Evaluating "should_not_be_defined" -value: undefined -exceptionDetails: { - columnNumber : 0 - exception : { - className : "ReferenceError" - description : "ReferenceError: should_not_be_defined is not defined - at test://evaluations/0/console-runtime-result-below-prompt.js:20:1" - objectId : <string> - subtype : "error" - type : "object" - } - exceptionId : <number> - lineNumber : 19 - scriptId : <string> - stackTrace : { - callFrames : [ - { - columnNumber : 0 - functionName : "" - lineNumber : 19 - scriptId : <string> - url : "test://evaluations/0/console-runtime-result-below-prompt.js" - } - ] - } - text : "Uncaught" -} -Evaluating "window.prop_should_not_be_set" -value: undefined -exceptionDetails: undefined - -Running: testSafeExpressions -Expression: "1 + 2" yielded preview: "3" -Expression: "123" yielded preview: "" - -Running: testNoOpForLongText -Setting max length for evaluation to 0 -Expression: "1 + 2" yielded preview: "" - -Running: testClickingPreviewFocusesEditor -Prompt text set to `1 + 2` -Selection before: {"startLine":0,"startColumn":0,"endLine":0,"endColumn":0} -Clicking preview element -Selection after: {"startLine":0,"startColumn":5,"endLine":0,"endColumn":5} -Editor has focus: true - -Running: testClickWithSelectionDoesNotFocusEditor -Prompt text set to `1 + 2` -Selection before: 3 -Clicking preview element -Selection after: 3 -Editor has focus: false -
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-runtime-result-below-prompt.js b/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-runtime-result-below-prompt.js deleted file mode 100644 index 3a680391..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-runtime-result-below-prompt.js +++ /dev/null
@@ -1,100 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - TestRunner.addResult(`Tests that console fills the empty element below the prompt editor.\n`); - await TestRunner.loadLegacyModule('console'); await TestRunner.loadTestModule('console_test_runner'); - await TestRunner.showPanel('console'); - await ConsoleTestRunner.waitForPendingViewportUpdates(); - const consoleView = Console.ConsoleView.instance(); - const prompt = consoleView.prompt; - const editor = await ConsoleTestRunner.waitUntilConsoleEditorLoaded(); - Common.settings.moduleSetting('consoleEagerEval').set(true); - - TestRunner.runTestSuite([ - async function testUnsafeExpressions(next) { - await checkExpression(`var should_not_be_defined`); - await checkExpression(`window.prop_should_not_be_set = 1`); - - await evaluateAndDumpResult(`should_not_be_defined`); - await evaluateAndDumpResult(`window.prop_should_not_be_set`); - - next(); - }, - - async function testSafeExpressions(next) { - await checkExpression(`1 + 2`); - await checkExpression(`123`); - - next(); - }, - - async function testNoOpForLongText(next) { - TestRunner.addResult('Setting max length for evaluation to 0'); - const originalMaxLength = ObjectUI.JavaScriptREPL._MaxLengthForEvaluation; - ObjectUI.JavaScriptREPL._MaxLengthForEvaluation = 0; - await checkExpression(`1 + 2`); - ObjectUI.JavaScriptREPL._MaxLengthForEvaluation = originalMaxLength; - - next(); - }, - - async function testClickingPreviewFocusesEditor(next) { - const expression = `1 + 2`; - TestRunner.addResult(`Prompt text set to \`${expression}\``); - prompt.setText(expression); - await prompt.previewRequestForTest; - - editor.setSelection(TextUtils.TextRange.createFromLocation(0, 0)); - TestRunner.addResult('Selection before: ' + editor.selection().toString()); - - TestRunner.addResult(`Clicking preview element`); - prompt.eagerPreviewElement.click(); - - TestRunner.addResult('Selection after: ' + editor.selection().toString()); - TestRunner.addResult(`Editor has focus: ${editor.element.hasFocus()}`); - - next(); - }, - - async function testClickWithSelectionDoesNotFocusEditor(next) { - const expression = `1 + 2`; - TestRunner.addResult(`Prompt text set to \`${expression}\``); - prompt.setText(expression); - await prompt.previewRequestForTest; - document.activeElement.blur(); - - var firstTextNode = prompt.belowEditorElement().traverseNextTextNode(); - window.getSelection().setBaseAndExtent(firstTextNode, 0, firstTextNode, 1); - TestRunner.addResult('Selection before: ' + window.getSelection().toString()); - - TestRunner.addResult(`Clicking preview element`); - prompt.eagerPreviewElement.click(); - - TestRunner.addResult('Selection after: ' + window.getSelection().toString()); - TestRunner.addResult(`Editor has focus: ${editor.element.hasFocus()}`); - - next(); - }, - ]); - - async function checkExpression(expression) { - prompt.setText(expression); - await prompt.previewRequestForTest; - const previewText = prompt.innerPreviewElement.deepTextContent(); - TestRunner.addResult(`Expression: "${expression}" yielded preview: "${previewText}"`); - } - - async function evaluateAndDumpResult(expression) { - const customFormatters = {}; - for (let name of ['objectId', 'scriptId', 'exceptionId']) - customFormatters[name] = 'formatAsTypeNameOrNull'; - - TestRunner.addResult(`Evaluating "${expression}"`); - await TestRunner.evaluateInPage(expression, (value, exceptionDetails) => { - TestRunner.dump(value, customFormatters, '', 'value: '); - TestRunner.dump(exceptionDetails, customFormatters, '', 'exceptionDetails: '); - }); - } -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-stick-to-bottom-with-large-prompt-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-stick-to-bottom-with-large-prompt-expected.txt deleted file mode 100644 index 1566bbe1..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-stick-to-bottom-with-large-prompt-expected.txt +++ /dev/null
@@ -1,15 +0,0 @@ -Verifies viewport stick-to-bottom behavior when prompt has space below editable area. - - -Running: testStickToBottomWhenAddingMessages -Is at bottom: true, should stick: true - -Running: testScrollViewportToBottom -Is at bottom: true, should stick: true - -Running: testJumpToBottomWhenTypingOnLastPromptLine -Is at bottom: true, should stick: true - -Running: testDoNotJumpToBottomWhenTypingAboveLastPromptLine -Is at bottom: false, should stick: false -
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-stick-to-bottom-with-large-prompt.js b/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-stick-to-bottom-with-large-prompt.js deleted file mode 100644 index 743b8cc..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-stick-to-bottom-with-large-prompt.js +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(async function() { - TestRunner.addResult(`Verifies viewport stick-to-bottom behavior when prompt has space below editable area.\n`); - await TestRunner.loadLegacyModule('console'); await TestRunner.loadTestModule('console_test_runner'); - await TestRunner.showPanel('console'); - await TestRunner.evaluateInPagePromise(` - function populateConsoleWithMessages(count) - { - for (var i = 0; i < count; ++i) - console.log("Multiline\\nMessage #" + i); - } - - //# sourceURL=console-viewport-stick-to-bottom-with-large-prompt.js - `); - await ConsoleTestRunner.waitUntilConsoleEditorLoaded(); - ConsoleTestRunner.fixConsoleViewportDimensions(600, 200); - await ConsoleTestRunner.waitForPendingViewportUpdates(); - - const consoleView = Console.ConsoleView.instance(); - const viewport = consoleView.viewport; - const heightBelowPromptEditor = consoleView.prompt.belowEditorElement().offsetHeight; - const messagesCount = 150; - - TestRunner.runTestSuite([ - async function testStickToBottomWhenAddingMessages(next) { - await logMessagesToConsole(messagesCount); - await ConsoleTestRunner.waitForPendingViewportUpdates(); - dumpAndContinue(next); - }, - - async function testScrollViewportToBottom(next) { - viewport.element.scrollTop = 0; - consoleView.immediatelyScrollToBottom(); - await ConsoleTestRunner.waitForPendingViewportUpdates(); - dumpAndContinue(next); - }, - - async function testJumpToBottomWhenTypingOnLastPromptLine(next) { - viewport.element.scrollTop = 0; - await ConsoleTestRunner.waitForPendingViewportUpdates(); - - // Simulate scroll on type. - viewport.element.scrollTop = viewport.element.scrollHeight - viewport.element.clientHeight - heightBelowPromptEditor; - consoleView.prompt.setText('a'); - - await ConsoleTestRunner.waitForPendingViewportUpdates(); - dumpAndContinue(next); - }, - - async function testDoNotJumpToBottomWhenTypingAboveLastPromptLine(next) { - const multilineText = `Multiline text\n\n\nfoo`; - consoleView.prompt.setText(multilineText); - viewport.element.scrollTop = 0; - await ConsoleTestRunner.waitForPendingViewportUpdates(); - - // Simulate scroll on type. - viewport.element.scrollTop = viewport.element.scrollHeight - viewport.element.clientHeight - heightBelowPromptEditor - 3; - consoleView.prompt.setText(multilineText + 'a'); - - await ConsoleTestRunner.waitForPendingViewportUpdates(); - dumpAndContinue(next); - } - ]); - - function dumpAndContinue(callback) { - viewport.refresh(); - TestRunner.addResult( - 'Is at bottom: ' + TestRunner.isScrolledToBottom(viewport.element) + ', should stick: ' + viewport.stickToBottom()); - callback(); - } - - function logMessagesToConsole(count) { - return new Promise(resolve => { - var awaitingMessagesCount = count; - function messageAdded() { - if (!--awaitingMessagesCount) - resolve(); - else - ConsoleTestRunner.addConsoleSniffer(messageAdded, false); - } - - ConsoleTestRunner.addConsoleSniffer(messageAdded, false); - TestRunner.evaluateInPage(String.sprintf('populateConsoleWithMessages(%d)', count)); - }) - } -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/network/network-choose-preview-view.js b/third_party/blink/web_tests/http/tests/devtools/network/network-choose-preview-view.js index b11bfca0..ea007b1 100644 --- a/third_party/blink/web_tests/http/tests/devtools/network/network-choose-preview-view.js +++ b/third_party/blink/web_tests/http/tests/devtools/network/network-choose-preview-view.js
@@ -11,9 +11,9 @@ function createNetworkRequest(mimeType, content, statusCode, resourceType) { var request = SDK.NetworkRequest.create(0, 'http://localhost'); - request.resourceType = resourceType; + request.setResourceType(resourceType); request.mimeType = mimeType; - request.contentDataInternal = Promise.resolve({error: null, content: content, encoded: false}); + request.setContentDataProvider(() => Promise.resolve({error: null, content: content, encoded: false})); if (statusCode !== undefined) request.statusCode = statusCode; return request;
diff --git a/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js b/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js index 22f73343..8b89bcd 100644 --- a/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js +++ b/third_party/blink/web_tests/http/tests/devtools/resource-har-headers.js
@@ -24,7 +24,7 @@ request.statusCode = 200; request.statusText = 'OK'; request.resourceSize = 1000; - request.transferSizeInternal = 539; // 39 = header size at the end of the day + request.setTransferSize(539); // 39 = header size at the end of the day request.setPriority('VeryHigh'); request.setResourceType(Common.resourceTypes.Fetch);
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-style/timeline-style-recalc-all-invalidator-types-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-style/timeline-style-recalc-all-invalidator-types-expected.txt index ccaa6b3a..c9d520c 100644 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-style/timeline-style-recalc-all-invalidator-types-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-style/timeline-style-recalc-all-invalidator-types-expected.txt
@@ -84,17 +84,6 @@ Running: testAttributeChange [ { - cause : {reason: PseudoClass, stackTrace: test://evaluations/0/timeline-style-recalc-all-invalidator-types.js:68} - changedAttribute : undefined - changedClass : undefined - changedId : undefined - changedPseudo : undefined - extraData : "" - nodeName : "DIV id='testElementFour' class='red'" - selectorPart : undefined - type : "StyleRecalcInvalidationTracking" - } - { cause : {reason: Attribute, stackTrace: test://evaluations/0/timeline-style-recalc-all-invalidator-types.js:68} changedAttribute : undefined changedClass : undefined @@ -106,17 +95,6 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: PseudoClass, stackTrace: test://evaluations/0/timeline-style-recalc-all-invalidator-types.js:69} - changedAttribute : undefined - changedClass : undefined - changedId : undefined - changedPseudo : undefined - extraData : "" - nodeName : "DIV id='testElementFive' class='red'" - selectorPart : undefined - type : "StyleRecalcInvalidationTracking" - } - { cause : {reason: Attribute, stackTrace: test://evaluations/0/timeline-style-recalc-all-invalidator-types.js:69} changedAttribute : undefined changedClass : undefined @@ -127,6 +105,28 @@ selectorPart : undefined type : "StyleRecalcInvalidationTracking" } + { + cause : {reason: Element has pending invalidation list, stackTrace: test://evaluations/0/timeline-style-recalc-all-invalidator-types.js:68} + changedAttribute : "dir" + changedClass : undefined + changedId : undefined + changedPseudo : undefined + extraData : undefined + nodeName : "DIV id='testElementFour' class='red'" + selectorPart : undefined + type : "StyleRecalcInvalidationTracking" + } + { + cause : {reason: Element has pending invalidation list, stackTrace: test://evaluations/0/timeline-style-recalc-all-invalidator-types.js:69} + changedAttribute : "dir" + changedClass : undefined + changedId : undefined + changedPseudo : undefined + extraData : undefined + nodeName : "DIV id='testElementFive' class='red'" + selectorPart : undefined + type : "StyleRecalcInvalidationTracking" + } ] Running: testPseudoChange
diff --git a/third_party/blink/web_tests/http/tests/devtools/unit/binary-resource-view.js b/third_party/blink/web_tests/http/tests/devtools/unit/binary-resource-view.js index 34d8ca4c..75cf8b8b 100644 --- a/third_party/blink/web_tests/http/tests/devtools/unit/binary-resource-view.js +++ b/third_party/blink/web_tests/http/tests/devtools/unit/binary-resource-view.js
@@ -3,7 +3,6 @@ 'Verifies that BinaryResourceViewFactory interprets base64 data correctly'); TestRunner.addResult(''); - await TestRunner.loadModule('source_frame'); await TestRunner.loadLegacyModule('source_frame'); const base64content = 'c2VuZGluZyB0aGlzIHV0Zi04IHN0cmluZyBhcyBhIGJpbmFyeSBtZXNzYWdlLi4u';
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/cookies-protocol-test-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cookies-protocol-test-expected.txt index 12d35dc..6c8aa4a 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/cookies-protocol-test-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cookies-protocol-test-expected.txt
@@ -182,3 +182,32 @@ Running test: deleteAllCookies +Running test: setPartitionedCookie +Setting Cookie +setCookie failed: Partitioned cookies disabled. Cannot set cookie partition key +Num of cookies 0 +Setting Cookie +setCookie failed: Partitioned cookies disabled. Cannot set cookie partition key +Num of cookies 0 + +Running test: deleteAllCookies + +Running test: logCookies +Num of cookies 0 + +Running test: setPartitionedCookies +Adding multiple cookies +Num of cookies 0 + +Running test: getPartitionedCookie +Num of cookies 1 +name: __Host-foo, value: bar, domain: example.test, path: /, secure, session, None + +Running test: deleteAllCookies + +Running test: getPartitionedCookieFromOpaqueOrigin +Num of cookies 1 +name: __Host-foo, value: bar, domain: example.test, path: /, secure, session, None + +Running test: deleteAllCookies +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/cookies-protocol-test.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cookies-protocol-test.js index 51d043c..d045fdf 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/cookies-protocol-test.js +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/cookies-protocol-test.js
@@ -1,13 +1,18 @@ (async function(testRunner) { + var {page, session, dp} = await testRunner.startBlank( `Tests that cookies are set, updated and removed.`); - async function logCookies() { - var data = (await dp.Network.getAllCookies()).result; + async function logCookies(opt_data) { + var data = opt_data || (await dp.Network.getAllCookies()).result; testRunner.log('Num of cookies ' + data.cookies.length); data.cookies.sort((a, b) => a.name.localeCompare(b.name)); for (var cookie of data.cookies) { var suffix = '' + if (cookie.partitionKeyOpaque) + suffix += `, partitionKey: <opaque>`; + else if (cookie.partitionKey) + suffix += `, partitionKey: ${cookie.partitionKey}`; if (cookie.secure) suffix += `, secure`; if (cookie.httpOnly) @@ -226,5 +231,34 @@ printCookieViaFetch, deleteAllCookies, + + async function setPartitionedCookie() { + await setCookie({url: 'https://devtools.test:8443', secure: true, name: '__Host-foo', value: 'bar', partitionKey: 'https://example.test:8443'}); + await setCookie({url: 'https://example.test:8443', secure: true, name: '__Host-foo', value: 'bar', partitionKey: 'https://devtools.test:8443'}); + }, + + deleteAllCookies, + logCookies, + + async function setPartitionedCookies() { + await setCookies([ + {url: 'https://devtools.test:8443', secure: true, name: '__Host-foo', value: 'bar', partitionKey: 'https://example.test:8443'}, + {url: 'https://example.test:8443', secure: true, name: '__Host-foo', value: 'bar', partitionKey: 'https://devtools.test:8443'} + ]); + }, + + async function getPartitionedCookie() { + await page.navigate('https://devtools.test:8443/inspector-protocol/resources/iframe-third-party-cookie-parent.php'); + logCookies((await dp.Network.getCookies()).result); + }, + + deleteAllCookies, + + async function getPartitionedCookieFromOpaqueOrigin() { + await page.navigate('https://devtools.test:8443/inspector-protocol/resources/iframe-third-party-cookie-parent.php?opaque'); + logCookies((await dp.Network.getCookies()).result); + }, + + deleteAllCookies, ]); })
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/websocket/slow-network.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/websocket/slow-network.js index d19b9b6..1871a0d 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/websocket/slow-network.js +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/websocket/slow-network.js
@@ -17,6 +17,7 @@ ws.onopen = () => { startTime = performance.now(); ws.send('x'.repeat(2000)); + ws.send('x'.repeat(2000)); }; ws.onmessage = () => { resolve(performance.now() - startTime); } ws.onerror = () => log += 'onerror ';
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/iframe-third-party-cookie-child.php b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/iframe-third-party-cookie-child.php new file mode 100644 index 0000000..7477d1b3 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/iframe-third-party-cookie-child.php
@@ -0,0 +1,4 @@ +<?php +header('Content-Type: text/html; charset=UTF-8'); +header('Set-Cookie: __Host-foo=bar; Secure; Path=/; SameSite=None; Partitioned'); +?>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/iframe-third-party-cookie-parent.php b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/iframe-third-party-cookie-parent.php new file mode 100644 index 0000000..7d43e3d --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/iframe-third-party-cookie-parent.php
@@ -0,0 +1,6 @@ +<?php +if(isset($_GET['opaque'])) { + header("Content-Security-Policy: sandbox;"); +} +?> +<iframe src="https://example.test:8443/inspector-protocol/resources/iframe-third-party-cookie-child.php"></iframe>
diff --git a/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-user-gesture-in-parent-expected.txt b/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-user-gesture-in-parent-expected.txt deleted file mode 100644 index ee18088..0000000 --- a/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-user-gesture-in-parent-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ - - --------- -Frame: '<!--framePath //<!--frame0-->-->' --------- -The navigation should fail. This text should be visible.
diff --git a/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-user-gesture-in-parent.html b/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-user-gesture-in-parent.html deleted file mode 100644 index f473720..0000000 --- a/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-user-gesture-in-parent.html +++ /dev/null
@@ -1,27 +0,0 @@ -<html> -<body> -<script> -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.dumpChildFrames(); - testRunner.setDumpConsoleMessages(false); - testRunner.waitUntilDone(); -} - -// Ensure a user gesture happened in the main frame, but not in the iframe. -if (window.eventSender) { - eventSender.mouseMoveTo(0, 0); - eventSender.mouseDown(0, 0); - eventSender.mouseUp(0, 0); -} - -window.addEventListener("message", e => { - if (e.data == "PASS") - setTimeout(_ => { testRunner.notifyDone(); }, 500); // Give the schedule blocking navigation time to fire. - else - testRunner.testFailed("'top.location' didn't throw."); -}); -</script> -<iframe src="http://localhost:8000/security/frameNavigation/resources/iframe-that-performs-top-navigation-without-user-gesture.html"></iframe> -</body> -</html>
diff --git a/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture-expected.txt b/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture-expected.txt deleted file mode 100644 index b6161c3..0000000 --- a/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -CONSOLE ERROR: line 8: Unsafe attempt to initiate navigation for frame with URL 'http://127.0.0.1:8000/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html' from frame with URL 'http://localhost:8000/security/frameNavigation/resources/iframe-that-performs-top-navigation-without-user-gesture.html'. The frame attempting navigation is targeting its top-level window, but is neither same-origin with its target nor has it received a user gesture. See https://www.chromestatus.com/feature/5851021045661696. - - - --------- -Frame: '<!--framePath //<!--frame0-->-->' --------- -The navigation should fail. This text should be visible.
diff --git a/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html b/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html deleted file mode 100644 index 379a7b7..0000000 --- a/third_party/blink/web_tests/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html +++ /dev/null
@@ -1,22 +0,0 @@ -<html> -<head> -<script> -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.dumpChildFrames(); - testRunner.setDumpConsoleMessages(true); - testRunner.waitUntilDone(); -} - -window.addEventListener("message", e => { - if (e.data == "PASS") - testRunner.notifyDone(); - else - testRunner.testFailed("'top.location' didn't throw."); -}); -</script> -</head> -<body> -<iframe src="http://localhost:8000/security/frameNavigation/resources/iframe-that-performs-top-navigation-without-user-gesture.html"></iframe> -</body> -</html>
diff --git a/third_party/blink/web_tests/http/tests/security/isolatedWorld/window-setTimeout-function.html b/third_party/blink/web_tests/http/tests/security/isolatedWorld/window-setTimeout-function.html index f35ae5e..c68ed92 100644 --- a/third_party/blink/web_tests/http/tests/security/isolatedWorld/window-setTimeout-function.html +++ b/third_party/blink/web_tests/http/tests/security/isolatedWorld/window-setTimeout-function.html
@@ -7,11 +7,19 @@ if (window.testRunner) testRunner.notifyDone(); } + +addEventListener('message', (msg) => { + if (msg.data === 'done') + done(); +}); + window.func = function () { alert("FAIL: Wrong function."); done(); }; + document.foo = "FAIL: Wrong wrappers."; + if (window.testRunner) { testRunner.dumpAsText(); testRunner.waitUntilDone(); @@ -20,7 +28,7 @@ "document.foo = 'PASS';\n" + "window.func = function () {\n" + " alert(document.foo);\n" + - " window.location = 'javascript:done()';\n" + + " window.postMessage('done', '*');\n" + "};\n" + "window.setTimeout(func, 0);"); }
diff --git a/third_party/blink/web_tests/http/tests/security/isolatedWorld/window-setTimeout-string.html b/third_party/blink/web_tests/http/tests/security/isolatedWorld/window-setTimeout-string.html index 9e33827..3f44aabf 100644 --- a/third_party/blink/web_tests/http/tests/security/isolatedWorld/window-setTimeout-string.html +++ b/third_party/blink/web_tests/http/tests/security/isolatedWorld/window-setTimeout-string.html
@@ -7,11 +7,19 @@ if (window.testRunner) testRunner.notifyDone(); } + +addEventListener('message', (msg) => { + if (msg.data === 'done') + done(); +}); + window.func = function () { alert("FAIL: Wrong function."); done(); }; + document.foo = "FAIL: Wrong wrappers."; + if (window.testRunner) { testRunner.dumpAsText(); testRunner.waitUntilDone(); @@ -20,7 +28,7 @@ "document.foo = 'PASS';\n" + "window.func = function () {\n" + " alert(document.foo);\n" + - " window.location = 'javascript:done()';\n" + + " window.postMessage('done', '*');\n" + "};\n" + "window.setTimeout('func()', 0);"); }
diff --git a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/colrv1-samples-visual-expected.png b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/colrv1-samples-visual-expected.png new file mode 100644 index 0000000..99093e16 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/colrv1-samples-visual-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/text-antialias/colrv1-samples-visual-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/text-antialias/colrv1-samples-visual-expected.png new file mode 100644 index 0000000..aa42e1c --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/text-antialias/colrv1-samples-visual-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/colrv1-samples-visual-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/colrv1-samples-visual-expected.png new file mode 100644 index 0000000..3c0dc1d --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/text-antialias/colrv1-samples-visual-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/colrv1-samples-visual-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/colrv1-samples-visual-expected.png new file mode 100644 index 0000000..0611f9e --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/colrv1-samples-visual-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/colrv1-samples-visual-expected.png b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/colrv1-samples-visual-expected.png new file mode 100644 index 0000000..73e6dc1 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/colrv1-samples-visual-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/text-antialias/colrv1-samples-visual-expected.png b/third_party/blink/web_tests/platform/win/virtual/text-antialias/colrv1-samples-visual-expected.png new file mode 100644 index 0000000..2976a17 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/text-antialias/colrv1-samples-visual-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/text-antialias/colrv1-samples-visual-expected.png b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/colrv1-samples-visual-expected.png new file mode 100644 index 0000000..bdb4559 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/virtual/text-antialias/colrv1-samples-visual-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/partitioned-cookies/http/tests/inspector-protocol/network/cookies-protocol-test-expected.txt b/third_party/blink/web_tests/virtual/partitioned-cookies/http/tests/inspector-protocol/network/cookies-protocol-test-expected.txt new file mode 100644 index 0000000..6a214b0 --- /dev/null +++ b/third_party/blink/web_tests/virtual/partitioned-cookies/http/tests/inspector-protocol/network/cookies-protocol-test-expected.txt
@@ -0,0 +1,216 @@ +Tests that cookies are set, updated and removed. +Test started +Enabling network + +Running test: simpleCookieAdd +Setting Cookie +Num of cookies 1 +name: foo, value: bar1, domain: 127.0.0.1, path: /, session + +Running test: simpleCookieChange +Setting Cookie +Num of cookies 1 +name: foo, value: second bar2, domain: 127.0.0.1, path: /, session + +Running test: anotherSimpleCookieAdd +Setting Cookie +Num of cookies 2 +name: foo, value: second bar2, domain: 127.0.0.1, path: /, session +name: foo2, value: bar1, domain: 127.0.0.1, path: /, session + +Running test: simpleCookieDelete +Deleting Cookie +Num of cookies 1 +name: foo2, value: bar1, domain: 127.0.0.1, path: /, session + +Running test: deleteAllCookies + +Running test: sessionCookieAdd +Setting Cookie +Num of cookies 1 +name: foo, value: bar4, domain: 127.0.0.1, path: /, session + +Running test: deleteAllCookies + +Running test: nonSessionCookieZeroAdd +Setting Cookie +Num of cookies 0 + +Running test: deleteAllCookies + +Running test: nonSessionCookieAdd +Setting Cookie +Num of cookies 1 +name: foo, value: bar6, domain: 127.0.0.1, path: /, expires + +Running test: deleteAllCookies + +Running test: differentOriginCookieAdd +Setting Cookie +Num of cookies 1 +name: foo, value: bar7, domain: example.com, path: /, session + +Running test: deleteAllCookies + +Running test: invalidCookieAddDomain +Setting Cookie +setCookie failed: URL must have scheme http or https +Num of cookies 0 + +Running test: deleteAllCookies + +Running test: invalidCookieAddName +Setting Cookie +setCookie failed: Sanitizing cookie failed +Num of cookies 0 + +Running test: deleteAllCookies + +Running test: invalidCookieSourceScheme +Setting Cookie +setCookie failed: Invalid cookie source scheme +Num of cookies 0 + +Running test: deleteAllCookies + +Running test: invalidCookieSourcePort +Setting Cookie +setCookie failed: Invalid source port +Num of cookies 0 + +Running test: deleteAllCookies + +Running test: secureCookieAdd +Setting Cookie +Num of cookies 1 +name: foo, value: bar, domain: 127.0.0.1, path: /, secure, session + +Running test: deleteAllCookies + +Running test: cookieAddHttpOnly +Setting Cookie +Num of cookies 1 +name: foo, value: bar, domain: 127.0.0.1, path: /, httpOnly, session + +Running test: deleteAllCookies + +Running test: cookieAddSameSiteLax +Setting Cookie +Num of cookies 1 +name: foo, value: bar, domain: 127.0.0.1, path: /, session, Lax + +Running test: deleteAllCookies + +Running test: cookieAddSameSiteLax +Setting Cookie +Num of cookies 1 +name: foo, value: bar, domain: 127.0.0.1, path: /, session, Strict + +Running test: deleteAllCookies + +Running test: setCookiesBasic +Adding multiple cookies +Num of cookies 8 +name: cookie1, value: session, domain: localhost, path: /, session +name: cookie2, value: httpOnly, domain: localhost, path: /, httpOnly, session +name: cookie3, value: secure, domain: localhost, path: /, secure, session +name: cookie4, value: lax, domain: localhost, path: /, session, Lax +name: cookie5, value: expires, domain: localhost, path: /, expires +name: cookie6, value: .domain, domain: .chromium.org, path: /path, session +name: cookie7, value: domain, domain: www.chromium.org, path: /path, session +name: cookie8, value: url-based, domain: www.chromium.org, path: /, secure, session + +Running test: deleteAllCookies + +Running test: setCookiesWithInvalidCookie +Adding multiple cookies +Num of cookies 0 + +Running test: deleteAllCookies + +Running test: deleteCookieByURL +Adding multiple cookies +Num of cookies 2 +name: cookie1, value: .domain, domain: www.chromium.org, path: /, session +name: cookie2, value: .domain, domain: www.chromium.org, path: /, expires +Deleting Cookie +Num of cookies 1 +name: cookie2, value: .domain, domain: www.chromium.org, path: /, expires + +Running test: deleteAllCookies + +Running test: deleteCookieByDomain +Adding multiple cookies +Num of cookies 2 +name: cookie1, value: .domain, domain: .chromium.org, path: /path, session +name: cookie2, value: .domain, domain: .chromium.org, path: /path, expires +Deleting Cookie +Num of cookies 1 +name: cookie2, value: .domain, domain: .chromium.org, path: /path, expires +Deleting Cookie +Num of cookies 0 + +Running test: deleteAllCookies + +Running test: deleteCookieByDomainAndPath +Adding multiple cookies +Num of cookies 1 +name: cookie1, value: .domain, domain: .chromium.org, path: /path, session +Deleting Cookie +Num of cookies 1 +name: cookie1, value: .domain, domain: .chromium.org, path: /path, session +Deleting Cookie +Num of cookies 0 + +Running test: deleteAllCookies + +Running test: nonUnicodeCookie +Adding multiple cookies +Num of cookies 1 +name: cookie1, value: привет, domain: .chromium.org, path: /path, session + +Running test: deleteAllCookies + +Running test: setCookieViaFetch +Num of cookies 1 +name: name, value: value, domain: 127.0.0.1, path: /inspector-protocol/network/resources, session + +Running test: deleteAllCookies + +Running test: printCookieViaFetch +Cookies as seen on server: "HTTP_COOKIE: foo=bar1\n" + +Running test: deleteAllCookies + +Running test: setPartitionedCookie +Setting Cookie +Num of cookies 1 +name: __Host-foo, value: bar, domain: devtools.test, path: /, partitionKey: https://example.test, secure, session +Setting Cookie +Num of cookies 2 +name: __Host-foo, value: bar, domain: devtools.test, path: /, partitionKey: https://example.test, secure, session +name: __Host-foo, value: bar, domain: example.test, path: /, partitionKey: https://devtools.test, secure, session + +Running test: deleteAllCookies + +Running test: logCookies +Num of cookies 0 + +Running test: setPartitionedCookies +Adding multiple cookies +Num of cookies 2 +name: __Host-foo, value: bar, domain: devtools.test, path: /, partitionKey: https://example.test, secure, session +name: __Host-foo, value: bar, domain: example.test, path: /, partitionKey: https://devtools.test, secure, session + +Running test: getPartitionedCookie +Num of cookies 1 +name: __Host-foo, value: bar, domain: example.test, path: /, partitionKey: https://devtools.test, secure, session, None + +Running test: deleteAllCookies + +Running test: getPartitionedCookieFromOpaqueOrigin +Num of cookies 1 +name: __Host-foo, value: bar, domain: example.test, path: /, partitionKey: <opaque>, secure, session, None + +Running test: deleteAllCookies +
diff --git a/third_party/blink/web_tests/virtual/text-antialias/colrv1-samples-visual.html b/third_party/blink/web_tests/virtual/text-antialias/colrv1-samples-visual.html new file mode 100644 index 0000000..91691199 --- /dev/null +++ b/third_party/blink/web_tests/virtual/text-antialias/colrv1-samples-visual.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>COLRv1 test font visual rendering test</title> +<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-face-src-parsing" /> +<link rel="author" href="drott@chromium.org" /> +<meta name="assert" content="Checks that COLRv1 glyphs are displayed in color." /> +<style> +@font-face { + font-family: colrv1_samples; + src: url(resources/more_samples-glyf_colr_1.ttf); +} + +.colrv1 { + font: 40px/1 colrv1_samples, monospace; + word-break: break-all; +} +</style> +Test passes if only color glyphs are seen below. Basic sanity check for COLRv1 rendering, additional testing is done in +the Skia GM test for COLRv1, see Skia's gm/colrv1.cpp for details. + +<div class="colrv1">adefg<br>hijklm<br>nopqrs<br>tuvw<br>xyzABC<br>DEFG<br>HIJKL<br>MNOPQRS</div> + +The following two rows must feature purple (first row) and green (second row) in the glyph gradients. +<div class="colrv1" style="color: purple;">TUVWXYZ</div> +<div class="colrv1" style="color: green;">TUVWXYZ</div>
diff --git a/third_party/blink/web_tests/virtual/text-antialias/resources/more_samples-glyf_colr_1.ttf b/third_party/blink/web_tests/virtual/text-antialias/resources/more_samples-glyf_colr_1.ttf new file mode 100644 index 0000000..55d4415 --- /dev/null +++ b/third_party/blink/web_tests/virtual/text-antialias/resources/more_samples-glyf_colr_1.ttf Binary files differ
diff --git a/third_party/private_membership/BUILD.gn b/third_party/private_membership/BUILD.gn index 34c76a02..b022f3d 100644 --- a/third_party/private_membership/BUILD.gn +++ b/third_party/private_membership/BUILD.gn
@@ -9,6 +9,16 @@ config("private_membership_config") { # TODO(crbug.com/1072732) Reenable the deprecated warning, after updating the upstream. cflags = [ "-Wno-deprecated-declarations" ] + defines = [] + if (is_component_build) { + defines = [ + # Build targets inside private_membership will need this macro to + # be defined in order to correctly export symbols when is_component_build + # is true. + # For more info see: base/private_membership_export.h. + "PRIVATE_MEMBERSHIP_ENABLE_SYMBOL_EXPORT", + ] + } include_dirs = [ # Allow includes to be prefixed with shell-encryption/src/ in case it is not an # immediate subdirectory of the top-level. @@ -31,16 +41,24 @@ "src/private_membership_rlwe.proto", ] import_dirs = [ "//third_party/shell-encryption/src" ] + extra_configs = [ ":private_membership_config" ] + proto_in_dir = "src/" + cc_generator_options = "dllexport_decl=PRIVATE_MEMBERSHIP_EXPORT:" + cc_include = "third_party/private_membership/base/private_membership_export.h" + component_build_force_source_set = true + link_deps = [ "//third_party/shell-encryption:serialization_proto" ] } if (is_chromeos_ash) { - source_set("private_membership") { + component("private_membership") { public_configs = [ ":private_membership_config" ] configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code" ] + public = [ + "base/private_membership_export.h", "src/internal/aes_ctr_256_with_fixed_iv.h", "src/internal/constants.h", "src/internal/crypto_utils.h",
diff --git a/third_party/private_membership/base/private_membership_export.h b/third_party/private_membership/base/private_membership_export.h new file mode 100644 index 0000000..58ff63f --- /dev/null +++ b/third_party/private_membership/base/private_membership_export.h
@@ -0,0 +1,28 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PRIVATE_MEMBERSHIP_BASE_PRIVATE_MEMBERSHIP_EXPORT_H_ +#define PRIVATE_MEMBERSHIP_BASE_PRIVATE_MEMBERSHIP_EXPORT_H_ + +// PRIVATE_MEMBERSHIP_EXPORT is used to mark symbols as imported or +// exported when private_membership is built or used as a shared library. +// When private_membership is built as a static library the +// PRIVATE_MEMBERSHIP_EXPORT macro expands to nothing. +// +// This export macros doesn't support Windows. There will be additional +// component build work to support Windows (see crbug.com/1269714). + +#ifdef PRIVATE_MEMBERSHIP_ENABLE_SYMBOL_EXPORT + +#if __has_attribute(visibility) +#define PRIVATE_MEMBERSHIP_EXPORT __attribute__((visibility("default"))) +#endif + +#endif // PRIVATE_MEMBERSHIP_ENABLE_SYMBOL_EXPORT + +#ifndef PRIVATE_MEMBERSHIP_EXPORT +#define PRIVATE_MEMBERSHIP_EXPORT +#endif + +#endif // PRIVATE_MEMBERSHIP_BASE_PRIVATE_MEMBERSHIP_EXPORT_H_
diff --git a/third_party/private_membership/patches/0002-Support-PSM-component-build.patch b/third_party/private_membership/patches/0002-Support-PSM-component-build.patch new file mode 100644 index 0000000..4e42b83 --- /dev/null +++ b/third_party/private_membership/patches/0002-Support-PSM-component-build.patch
@@ -0,0 +1,69 @@ +diff --git a/membership_response_map.h b/membership_response_map.h +index dc56c4bbe148a..d8233d94e63c3 100644 +--- a/membership_response_map.h ++++ b/membership_response_map.h +@@ -15,6 +15,7 @@ + #ifndef THIRD_PARTY_PRIVATE_MEMBERSHIP_SRC_MEMBERSHIP_RESPONSE_MAP_H_ + #define THIRD_PARTY_PRIVATE_MEMBERSHIP_SRC_MEMBERSHIP_RESPONSE_MAP_H_ + ++#include "third_party/private_membership/base/private_membership_export.h" + #include "third_party/private_membership/src/private_membership.pb.h" + #include "third_party/private_membership/src/private_membership_rlwe.pb.h" + #include "absl/container/flat_hash_map.h" +@@ -22,7 +23,7 @@ + namespace private_membership { + namespace rlwe { + +-class MembershipResponseMap { ++class PRIVATE_MEMBERSHIP_EXPORT MembershipResponseMap { + public: + MembershipResponseMap() = default; + +diff --git a/private_membership_rlwe_client.h b/private_membership_rlwe_client.h +index 888fe190094ac..533a517c1a155 100644 +--- a/private_membership_rlwe_client.h ++++ b/private_membership_rlwe_client.h +@@ -15,6 +15,7 @@ + #ifndef THIRD_PARTY_PRIVATE_MEMBERSHIP_SRC_PRIVATE_MEMBERSHIP_RLWE_CLIENT_H_ + #define THIRD_PARTY_PRIVATE_MEMBERSHIP_SRC_PRIVATE_MEMBERSHIP_RLWE_CLIENT_H_ + ++#include "third_party/private_membership/base/private_membership_export.h" + #include "third_party/private-join-and-compute/src/crypto/ec_commutative_cipher.h" + #include "third_party/private_membership/src/private_membership.pb.h" + #include "third_party/private_membership/src/membership_response_map.h" +@@ -30,7 +31,7 @@ namespace rlwe { + namespace internal { + + // PRNG seed generator which supports deterministic seed generation. +-class PrngSeedGenerator { ++class PRIVATE_MEMBERSHIP_EXPORT PrngSeedGenerator { + public: + // Creates a non deterministic PRNG seed generator. + static std::unique_ptr<PrngSeedGenerator> Create(); +@@ -54,7 +55,7 @@ class PrngSeedGenerator { + + // Lightweight wrapper for processing PIR related requests and responses. + // Thread safe. +-class PirClient { ++class PRIVATE_MEMBERSHIP_EXPORT PirClient { + public: + virtual ~PirClient() = default; + +@@ -79,7 +80,7 @@ class PirClient { + + // Thread safe. + template <typename ModularInt> +-class PirClientImpl : public PirClient { ++class PRIVATE_MEMBERSHIP_EXPORT PirClientImpl : public PirClient { + public: + static ::rlwe::StatusOr<std::unique_ptr<PirClientImpl<ModularInt>>> Create( + const RlweParameters& rlwe_params, int total_entry_count, +@@ -142,7 +143,7 @@ class PirClientImpl : public PirClient { + } // namespace internal + + // Client for the Private Membership RLWE protocol. +-class PrivateMembershipRlweClient { ++class PRIVATE_MEMBERSHIP_EXPORT PrivateMembershipRlweClient { + public: + // PrivateMembershipRlweClient is neither copyable nor copy assignable. + PrivateMembershipRlweClient(const PrivateMembershipRlweClient&) = delete;
diff --git a/third_party/private_membership/src/membership_response_map.h b/third_party/private_membership/src/membership_response_map.h index dc56c4b..d8233d9 100644 --- a/third_party/private_membership/src/membership_response_map.h +++ b/third_party/private_membership/src/membership_response_map.h
@@ -15,6 +15,7 @@ #ifndef THIRD_PARTY_PRIVATE_MEMBERSHIP_SRC_MEMBERSHIP_RESPONSE_MAP_H_ #define THIRD_PARTY_PRIVATE_MEMBERSHIP_SRC_MEMBERSHIP_RESPONSE_MAP_H_ +#include "third_party/private_membership/base/private_membership_export.h" #include "third_party/private_membership/src/private_membership.pb.h" #include "third_party/private_membership/src/private_membership_rlwe.pb.h" #include "absl/container/flat_hash_map.h" @@ -22,7 +23,7 @@ namespace private_membership { namespace rlwe { -class MembershipResponseMap { +class PRIVATE_MEMBERSHIP_EXPORT MembershipResponseMap { public: MembershipResponseMap() = default;
diff --git a/third_party/private_membership/src/private_membership_rlwe_client.h b/third_party/private_membership/src/private_membership_rlwe_client.h index 888fe19..533a517 100644 --- a/third_party/private_membership/src/private_membership_rlwe_client.h +++ b/third_party/private_membership/src/private_membership_rlwe_client.h
@@ -15,6 +15,7 @@ #ifndef THIRD_PARTY_PRIVATE_MEMBERSHIP_SRC_PRIVATE_MEMBERSHIP_RLWE_CLIENT_H_ #define THIRD_PARTY_PRIVATE_MEMBERSHIP_SRC_PRIVATE_MEMBERSHIP_RLWE_CLIENT_H_ +#include "third_party/private_membership/base/private_membership_export.h" #include "third_party/private-join-and-compute/src/crypto/ec_commutative_cipher.h" #include "third_party/private_membership/src/private_membership.pb.h" #include "third_party/private_membership/src/membership_response_map.h" @@ -30,7 +31,7 @@ namespace internal { // PRNG seed generator which supports deterministic seed generation. -class PrngSeedGenerator { +class PRIVATE_MEMBERSHIP_EXPORT PrngSeedGenerator { public: // Creates a non deterministic PRNG seed generator. static std::unique_ptr<PrngSeedGenerator> Create(); @@ -54,7 +55,7 @@ // Lightweight wrapper for processing PIR related requests and responses. // Thread safe. -class PirClient { +class PRIVATE_MEMBERSHIP_EXPORT PirClient { public: virtual ~PirClient() = default; @@ -79,7 +80,7 @@ // Thread safe. template <typename ModularInt> -class PirClientImpl : public PirClient { +class PRIVATE_MEMBERSHIP_EXPORT PirClientImpl : public PirClient { public: static ::rlwe::StatusOr<std::unique_ptr<PirClientImpl<ModularInt>>> Create( const RlweParameters& rlwe_params, int total_entry_count, @@ -142,7 +143,7 @@ } // namespace internal // Client for the Private Membership RLWE protocol. -class PrivateMembershipRlweClient { +class PRIVATE_MEMBERSHIP_EXPORT PrivateMembershipRlweClient { public: // PrivateMembershipRlweClient is neither copyable nor copy assignable. PrivateMembershipRlweClient(const PrivateMembershipRlweClient&) = delete;
diff --git a/third_party/shell-encryption/BUILD.gn b/third_party/shell-encryption/BUILD.gn index 91095005..2f92906 100644 --- a/third_party/shell-encryption/BUILD.gn +++ b/third_party/shell-encryption/BUILD.gn
@@ -15,6 +15,17 @@ "-Wno-ignored-qualifiers", ] + defines = [] + if (is_component_build) { + defines = [ + # Build targets inside shell-encryption will need this macro to + # be defined in order to correctly export symbols when is_component_build + # is true. + # For more info see: base/shell_encryption_export.h. + "SHELL_ENCRYPTION_ENABLE_SYMBOL_EXPORT", + ] + } + include_dirs = [ # Allow includes to be prefixed with shell-encryption/src/ in case it is not an # immediate subdirectory of the top-level. @@ -39,20 +50,30 @@ proto_library("serialization_proto") { sources = [ "src/serialization.proto" ] proto_in_dir = "src/" + + cc_generator_options = "dllexport_decl=SHELL_ENCRYPTION_EXPORT:" + cc_include = "third_party/shell-encryption/base/shell_encryption_export.h" + component_build_force_source_set = true } proto_library("coefficient_polynomial_proto") { sources = [ "src/testing/coefficient_polynomial.proto" ] proto_in_dir = "src/testing/" + + cc_generator_options = "dllexport_decl=SHELL_ENCRYPTION_EXPORT:" + cc_include = "third_party/shell-encryption/base/shell_encryption_export.h" + component_build_force_source_set = true } # SHELL lib. if (is_chromeos_ash) { - source_set("shell_encryption") { + component("shell_encryption") { public_configs = [ ":shell_encryption_config1" ] configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code" ] public = [ + "base/shell_encryption_export.h", + "base/shell_encryption_export_template.h", "glog/logging.h", "src/bits_util.h", "src/constants.h", @@ -116,6 +137,7 @@ ] public_deps = [ ":coefficient_polynomial_proto", + ":serialization_proto", ":shell_encryption", "//testing/gmock:gmock", "//testing/gtest:gtest",
diff --git a/third_party/shell-encryption/base/shell_encryption_export.h b/third_party/shell-encryption/base/shell_encryption_export.h new file mode 100644 index 0000000..72670c3 --- /dev/null +++ b/third_party/shell-encryption/base/shell_encryption_export.h
@@ -0,0 +1,28 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SHELL_ENCRYPTION_BASE_SHELL_ENCRYPTION_EXPORT_H_ +#define SHELL_ENCRYPTION_BASE_SHELL_ENCRYPTION_EXPORT_H_ + +// SHELL_ENCRYPTION_EXPORT is used to mark symbols as imported or +// exported when shell-encryption is built or used as a shared library. +// When shell-encryption is built as a static library the +// SHELL_ENCRYPTION_EXPORT macro expands to nothing. +// +// This export macros doesn't support Windows. There will be additional +// component build work to support Windows (see crbug.com/1269714). + +#ifdef SHELL_ENCRYPTION_ENABLE_SYMBOL_EXPORT + +#if __has_attribute(visibility) +#define SHELL_ENCRYPTION_EXPORT __attribute__((visibility("default"))) +#endif + +#endif // SHELL_ENCRYPTION_ENABLE_SYMBOL_EXPORT + +#ifndef SHELL_ENCRYPTION_EXPORT +#define SHELL_ENCRYPTION_EXPORT +#endif + +#endif // SHELL_ENCRYPTION_BASE_SHELL_ENCRYPTION_EXPORT_H_
diff --git a/third_party/shell-encryption/base/shell_encryption_export_template.h b/third_party/shell-encryption/base/shell_encryption_export_template.h new file mode 100644 index 0000000..1feb536 --- /dev/null +++ b/third_party/shell-encryption/base/shell_encryption_export_template.h
@@ -0,0 +1,152 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SHELL_ENCRYPTION_BASE_SHELL_ENCRYPTION_EXPORT_TEMPLATE_H_ +#define SHELL_ENCRYPTION_BASE_SHELL_ENCRYPTION_EXPORT_TEMPLATE_H_ + +// This was borrowed from Chromium's base/export_template.h. +// +// TODO(crbug.com/1271458): Use shell-encryption template macro's name +// instead of generic Chromium macro names. + +// Synopsis +// +// This header provides macros for using FOO_EXPORT macros with explicit +// template instantiation declarations and definitions. +// Generally, the FOO_EXPORT macros are used at declarations, +// and GCC requires them to be used at explicit instantiation declarations, +// but MSVC requires __declspec(dllexport) to be used at the explicit +// instantiation definitions instead. + +// Usage +// +// In a header file, write: +// +// extern template class EXPORT_TEMPLATE_DECLARE(FOO_EXPORT) foo<bar>; +// +// In a source file, write: +// +// template class EXPORT_TEMPLATE_DEFINE(FOO_EXPORT) foo<bar>; + +// Implementation notes +// +// On Windows, when building the FOO library (that is, when FOO_EXPORT expands +// to __declspec(dllexport)), we want the two lines to expand to: +// +// extern template class foo<bar>; +// template class FOO_EXPORT foo<bar>; +// +// In all other cases (non-Windows, and Windows when using the FOO library (that +// is when FOO_EXPORT expands to __declspec(dllimport)), we want: +// +// extern template class FOO_EXPORT foo<bar>; +// template class foo<bar>; +// +// The implementation of this header uses some subtle macro semantics to +// detect what the provided FOO_EXPORT value was defined as and then +// to dispatch to appropriate macro definitions. + +#define EXPORT_TEMPLATE_DECLARE(foo_export) \ + EXPORT_TEMPLATE_INVOKE(DECLARE, EXPORT_TEMPLATE_STYLE(foo_export), foo_export) +#define EXPORT_TEMPLATE_DEFINE(foo_export) \ + EXPORT_TEMPLATE_INVOKE(DEFINE, EXPORT_TEMPLATE_STYLE(foo_export), foo_export) + +// INVOKE is an internal helper macro to perform parameter replacements +// and token pasting to chain invoke another macro. E.g., +// EXPORT_TEMPLATE_INVOKE(DECLARE, DEFAULT, FOO_EXPORT) +// will expand to call +// EXPORT_TEMPLATE_DECLARE_DEFAULT(FOO_EXPORT) +// (but with FOO_EXPORT expanded too). +#define EXPORT_TEMPLATE_INVOKE(which, style, foo_export) \ + EXPORT_TEMPLATE_INVOKE_2(which, style, foo_export) +#define EXPORT_TEMPLATE_INVOKE_2(which, style, foo_export) \ + EXPORT_TEMPLATE_##which##_##style(foo_export) + +// Default style is to apply the FOO_EXPORT macro at declaration sites. +#define EXPORT_TEMPLATE_DECLARE_DEFAULT(foo_export) foo_export +#define EXPORT_TEMPLATE_DEFINE_DEFAULT(foo_export) + +// The "declspec" style is used when FOO_EXPORT is defined +// as __declspec(dllexport), which MSVC requires to be used at +// definition sites instead. +#define EXPORT_TEMPLATE_DECLARE_EXPORT_DLLEXPORT(foo_export) +#define EXPORT_TEMPLATE_DEFINE_EXPORT_DLLEXPORT(foo_export) foo_export + +// EXPORT_TEMPLATE_STYLE is an internal helper macro that identifies which +// export style needs to be used for the provided FOO_EXPORT macro definition. +// "", "__attribute__(...)", and "__declspec(dllimport)" are mapped +// to "DEFAULT"; while "__declspec(dllexport)" is mapped to "EXPORT_DLLEXPORT". +// (NaCl headers define "DLLEXPORT" already, else we'd use that. +// TODO(thakis): Rename once nacl is gone.) +// +// It's implemented with token pasting to transform the __attribute__ and +// __declspec annotations into macro invocations. E.g., if FOO_EXPORT is +// defined as "__declspec(dllimport)", it undergoes the following sequence of +// macro substitutions: +// EXPORT_TEMPLATE_STYLE(FOO_EXPORT) +// EXPORT_TEMPLATE_STYLE_2(__declspec(dllimport)) +// EXPORT_TEMPLATE_STYLE_MATCH__declspec(dllimport) +// EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllimport +// DEFAULT +#define EXPORT_TEMPLATE_STYLE(foo_export) EXPORT_TEMPLATE_STYLE_2(foo_export) +#define EXPORT_TEMPLATE_STYLE_2(foo_export) \ + EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA##foo_export + +// Internal helper macros for EXPORT_TEMPLATE_STYLE. +// +// XXX: C++ reserves all identifiers containing "__" for the implementation, +// but "__attribute__" and "__declspec" already contain "__" and the token-paste +// operator can only add characters; not remove them. To minimize the risk of +// conflict with implementations, we include "foj3FJo5StF0OvIzl7oMxA" (a random +// 128-bit string, encoded in Base64) in the macro name. +#define EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA DEFAULT +#define EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA__attribute__(...) \ + DEFAULT +#define EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA__declspec(arg) \ + EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_##arg + +// Internal helper macros for EXPORT_TEMPLATE_STYLE. +#define EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllexport EXPORT_DLLEXPORT +#define EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllimport DEFAULT + +// Sanity checks. +// +// EXPORT_TEMPLATE_TEST uses the same macro invocation pattern as +// EXPORT_TEMPLATE_DECLARE and EXPORT_TEMPLATE_DEFINE do to check that they're +// working correctly. When they're working correctly, the sequence of macro +// replacements should go something like: +// +// EXPORT_TEMPLATE_TEST(DEFAULT, __declspec(dllimport)); +// +// static_assert(EXPORT_TEMPLATE_INVOKE(TEST_DEFAULT, +// EXPORT_TEMPLATE_STYLE(__declspec(dllimport)), +// __declspec(dllimport)), "__declspec(dllimport)"); +// +// static_assert(EXPORT_TEMPLATE_INVOKE(TEST_DEFAULT, +// DEFAULT, __declspec(dllimport)), "__declspec(dllimport)"); +// +// static_assert(EXPORT_TEMPLATE_TEST_DEFAULT_DEFAULT( +// __declspec(dllimport)), "__declspec(dllimport)"); +// +// static_assert(true, "__declspec(dllimport)"); +// +// When they're not working correctly, a syntax error should occur instead. +#define EXPORT_TEMPLATE_TEST(want, foo_export) \ + static_assert( \ + EXPORT_TEMPLATE_INVOKE(TEST_##want, EXPORT_TEMPLATE_STYLE(foo_export), \ + foo_export), \ + #foo_export) +#define EXPORT_TEMPLATE_TEST_DEFAULT_DEFAULT(...) true +#define EXPORT_TEMPLATE_TEST_EXPORT_DLLEXPORT_EXPORT_DLLEXPORT(...) true + +EXPORT_TEMPLATE_TEST(DEFAULT, ); +EXPORT_TEMPLATE_TEST(DEFAULT, __attribute__((visibility("default")))); +EXPORT_TEMPLATE_TEST(EXPORT_DLLEXPORT, __declspec(dllexport)); +EXPORT_TEMPLATE_TEST(DEFAULT, __declspec(dllimport)); + +#undef EXPORT_TEMPLATE_TEST +#undef EXPORT_TEMPLATE_TEST_DEFAULT_DEFAULT +#undef EXPORT_TEMPLATE_TEST_EXPORT_DLLEXPORT_EXPORT_DLLEXPORT + +#endif // SHELL_ENCRYPTION_BASE_SHELL_ENCRYPTION_EXPORT_TEMPLATE_H_
diff --git a/third_party/shell-encryption/patches/0004-Support-SHELL-component-build.patch b/third_party/shell-encryption/patches/0004-Support-SHELL-component-build.patch new file mode 100644 index 0000000..55072fa3 --- /dev/null +++ b/third_party/shell-encryption/patches/0004-Support-SHELL-component-build.patch
@@ -0,0 +1,655 @@ +diff --git a/galois_key.h b/galois_key.h +index 0b73a63eff4d0..e6295f1082748 100644 +--- a/galois_key.h ++++ b/galois_key.h +@@ -23,6 +23,8 @@ + #include "relinearization_key.h" + #include "status_macros.h" + #include "statusor.h" ++#include "third_party/shell-encryption/base/shell_encryption_export.h" ++#include "third_party/shell-encryption/base/shell_encryption_export_template.h" + + namespace rlwe { + +@@ -41,7 +43,7 @@ namespace rlwe { + // + // Details can be found in Appendix D.2 of https://eprint.iacr.org/2011/566.pdf + template <typename ModularInt> +-class GaloisKey { ++class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) GaloisKey { + public: + // Initializes a GaloisKey based on a SymmetricRlweKey key that can key-switch + // two component ciphertexts. A positive log_decomposition_modulus corresponds +@@ -49,7 +51,7 @@ class GaloisKey { + // power of x in the secret key polynomial s(x^substitution_power) that the + // ciphertext is encrypted with. The prng_seed is used to generate and encode + // the bottom row of the matrix, which consists of random entries. +- static rlwe::StatusOr<GaloisKey> Create( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<GaloisKey> Create( + const SymmetricRlweKey<ModularInt>& key, absl::string_view prng_seed, + Uint64 substitution_power, Uint64 log_decomposition_modulus) { + RLWE_ASSIGN_OR_RETURN(auto relinearization_key, +@@ -88,7 +90,7 @@ class GaloisKey { + // SerializedGaloisKey is (2 * num_parts * dimension) where dimension is the + // number of digits needed to represent the modulus in base + // 2^{log_decomposition_modulus}. Crashes for non-valid input parameters. +- static rlwe::StatusOr<GaloisKey> Deserialize( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<GaloisKey> Deserialize( + const SerializedGaloisKey& serialized, + const typename ModularInt::Params* modulus_params, + const NttParameters<ModularInt>* ntt_params) { +@@ -110,6 +112,14 @@ class GaloisKey { + RelinearizationKey<ModularInt> relinearization_key_; + }; + ++template class EXPORT_TEMPLATE_DECLARE( ++ SHELL_ENCRYPTION_EXPORT) GaloisKey<rlwe::MontgomeryInt<Uint16>>; ++template class EXPORT_TEMPLATE_DECLARE( ++ SHELL_ENCRYPTION_EXPORT) GaloisKey<rlwe::MontgomeryInt<Uint32>>; ++template class EXPORT_TEMPLATE_DECLARE( ++ SHELL_ENCRYPTION_EXPORT) GaloisKey<rlwe::MontgomeryInt<Uint64>>; ++template class EXPORT_TEMPLATE_DECLARE( ++ SHELL_ENCRYPTION_EXPORT) GaloisKey<rlwe::MontgomeryInt<absl::uint128>>; + } // namespace rlwe + + #endif // RLWE_GALOIS_KEY_H_ +diff --git a/int256.h b/int256.h +index 540dce2d765b1..4c464a4978412 100644 +--- a/int256.h ++++ b/int256.h +@@ -18,13 +18,15 @@ + + #include "absl/numeric/int128.h" + #include "integral_types.h" ++#include "third_party/shell-encryption/base/shell_encryption_export.h" ++#include "third_party/shell-encryption/base/shell_encryption_export_template.h" + + namespace rlwe { + + struct uint256_pod; + + // An unsigned 256-bit integer type. Thread-compatible. +-class uint256 { ++class SHELL_ENCRYPTION_EXPORT uint256 { + public: + constexpr uint256(); + constexpr uint256(absl::uint128 top, absl::uint128 bottom); +@@ -74,11 +76,11 @@ class uint256 { + uint256& operator-=(const uint256& b); + uint256& operator*=(const uint256& b); + // Long division/modulo for uint256. +- uint256& operator/=(const uint256& b); +- uint256& operator%=(const uint256& b); ++ SHELL_ENCRYPTION_EXPORT uint256& operator/=(const uint256& b); ++ SHELL_ENCRYPTION_EXPORT uint256& operator%=(const uint256& b); + uint256 operator++(int); + uint256 operator--(int); +- uint256& operator<<=(int); ++ SHELL_ENCRYPTION_EXPORT uint256& operator<<=(int); + uint256& operator>>=(int); + uint256& operator&=(const uint256& b); + uint256& operator|=(const uint256& b); +@@ -90,7 +92,7 @@ class uint256 { + friend absl::uint128 Uint256High128(const uint256& v); + + // We add "std::" to avoid including all of port.h. +- friend std::ostream& operator<<(std::ostream& o, const uint256& b); ++ friend SHELL_ENCRYPTION_EXPORT std::ostream& operator<<(std::ostream& o, const uint256& b); + + private: + static void DivModImpl(uint256 dividend, uint256 divisor, +@@ -121,7 +123,7 @@ constexpr uint256 Uint256Max() { + + // This is a POD form of uint256 which can be used for static variables which + // need to be operated on as uint256. +-struct uint256_pod { ++struct SHELL_ENCRYPTION_EXPORT uint256_pod { + // Note: The ordering of fields is different than 'class uint256' but the + // same as its 2-arg constructor. This enables more obvious initialization + // of static instances, which is the primary reason for this struct in the +diff --git a/montgomery.cc b/montgomery.cc +index 9fbc5dabee18c..4bd03362420fc 100644 +--- a/montgomery.cc ++++ b/montgomery.cc +@@ -14,6 +14,8 @@ + + #include "montgomery.h" + ++#include "third_party/shell-encryption/base/shell_encryption_export.h" ++#include "third_party/shell-encryption/base/shell_encryption_export_template.h" + #include "transcription.h" + + namespace rlwe { +@@ -416,12 +418,12 @@ MontgomeryInt<T> MontgomeryInt<T>::MultiplicativeInverse( + + // Instantiations of MontgomeryInt and MontgomeryIntParams with specific + // integral types. +-template struct MontgomeryIntParams<Uint16>; +-template struct MontgomeryIntParams<Uint32>; +-template struct MontgomeryIntParams<Uint64>; +-template struct MontgomeryIntParams<absl::uint128>; +-template class MontgomeryInt<Uint16>; +-template class MontgomeryInt<Uint32>; +-template class MontgomeryInt<Uint64>; +-template class MontgomeryInt<absl::uint128>; ++template struct EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint16>; ++template struct EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint32>; ++template struct EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint64>; ++template struct EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<absl::uint128>; ++template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint16>; ++template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint32>; ++template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint64>; ++template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<absl::uint128>; + } // namespace rlwe +diff --git a/montgomery.h b/montgomery.h +index 4f0e2eafb815f..c3988ff34da34 100644 +--- a/montgomery.h ++++ b/montgomery.h +@@ -34,6 +34,8 @@ + #include "serialization.pb.h" + #include "status_macros.h" + #include "statusor.h" ++#include "third_party/shell-encryption/base/shell_encryption_export.h" ++#include "third_party/shell-encryption/base/shell_encryption_export_template.h" + + namespace rlwe { + +@@ -43,24 +45,24 @@ namespace internal { + template <typename T> + struct BigInt; + // Specialization for uint8, uint16, uint32, uint64, and uint128. +-template <> +-struct BigInt<Uint8> { ++template <> ++struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) BigInt<Uint8> { + typedef Uint16 value_type; + }; +-template <> +-struct BigInt<Uint16> { ++template <> ++struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) BigInt<Uint16> { + typedef Uint32 value_type; + }; +-template <> +-struct BigInt<Uint32> { ++template <> ++struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) BigInt<Uint32> { + typedef Uint64 value_type; + }; +-template <> +-struct BigInt<Uint64> { ++template <> ++struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) BigInt<Uint64> { + typedef absl::uint128 value_type; + }; +-template <> +-struct BigInt<absl::uint128> { ++template <> ++struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) BigInt<absl::uint128> { + typedef uint256 value_type; + }; + +@@ -69,7 +71,7 @@ struct BigInt<absl::uint128> { + // The parameters necessary for a Montgomery integer. Note that the template + // parameters ensure that T is an unsigned integral of at least 8 bits. + template <typename T> +-struct MontgomeryIntParams { ++struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams{ + // Expose Int and its greater type. BigInt is required in order to multiply + // two Int and ensure that no overflow occurs. + // +@@ -159,7 +161,7 @@ struct MontgomeryIntParams { + // modulus must be odd. + // Returns a tuple of (inv_r, inv_modulus) such that: + // r * inv_r - modulus * inv_modulus = 1 +- static std::tuple<Int, Int> Inverses(BigInt modulus_bigint, BigInt r); ++ static SHELL_ENCRYPTION_EXPORT std::tuple<Int, Int> Inverses(BigInt modulus_bigint, BigInt r); + }; + + // Stores an integer in Montgomery representation. The goal of this +@@ -170,7 +172,7 @@ struct MontgomeryIntParams { + // The underlying integer type T must be unsigned and must not be bool. + // This class is thread safe. + template <typename T> +-class ABSL_MUST_USE_RESULT MontgomeryInt { ++class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) ABSL_MUST_USE_RESULT MontgomeryInt { + public: + // Expose Int and its greater type. BigInt is required in order to multiply + // two Int and ensure that no overflow occurs. This should also be used by +@@ -184,16 +186,16 @@ class ABSL_MUST_USE_RESULT MontgomeryInt { + // Static factory that converts a non-Montgomery representation integer, the + // underlying integer type, into a Montgomery representation integer. Does not + // take ownership of params. i.e., import "a". +- static rlwe::StatusOr<MontgomeryInt> ImportInt(Int n, const Params* params); ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<MontgomeryInt> ImportInt(Int n, const Params* params); + + // Static functions to create a MontgomeryInt of 0 and 1. +- static MontgomeryInt ImportZero(const Params* params); +- static MontgomeryInt ImportOne(const Params* params); ++ static SHELL_ENCRYPTION_EXPORT MontgomeryInt ImportZero(const Params* params); ++ static SHELL_ENCRYPTION_EXPORT MontgomeryInt ImportOne(const Params* params); + + // Import a random integer using entropy from specified prng. Does not take + // ownership of params or prng. + template <typename Prng = rlwe::SecurePrng> +- static rlwe::StatusOr<MontgomeryInt> ImportRandom(Prng* prng, ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<MontgomeryInt> ImportRandom(Prng* prng, + const Params* params) { + // In order to generate unbiased randomness, we uniformly and randomly + // sample integers in [0, 2^params->log_modulus) until the generated integer +@@ -234,13 +236,13 @@ class ABSL_MUST_USE_RESULT MontgomeryInt { + + // Serialization. + rlwe::StatusOr<std::string> Serialize(const Params* params) const; +- static rlwe::StatusOr<std::string> SerializeVector( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::string> SerializeVector( + const std::vector<MontgomeryInt>& coeffs, const Params* params); + + // Deserialization. +- static rlwe::StatusOr<MontgomeryInt> Deserialize(absl::string_view payload, ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<MontgomeryInt> Deserialize(absl::string_view payload, + const Params* params); +- static rlwe::StatusOr<std::vector<MontgomeryInt>> DeserializeVector( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> DeserializeVector( + int num_coeffs, absl::string_view serialized, const Params* params); + + // Modular multiplication. +@@ -353,7 +355,7 @@ class ABSL_MUST_USE_RESULT MontgomeryInt { + // size. + + // Batch addition of two vectors. +- static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchAdd( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchAdd( + const std::vector<MontgomeryInt>& in1, + const std::vector<MontgomeryInt>& in2, const Params* params); + static absl::Status BatchAddInPlace(std::vector<MontgomeryInt>* in1, +@@ -361,7 +363,7 @@ class ABSL_MUST_USE_RESULT MontgomeryInt { + const Params* params); + + // Batch addition of one vector with a scalar. +- static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchAdd( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchAdd( + const std::vector<MontgomeryInt>& in1, const MontgomeryInt& in2, + const Params* params); + static absl::Status BatchAddInPlace(std::vector<MontgomeryInt>* in1, +@@ -369,51 +371,51 @@ class ABSL_MUST_USE_RESULT MontgomeryInt { + const Params* params); + + // Batch subtraction of two vectors. +- static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchSub( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchSub( + const std::vector<MontgomeryInt>& in1, + const std::vector<MontgomeryInt>& in2, const Params* params); +- static absl::Status BatchSubInPlace(std::vector<MontgomeryInt>* in1, ++ static SHELL_ENCRYPTION_EXPORT absl::Status BatchSubInPlace(std::vector<MontgomeryInt>* in1, + const std::vector<MontgomeryInt>& in2, + const Params* params); + + // Batch subtraction of one vector with a scalar. +- static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchSub( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchSub( + const std::vector<MontgomeryInt>& in1, const MontgomeryInt& in2, + const Params* params); +- static absl::Status BatchSubInPlace(std::vector<MontgomeryInt>* in1, ++ static SHELL_ENCRYPTION_EXPORT absl::Status BatchSubInPlace(std::vector<MontgomeryInt>* in1, + const MontgomeryInt& in2, + const Params* params); + + // Batch multiplication of two vectors. +- static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMul( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMul( + const std::vector<MontgomeryInt>& in1, + const std::vector<MontgomeryInt>& in2, const Params* params); +- static absl::Status BatchMulInPlace(std::vector<MontgomeryInt>* in1, ++ static SHELL_ENCRYPTION_EXPORT absl::Status BatchMulInPlace(std::vector<MontgomeryInt>* in1, + const std::vector<MontgomeryInt>& in2, + const Params* params); + + // Batch multiplication of two vectors, where the second vector is a constant. +- static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMulConstant( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMulConstant( + const std::vector<MontgomeryInt>& in1, + const std::vector<Int>& in2_constant, + const std::vector<Int>& in2_constant_barrett, const Params* params); +- static absl::Status BatchMulConstantInPlace( ++ static SHELL_ENCRYPTION_EXPORT absl::Status BatchMulConstantInPlace( + std::vector<MontgomeryInt>* in1, const std::vector<Int>& in2_constant, + const std::vector<Int>& in2_constant_barrett, const Params* params); + + // Batch multiplication of a vector with a scalar. +- static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMul( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMul( + const std::vector<MontgomeryInt>& in1, const MontgomeryInt& in2, + const Params* params); +- static absl::Status BatchMulInPlace(std::vector<MontgomeryInt>* in1, ++ static SHELL_ENCRYPTION_EXPORT absl::Status BatchMulInPlace(std::vector<MontgomeryInt>* in1, + const MontgomeryInt& in2, + const Params* params); + + // Batch multiplication of a vector with a constant scalar. +- static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMulConstant( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMulConstant( + const std::vector<MontgomeryInt>& in1, const Int& constant, + const Int& constant_barrett, const Params* params); +- static absl::Status BatchMulConstantInPlace(std::vector<MontgomeryInt>* in1, ++ static SHELL_ENCRYPTION_EXPORT absl::Status BatchMulConstantInPlace(std::vector<MontgomeryInt>* in1, + const Int& constant, + const Int& constant_barrett, + const Params* params); +@@ -423,14 +425,14 @@ class ABSL_MUST_USE_RESULT MontgomeryInt { + bool operator!=(const MontgomeryInt& that) const { return !(*this == that); } + + // Modular exponentiation. +- MontgomeryInt ModExp(Int exponent, const Params* params) const; ++ SHELL_ENCRYPTION_EXPORT MontgomeryInt ModExp(Int exponent, const Params* params) const; + + // Inverse. +- MontgomeryInt MultiplicativeInverse(const Params* params) const; ++ SHELL_ENCRYPTION_EXPORT MontgomeryInt MultiplicativeInverse(const Params* params) const; + + private: + template <typename Prng = rlwe::SecurePrng> +- static rlwe::StatusOr<Int> GenerateRandomInt(int log_modulus, Prng* prng) { ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<Int> GenerateRandomInt(int log_modulus, Prng* prng) { + // Generate a random Int. As the modulus is always smaller than max(Int), + // there will be no issues with overflow. + int max_bits_per_step = std::min((int)Params::bitsize_int, (int)64); +@@ -467,6 +469,17 @@ class ABSL_MUST_USE_RESULT MontgomeryInt { + Int n_; + }; + ++// Instantiations of MontgomeryInt and MontgomeryIntParams with specific ++// integral types. ++extern template struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint16>; ++extern template struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint32>; ++extern template struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint64>; ++extern template struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<absl::uint128>; ++extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint16>; ++extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint32>; ++extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint64>; ++extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<absl::uint128>; ++ + } // namespace rlwe + + #endif // RLWE_MONTGOMERY_H_ +diff --git a/montgomery_test.cc b/montgomery_test.cc +index 7caf459a4c08b..2d952ddfbdad4 100644 +--- a/montgomery_test.cc ++++ b/montgomery_test.cc +@@ -30,6 +30,8 @@ + #include "testing/status_matchers.h" + #include "testing/status_testing.h" + #include "testing/testing_prng.h" ++#include "third_party/shell-encryption/base/shell_encryption_export.h" ++#include "third_party/shell-encryption/base/shell_encryption_export_template.h" + + namespace rlwe { + namespace { +@@ -65,7 +67,7 @@ uint256 GenerateRandom(unsigned int* seed) { + } + + template <typename T> +-class MontgomeryTest : public ::testing::Test {}; ++class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryTest : public ::testing::Test {}; + TYPED_TEST_SUITE(MontgomeryTest, testing::ModularIntTypes); + + TYPED_TEST(MontgomeryTest, ModulusTooLarge) { +diff --git a/ntt_parameters.h b/ntt_parameters.h +index 55671ec5e65de..eba9579ab87ca 100644 +--- a/ntt_parameters.h ++++ b/ntt_parameters.h +@@ -24,6 +24,7 @@ + #include "constants.h" + #include "status_macros.h" + #include "statusor.h" ++#include "third_party/shell-encryption/base/shell_encryption_export.h" + + namespace rlwe { + namespace internal { +@@ -94,7 +95,7 @@ rlwe::StatusOr<std::vector<ModularInt>> NttPsis( + // Creates a vector containing the indices necessary to perform the NTT bit + // reversal operation. Index i of the returned vector contains an integer with + // the rightmost log_n bits of i reversed. +-std::vector<unsigned int> BitrevArray(unsigned int log_n); ++SHELL_ENCRYPTION_EXPORT std::vector<unsigned int> BitrevArray(unsigned int log_n); + + // Helper function: Perform the bit-reversal operation in-place on coeffs_. + template <typename ModularInt> +diff --git a/prng/chacha_prng.h b/prng/chacha_prng.h +index 27940fd82c646..7e4f719fedaf6 100644 +--- a/prng/chacha_prng.h ++++ b/prng/chacha_prng.h +@@ -26,6 +26,7 @@ + #include "prng/chacha_prng_util.h" + #include "prng/prng.h" + #include "statusor.h" ++#include "third_party/shell-encryption/base/shell_encryption_export.h" + + namespace rlwe { + +@@ -56,7 +57,7 @@ class ChaChaPrng : public SecurePrng { + // errors. + // + // Thread safe. +- static rlwe::StatusOr<std::unique_ptr<ChaChaPrng>> Create( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::unique_ptr<ChaChaPrng>> Create( + absl::string_view in_key); + + // Returns 8 bits of randomness. +@@ -72,12 +73,12 @@ class ChaChaPrng : public SecurePrng { + // Generate a valid seed for the Prng. + // + // Fails on internal cryptographic errors. +- static rlwe::StatusOr<std::string> GenerateSeed() { ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::string> GenerateSeed() { + return internal::ChaChaPrngGenerateKey(); + } + + // Output the size of the expected generated seed. +- static int SeedLength() { return internal::kChaChaKeyBytesSize; } ++ static SHELL_ENCRYPTION_EXPORT int SeedLength() { return internal::kChaChaKeyBytesSize; } + + private: + explicit ChaChaPrng(absl::string_view in_key, int position_in_buffer, +diff --git a/prng/chacha_prng_util.h b/prng/chacha_prng_util.h +index 8eb8118fe26f9..80f0cedf4a703 100644 +--- a/prng/chacha_prng_util.h ++++ b/prng/chacha_prng_util.h +@@ -27,6 +27,7 @@ + #include "absl/strings/string_view.h" + #include "integral_types.h" + #include "statusor.h" ++#include "third_party/shell-encryption/base/shell_encryption_export.h" + + namespace rlwe { + namespace internal { +@@ -37,28 +38,33 @@ const int kChaChaOutputBytes = 255 * 32; + + // Once pseudorandom output is exhausted, the salt is updated to construct + // new pseudorandom output. +-absl::Status ChaChaPrngResalt(absl::string_view key, int buffer_size, +- int* salt_counter, int* position_in_buffer, +- std::vector<Uint8>* buffer); ++SHELL_ENCRYPTION_EXPORT absl::Status ChaChaPrngResalt( ++ absl::string_view key, ++ int buffer_size, ++ int* salt_counter, ++ int* position_in_buffer, ++ std::vector<Uint8>* buffer); + + // Generates a secure key for instantiating an CHACHA. +-rlwe::StatusOr<std::string> ChaChaPrngGenerateKey(); ++SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::string> ChaChaPrngGenerateKey(); + + // Returns 8 bits of randomness. + // + // Fails on internal cryptographic errors. +-rlwe::StatusOr<Uint8> ChaChaPrngRand8(absl::string_view key, +- int* position_in_buffer, +- int* salt_counter, +- std::vector<Uint8>* buffer); ++SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<Uint8> ChaChaPrngRand8( ++ absl::string_view key, ++ int* position_in_buffer, ++ int* salt_counter, ++ std::vector<Uint8>* buffer); + + // Returns 64 bits of randomness. + // + // Fails on internal cryptographic errors. +-rlwe::StatusOr<Uint64> ChaChaPrngRand64(absl::string_view key, +- int* position_in_buffer, +- int* salt_counter, +- std::vector<Uint8>* buffer); ++SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<Uint64> ChaChaPrngRand64( ++ absl::string_view key, ++ int* position_in_buffer, ++ int* salt_counter, ++ std::vector<Uint8>* buffer); + + } // namespace internal + } // namespace rlwe +diff --git a/prng/single_thread_chacha_prng.h b/prng/single_thread_chacha_prng.h +index fcaff827be355..2fddf6f3530c4 100644 +--- a/prng/single_thread_chacha_prng.h ++++ b/prng/single_thread_chacha_prng.h +@@ -24,6 +24,7 @@ + #include "prng/chacha_prng_util.h" + #include "prng/prng.h" + #include "statusor.h" ++#include "third_party/shell-encryption/base/shell_encryption_export.h" + + namespace rlwe { + +@@ -52,7 +53,7 @@ class SingleThreadChaChaPrng : public SecurePrng { + // + // Fails if the key is not the expected size or on internal cryptographic + // errors. +- static rlwe::StatusOr<std::unique_ptr<SingleThreadChaChaPrng>> Create( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::unique_ptr<SingleThreadChaChaPrng>> Create( + absl::string_view in_key); + + // Returns 8 bits of randomness. +diff --git a/relinearization_key.cc b/relinearization_key.cc +index 7982a2f71a74c..0b22a50e0abb7 100644 +--- a/relinearization_key.cc ++++ b/relinearization_key.cc +@@ -22,6 +22,8 @@ + #include "status_macros.h" + #include "statusor.h" + #include "symmetric_encryption_with_prng.h" ++#include "third_party/shell-encryption/base/shell_encryption_export.h" ++#include "third_party/shell-encryption/base/shell_encryption_export_template.h" + + namespace rlwe { + namespace { +@@ -432,9 +434,9 @@ RelinearizationKey<ModularInt>::Deserialize( + // Instantiations of RelinearizationKey with specific MontgomeryInt classes. + // If any new types are added, montgomery.h should be updated accordingly (such + // as ensuring BigInt is correctly specialized, etc.). +-template class RelinearizationKey<MontgomeryInt<Uint16>>; +-template class RelinearizationKey<MontgomeryInt<Uint32>>; +-template class RelinearizationKey<MontgomeryInt<Uint64>>; +-template class RelinearizationKey<MontgomeryInt<absl::uint128>>; ++template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint16>>; ++template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint32>>; ++template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint64>>; ++template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<absl::uint128>>; + + } // namespace rlwe +diff --git a/relinearization_key.h b/relinearization_key.h +index 265da33e5af15..1aff179b9ed39 100644 +--- a/relinearization_key.h ++++ b/relinearization_key.h +@@ -22,6 +22,8 @@ + #include "sample_error.h" + #include "statusor.h" + #include "symmetric_encryption.h" ++#include "third_party/shell-encryption/base/shell_encryption_export.h" ++#include "third_party/shell-encryption/base/shell_encryption_export_template.h" + + namespace rlwe { + // Represents a RelinearizationKey constructed from a symmetric-key. Applying a +@@ -57,7 +59,7 @@ namespace rlwe { + // length (k - 1), where k is the number of parts of the ciphertext it applies + // to. + template <typename ModularInt> +-class RelinearizationKey { ++class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey { + using ModularIntParams = typename ModularInt::Params; + + public: +@@ -73,7 +75,7 @@ class RelinearizationKey { + // with (1, s^k). In that case, we would use a relinearization key with + // substition_power = k to return the ciphertext to be encrypted with (1,s). + // See GaloisKey for an explicit wrapper around RelinearizationKey. +- static rlwe::StatusOr<RelinearizationKey> Create( ++ static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<RelinearizationKey> Create( + const SymmetricRlweKey<ModularInt>& key, absl::string_view prng_seed, + ssize_t num_parts, Uint64 log_decomposition_modulus, + Uint64 substitution_power = 1); +@@ -192,6 +194,13 @@ class RelinearizationKey { + std::string prng_seed_; + }; + ++// Instantiations of RelinearizationKey with specific MontgomeryInt classes. ++// If any new types are added, montgomery.h should be updated accordingly (such ++// as ensuring BigInt is correctly specialized, etc.). ++extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint16>>; ++extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint32>>; ++extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint64>>; ++extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<absl::uint128>>; + } // namespace rlwe + + #endif // RLWE_RELINEARIZATION_KEY_H_ +diff --git a/statusor.h b/statusor.h +index 200f62d917d0f..b7ada09372c9f 100644 +--- a/statusor.h ++++ b/statusor.h +@@ -22,11 +22,12 @@ + #include "absl/base/attributes.h" + #include "absl/status/status.h" + #include "absl/types/optional.h" ++#include "third_party/shell-encryption/base/shell_encryption_export.h" + + namespace rlwe { + + template <typename T> +-class StatusOr { ++class SHELL_ENCRYPTION_EXPORT StatusOr { + public: + // Construct a new StatusOr with Status::UNKNOWN status + StatusOr(); +@@ -112,12 +113,12 @@ class StatusOr { + + namespace internal { + +-class StatusOrHelper { ++class SHELL_ENCRYPTION_EXPORT StatusOrHelper { + public: + // Move type-agnostic error handling to the .cc. +- static absl::Status HandleInvalidStatusCtorArg(); +- static absl::Status HandleNullObjectCtorArg(); +- static void Crash(const absl::Status& status); ++ static SHELL_ENCRYPTION_EXPORT absl::Status HandleInvalidStatusCtorArg(); ++ static SHELL_ENCRYPTION_EXPORT absl::Status HandleNullObjectCtorArg(); ++ static SHELL_ENCRYPTION_EXPORT void Crash(const absl::Status& status); + + // Customized behavior for StatusOr<T> vs. StatusOr<T*> + template <typename T> +@@ -125,13 +126,13 @@ class StatusOrHelper { + }; + + template <typename T> +-struct StatusOrHelper::Specialize { ++struct SHELL_ENCRYPTION_EXPORT StatusOrHelper::Specialize { + // For non-pointer T, a reference can never be NULL. + static inline bool IsValueNull(const T& t) { return false; } + }; + + template <typename T> +-struct StatusOrHelper::Specialize<T*> { ++struct SHELL_ENCRYPTION_EXPORT StatusOrHelper::Specialize<T*> { + static inline bool IsValueNull(const T* t) { return t == nullptr; } + }; +
diff --git a/third_party/shell-encryption/src/galois_key.h b/third_party/shell-encryption/src/galois_key.h index 0b73a63..e6295f1 100644 --- a/third_party/shell-encryption/src/galois_key.h +++ b/third_party/shell-encryption/src/galois_key.h
@@ -23,6 +23,8 @@ #include "relinearization_key.h" #include "status_macros.h" #include "statusor.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" +#include "third_party/shell-encryption/base/shell_encryption_export_template.h" namespace rlwe { @@ -41,7 +43,7 @@ // // Details can be found in Appendix D.2 of https://eprint.iacr.org/2011/566.pdf template <typename ModularInt> -class GaloisKey { +class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) GaloisKey { public: // Initializes a GaloisKey based on a SymmetricRlweKey key that can key-switch // two component ciphertexts. A positive log_decomposition_modulus corresponds @@ -49,7 +51,7 @@ // power of x in the secret key polynomial s(x^substitution_power) that the // ciphertext is encrypted with. The prng_seed is used to generate and encode // the bottom row of the matrix, which consists of random entries. - static rlwe::StatusOr<GaloisKey> Create( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<GaloisKey> Create( const SymmetricRlweKey<ModularInt>& key, absl::string_view prng_seed, Uint64 substitution_power, Uint64 log_decomposition_modulus) { RLWE_ASSIGN_OR_RETURN(auto relinearization_key, @@ -88,7 +90,7 @@ // SerializedGaloisKey is (2 * num_parts * dimension) where dimension is the // number of digits needed to represent the modulus in base // 2^{log_decomposition_modulus}. Crashes for non-valid input parameters. - static rlwe::StatusOr<GaloisKey> Deserialize( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<GaloisKey> Deserialize( const SerializedGaloisKey& serialized, const typename ModularInt::Params* modulus_params, const NttParameters<ModularInt>* ntt_params) { @@ -110,6 +112,14 @@ RelinearizationKey<ModularInt> relinearization_key_; }; +template class EXPORT_TEMPLATE_DECLARE( + SHELL_ENCRYPTION_EXPORT) GaloisKey<rlwe::MontgomeryInt<Uint16>>; +template class EXPORT_TEMPLATE_DECLARE( + SHELL_ENCRYPTION_EXPORT) GaloisKey<rlwe::MontgomeryInt<Uint32>>; +template class EXPORT_TEMPLATE_DECLARE( + SHELL_ENCRYPTION_EXPORT) GaloisKey<rlwe::MontgomeryInt<Uint64>>; +template class EXPORT_TEMPLATE_DECLARE( + SHELL_ENCRYPTION_EXPORT) GaloisKey<rlwe::MontgomeryInt<absl::uint128>>; } // namespace rlwe #endif // RLWE_GALOIS_KEY_H_
diff --git a/third_party/shell-encryption/src/int256.h b/third_party/shell-encryption/src/int256.h index 540dce2d..4c464a4 100644 --- a/third_party/shell-encryption/src/int256.h +++ b/third_party/shell-encryption/src/int256.h
@@ -18,13 +18,15 @@ #include "absl/numeric/int128.h" #include "integral_types.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" +#include "third_party/shell-encryption/base/shell_encryption_export_template.h" namespace rlwe { struct uint256_pod; // An unsigned 256-bit integer type. Thread-compatible. -class uint256 { +class SHELL_ENCRYPTION_EXPORT uint256 { public: constexpr uint256(); constexpr uint256(absl::uint128 top, absl::uint128 bottom); @@ -74,11 +76,11 @@ uint256& operator-=(const uint256& b); uint256& operator*=(const uint256& b); // Long division/modulo for uint256. - uint256& operator/=(const uint256& b); - uint256& operator%=(const uint256& b); + SHELL_ENCRYPTION_EXPORT uint256& operator/=(const uint256& b); + SHELL_ENCRYPTION_EXPORT uint256& operator%=(const uint256& b); uint256 operator++(int); uint256 operator--(int); - uint256& operator<<=(int); + SHELL_ENCRYPTION_EXPORT uint256& operator<<=(int); uint256& operator>>=(int); uint256& operator&=(const uint256& b); uint256& operator|=(const uint256& b); @@ -90,7 +92,7 @@ friend absl::uint128 Uint256High128(const uint256& v); // We add "std::" to avoid including all of port.h. - friend std::ostream& operator<<(std::ostream& o, const uint256& b); + friend SHELL_ENCRYPTION_EXPORT std::ostream& operator<<(std::ostream& o, const uint256& b); private: static void DivModImpl(uint256 dividend, uint256 divisor, @@ -121,7 +123,7 @@ // This is a POD form of uint256 which can be used for static variables which // need to be operated on as uint256. -struct uint256_pod { +struct SHELL_ENCRYPTION_EXPORT uint256_pod { // Note: The ordering of fields is different than 'class uint256' but the // same as its 2-arg constructor. This enables more obvious initialization // of static instances, which is the primary reason for this struct in the
diff --git a/third_party/shell-encryption/src/montgomery.cc b/third_party/shell-encryption/src/montgomery.cc index 9fbc5dab..4bd0336 100644 --- a/third_party/shell-encryption/src/montgomery.cc +++ b/third_party/shell-encryption/src/montgomery.cc
@@ -14,6 +14,8 @@ #include "montgomery.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" +#include "third_party/shell-encryption/base/shell_encryption_export_template.h" #include "transcription.h" namespace rlwe { @@ -416,12 +418,12 @@ // Instantiations of MontgomeryInt and MontgomeryIntParams with specific // integral types. -template struct MontgomeryIntParams<Uint16>; -template struct MontgomeryIntParams<Uint32>; -template struct MontgomeryIntParams<Uint64>; -template struct MontgomeryIntParams<absl::uint128>; -template class MontgomeryInt<Uint16>; -template class MontgomeryInt<Uint32>; -template class MontgomeryInt<Uint64>; -template class MontgomeryInt<absl::uint128>; +template struct EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint16>; +template struct EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint32>; +template struct EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint64>; +template struct EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<absl::uint128>; +template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint16>; +template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint32>; +template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint64>; +template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<absl::uint128>; } // namespace rlwe
diff --git a/third_party/shell-encryption/src/montgomery.h b/third_party/shell-encryption/src/montgomery.h index 4f0e2eaf..c3988ff3 100644 --- a/third_party/shell-encryption/src/montgomery.h +++ b/third_party/shell-encryption/src/montgomery.h
@@ -34,6 +34,8 @@ #include "serialization.pb.h" #include "status_macros.h" #include "statusor.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" +#include "third_party/shell-encryption/base/shell_encryption_export_template.h" namespace rlwe { @@ -43,24 +45,24 @@ template <typename T> struct BigInt; // Specialization for uint8, uint16, uint32, uint64, and uint128. -template <> -struct BigInt<Uint8> { +template <> +struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) BigInt<Uint8> { typedef Uint16 value_type; }; -template <> -struct BigInt<Uint16> { +template <> +struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) BigInt<Uint16> { typedef Uint32 value_type; }; -template <> -struct BigInt<Uint32> { +template <> +struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) BigInt<Uint32> { typedef Uint64 value_type; }; -template <> -struct BigInt<Uint64> { +template <> +struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) BigInt<Uint64> { typedef absl::uint128 value_type; }; -template <> -struct BigInt<absl::uint128> { +template <> +struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) BigInt<absl::uint128> { typedef uint256 value_type; }; @@ -69,7 +71,7 @@ // The parameters necessary for a Montgomery integer. Note that the template // parameters ensure that T is an unsigned integral of at least 8 bits. template <typename T> -struct MontgomeryIntParams { +struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams{ // Expose Int and its greater type. BigInt is required in order to multiply // two Int and ensure that no overflow occurs. // @@ -159,7 +161,7 @@ // modulus must be odd. // Returns a tuple of (inv_r, inv_modulus) such that: // r * inv_r - modulus * inv_modulus = 1 - static std::tuple<Int, Int> Inverses(BigInt modulus_bigint, BigInt r); + static SHELL_ENCRYPTION_EXPORT std::tuple<Int, Int> Inverses(BigInt modulus_bigint, BigInt r); }; // Stores an integer in Montgomery representation. The goal of this @@ -170,7 +172,7 @@ // The underlying integer type T must be unsigned and must not be bool. // This class is thread safe. template <typename T> -class ABSL_MUST_USE_RESULT MontgomeryInt { +class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) ABSL_MUST_USE_RESULT MontgomeryInt { public: // Expose Int and its greater type. BigInt is required in order to multiply // two Int and ensure that no overflow occurs. This should also be used by @@ -184,16 +186,16 @@ // Static factory that converts a non-Montgomery representation integer, the // underlying integer type, into a Montgomery representation integer. Does not // take ownership of params. i.e., import "a". - static rlwe::StatusOr<MontgomeryInt> ImportInt(Int n, const Params* params); + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<MontgomeryInt> ImportInt(Int n, const Params* params); // Static functions to create a MontgomeryInt of 0 and 1. - static MontgomeryInt ImportZero(const Params* params); - static MontgomeryInt ImportOne(const Params* params); + static SHELL_ENCRYPTION_EXPORT MontgomeryInt ImportZero(const Params* params); + static SHELL_ENCRYPTION_EXPORT MontgomeryInt ImportOne(const Params* params); // Import a random integer using entropy from specified prng. Does not take // ownership of params or prng. template <typename Prng = rlwe::SecurePrng> - static rlwe::StatusOr<MontgomeryInt> ImportRandom(Prng* prng, + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<MontgomeryInt> ImportRandom(Prng* prng, const Params* params) { // In order to generate unbiased randomness, we uniformly and randomly // sample integers in [0, 2^params->log_modulus) until the generated integer @@ -234,13 +236,13 @@ // Serialization. rlwe::StatusOr<std::string> Serialize(const Params* params) const; - static rlwe::StatusOr<std::string> SerializeVector( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::string> SerializeVector( const std::vector<MontgomeryInt>& coeffs, const Params* params); // Deserialization. - static rlwe::StatusOr<MontgomeryInt> Deserialize(absl::string_view payload, + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<MontgomeryInt> Deserialize(absl::string_view payload, const Params* params); - static rlwe::StatusOr<std::vector<MontgomeryInt>> DeserializeVector( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> DeserializeVector( int num_coeffs, absl::string_view serialized, const Params* params); // Modular multiplication. @@ -353,7 +355,7 @@ // size. // Batch addition of two vectors. - static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchAdd( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchAdd( const std::vector<MontgomeryInt>& in1, const std::vector<MontgomeryInt>& in2, const Params* params); static absl::Status BatchAddInPlace(std::vector<MontgomeryInt>* in1, @@ -361,7 +363,7 @@ const Params* params); // Batch addition of one vector with a scalar. - static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchAdd( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchAdd( const std::vector<MontgomeryInt>& in1, const MontgomeryInt& in2, const Params* params); static absl::Status BatchAddInPlace(std::vector<MontgomeryInt>* in1, @@ -369,51 +371,51 @@ const Params* params); // Batch subtraction of two vectors. - static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchSub( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchSub( const std::vector<MontgomeryInt>& in1, const std::vector<MontgomeryInt>& in2, const Params* params); - static absl::Status BatchSubInPlace(std::vector<MontgomeryInt>* in1, + static SHELL_ENCRYPTION_EXPORT absl::Status BatchSubInPlace(std::vector<MontgomeryInt>* in1, const std::vector<MontgomeryInt>& in2, const Params* params); // Batch subtraction of one vector with a scalar. - static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchSub( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchSub( const std::vector<MontgomeryInt>& in1, const MontgomeryInt& in2, const Params* params); - static absl::Status BatchSubInPlace(std::vector<MontgomeryInt>* in1, + static SHELL_ENCRYPTION_EXPORT absl::Status BatchSubInPlace(std::vector<MontgomeryInt>* in1, const MontgomeryInt& in2, const Params* params); // Batch multiplication of two vectors. - static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMul( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMul( const std::vector<MontgomeryInt>& in1, const std::vector<MontgomeryInt>& in2, const Params* params); - static absl::Status BatchMulInPlace(std::vector<MontgomeryInt>* in1, + static SHELL_ENCRYPTION_EXPORT absl::Status BatchMulInPlace(std::vector<MontgomeryInt>* in1, const std::vector<MontgomeryInt>& in2, const Params* params); // Batch multiplication of two vectors, where the second vector is a constant. - static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMulConstant( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMulConstant( const std::vector<MontgomeryInt>& in1, const std::vector<Int>& in2_constant, const std::vector<Int>& in2_constant_barrett, const Params* params); - static absl::Status BatchMulConstantInPlace( + static SHELL_ENCRYPTION_EXPORT absl::Status BatchMulConstantInPlace( std::vector<MontgomeryInt>* in1, const std::vector<Int>& in2_constant, const std::vector<Int>& in2_constant_barrett, const Params* params); // Batch multiplication of a vector with a scalar. - static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMul( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMul( const std::vector<MontgomeryInt>& in1, const MontgomeryInt& in2, const Params* params); - static absl::Status BatchMulInPlace(std::vector<MontgomeryInt>* in1, + static SHELL_ENCRYPTION_EXPORT absl::Status BatchMulInPlace(std::vector<MontgomeryInt>* in1, const MontgomeryInt& in2, const Params* params); // Batch multiplication of a vector with a constant scalar. - static rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMulConstant( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::vector<MontgomeryInt>> BatchMulConstant( const std::vector<MontgomeryInt>& in1, const Int& constant, const Int& constant_barrett, const Params* params); - static absl::Status BatchMulConstantInPlace(std::vector<MontgomeryInt>* in1, + static SHELL_ENCRYPTION_EXPORT absl::Status BatchMulConstantInPlace(std::vector<MontgomeryInt>* in1, const Int& constant, const Int& constant_barrett, const Params* params); @@ -423,14 +425,14 @@ bool operator!=(const MontgomeryInt& that) const { return !(*this == that); } // Modular exponentiation. - MontgomeryInt ModExp(Int exponent, const Params* params) const; + SHELL_ENCRYPTION_EXPORT MontgomeryInt ModExp(Int exponent, const Params* params) const; // Inverse. - MontgomeryInt MultiplicativeInverse(const Params* params) const; + SHELL_ENCRYPTION_EXPORT MontgomeryInt MultiplicativeInverse(const Params* params) const; private: template <typename Prng = rlwe::SecurePrng> - static rlwe::StatusOr<Int> GenerateRandomInt(int log_modulus, Prng* prng) { + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<Int> GenerateRandomInt(int log_modulus, Prng* prng) { // Generate a random Int. As the modulus is always smaller than max(Int), // there will be no issues with overflow. int max_bits_per_step = std::min((int)Params::bitsize_int, (int)64); @@ -467,6 +469,17 @@ Int n_; }; +// Instantiations of MontgomeryInt and MontgomeryIntParams with specific +// integral types. +extern template struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint16>; +extern template struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint32>; +extern template struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<Uint64>; +extern template struct EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryIntParams<absl::uint128>; +extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint16>; +extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint32>; +extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<Uint64>; +extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryInt<absl::uint128>; + } // namespace rlwe #endif // RLWE_MONTGOMERY_H_
diff --git a/third_party/shell-encryption/src/montgomery_test.cc b/third_party/shell-encryption/src/montgomery_test.cc index 7caf459a..2d952ddf 100644 --- a/third_party/shell-encryption/src/montgomery_test.cc +++ b/third_party/shell-encryption/src/montgomery_test.cc
@@ -30,6 +30,8 @@ #include "testing/status_matchers.h" #include "testing/status_testing.h" #include "testing/testing_prng.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" +#include "third_party/shell-encryption/base/shell_encryption_export_template.h" namespace rlwe { namespace { @@ -65,7 +67,7 @@ } template <typename T> -class MontgomeryTest : public ::testing::Test {}; +class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) MontgomeryTest : public ::testing::Test {}; TYPED_TEST_SUITE(MontgomeryTest, testing::ModularIntTypes); TYPED_TEST(MontgomeryTest, ModulusTooLarge) {
diff --git a/third_party/shell-encryption/src/ntt_parameters.h b/third_party/shell-encryption/src/ntt_parameters.h index 55671ec..eba9579 100644 --- a/third_party/shell-encryption/src/ntt_parameters.h +++ b/third_party/shell-encryption/src/ntt_parameters.h
@@ -24,6 +24,7 @@ #include "constants.h" #include "status_macros.h" #include "statusor.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" namespace rlwe { namespace internal { @@ -94,7 +95,7 @@ // Creates a vector containing the indices necessary to perform the NTT bit // reversal operation. Index i of the returned vector contains an integer with // the rightmost log_n bits of i reversed. -std::vector<unsigned int> BitrevArray(unsigned int log_n); +SHELL_ENCRYPTION_EXPORT std::vector<unsigned int> BitrevArray(unsigned int log_n); // Helper function: Perform the bit-reversal operation in-place on coeffs_. template <typename ModularInt>
diff --git a/third_party/shell-encryption/src/prng/chacha_prng.h b/third_party/shell-encryption/src/prng/chacha_prng.h index 27940fd..7e4f719 100644 --- a/third_party/shell-encryption/src/prng/chacha_prng.h +++ b/third_party/shell-encryption/src/prng/chacha_prng.h
@@ -26,6 +26,7 @@ #include "prng/chacha_prng_util.h" #include "prng/prng.h" #include "statusor.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" namespace rlwe { @@ -56,7 +57,7 @@ // errors. // // Thread safe. - static rlwe::StatusOr<std::unique_ptr<ChaChaPrng>> Create( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::unique_ptr<ChaChaPrng>> Create( absl::string_view in_key); // Returns 8 bits of randomness. @@ -72,12 +73,12 @@ // Generate a valid seed for the Prng. // // Fails on internal cryptographic errors. - static rlwe::StatusOr<std::string> GenerateSeed() { + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::string> GenerateSeed() { return internal::ChaChaPrngGenerateKey(); } // Output the size of the expected generated seed. - static int SeedLength() { return internal::kChaChaKeyBytesSize; } + static SHELL_ENCRYPTION_EXPORT int SeedLength() { return internal::kChaChaKeyBytesSize; } private: explicit ChaChaPrng(absl::string_view in_key, int position_in_buffer,
diff --git a/third_party/shell-encryption/src/prng/chacha_prng_util.h b/third_party/shell-encryption/src/prng/chacha_prng_util.h index 8eb8118..80f0cedf 100644 --- a/third_party/shell-encryption/src/prng/chacha_prng_util.h +++ b/third_party/shell-encryption/src/prng/chacha_prng_util.h
@@ -27,6 +27,7 @@ #include "absl/strings/string_view.h" #include "integral_types.h" #include "statusor.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" namespace rlwe { namespace internal { @@ -37,28 +38,33 @@ // Once pseudorandom output is exhausted, the salt is updated to construct // new pseudorandom output. -absl::Status ChaChaPrngResalt(absl::string_view key, int buffer_size, - int* salt_counter, int* position_in_buffer, - std::vector<Uint8>* buffer); +SHELL_ENCRYPTION_EXPORT absl::Status ChaChaPrngResalt( + absl::string_view key, + int buffer_size, + int* salt_counter, + int* position_in_buffer, + std::vector<Uint8>* buffer); // Generates a secure key for instantiating an CHACHA. -rlwe::StatusOr<std::string> ChaChaPrngGenerateKey(); +SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::string> ChaChaPrngGenerateKey(); // Returns 8 bits of randomness. // // Fails on internal cryptographic errors. -rlwe::StatusOr<Uint8> ChaChaPrngRand8(absl::string_view key, - int* position_in_buffer, - int* salt_counter, - std::vector<Uint8>* buffer); +SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<Uint8> ChaChaPrngRand8( + absl::string_view key, + int* position_in_buffer, + int* salt_counter, + std::vector<Uint8>* buffer); // Returns 64 bits of randomness. // // Fails on internal cryptographic errors. -rlwe::StatusOr<Uint64> ChaChaPrngRand64(absl::string_view key, - int* position_in_buffer, - int* salt_counter, - std::vector<Uint8>* buffer); +SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<Uint64> ChaChaPrngRand64( + absl::string_view key, + int* position_in_buffer, + int* salt_counter, + std::vector<Uint8>* buffer); } // namespace internal } // namespace rlwe
diff --git a/third_party/shell-encryption/src/prng/single_thread_chacha_prng.h b/third_party/shell-encryption/src/prng/single_thread_chacha_prng.h index fcaff827..2fddf6f3 100644 --- a/third_party/shell-encryption/src/prng/single_thread_chacha_prng.h +++ b/third_party/shell-encryption/src/prng/single_thread_chacha_prng.h
@@ -24,6 +24,7 @@ #include "prng/chacha_prng_util.h" #include "prng/prng.h" #include "statusor.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" namespace rlwe { @@ -52,7 +53,7 @@ // // Fails if the key is not the expected size or on internal cryptographic // errors. - static rlwe::StatusOr<std::unique_ptr<SingleThreadChaChaPrng>> Create( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<std::unique_ptr<SingleThreadChaChaPrng>> Create( absl::string_view in_key); // Returns 8 bits of randomness.
diff --git a/third_party/shell-encryption/src/relinearization_key.cc b/third_party/shell-encryption/src/relinearization_key.cc index 7982a2f..0b22a50 100644 --- a/third_party/shell-encryption/src/relinearization_key.cc +++ b/third_party/shell-encryption/src/relinearization_key.cc
@@ -22,6 +22,8 @@ #include "status_macros.h" #include "statusor.h" #include "symmetric_encryption_with_prng.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" +#include "third_party/shell-encryption/base/shell_encryption_export_template.h" namespace rlwe { namespace { @@ -432,9 +434,9 @@ // Instantiations of RelinearizationKey with specific MontgomeryInt classes. // If any new types are added, montgomery.h should be updated accordingly (such // as ensuring BigInt is correctly specialized, etc.). -template class RelinearizationKey<MontgomeryInt<Uint16>>; -template class RelinearizationKey<MontgomeryInt<Uint32>>; -template class RelinearizationKey<MontgomeryInt<Uint64>>; -template class RelinearizationKey<MontgomeryInt<absl::uint128>>; +template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint16>>; +template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint32>>; +template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint64>>; +template class EXPORT_TEMPLATE_DEFINE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<absl::uint128>>; } // namespace rlwe
diff --git a/third_party/shell-encryption/src/relinearization_key.h b/third_party/shell-encryption/src/relinearization_key.h index 265da33..1aff179 100644 --- a/third_party/shell-encryption/src/relinearization_key.h +++ b/third_party/shell-encryption/src/relinearization_key.h
@@ -22,6 +22,8 @@ #include "sample_error.h" #include "statusor.h" #include "symmetric_encryption.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" +#include "third_party/shell-encryption/base/shell_encryption_export_template.h" namespace rlwe { // Represents a RelinearizationKey constructed from a symmetric-key. Applying a @@ -57,7 +59,7 @@ // length (k - 1), where k is the number of parts of the ciphertext it applies // to. template <typename ModularInt> -class RelinearizationKey { +class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey { using ModularIntParams = typename ModularInt::Params; public: @@ -73,7 +75,7 @@ // with (1, s^k). In that case, we would use a relinearization key with // substition_power = k to return the ciphertext to be encrypted with (1,s). // See GaloisKey for an explicit wrapper around RelinearizationKey. - static rlwe::StatusOr<RelinearizationKey> Create( + static SHELL_ENCRYPTION_EXPORT rlwe::StatusOr<RelinearizationKey> Create( const SymmetricRlweKey<ModularInt>& key, absl::string_view prng_seed, ssize_t num_parts, Uint64 log_decomposition_modulus, Uint64 substitution_power = 1); @@ -192,6 +194,13 @@ std::string prng_seed_; }; +// Instantiations of RelinearizationKey with specific MontgomeryInt classes. +// If any new types are added, montgomery.h should be updated accordingly (such +// as ensuring BigInt is correctly specialized, etc.). +extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint16>>; +extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint32>>; +extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<Uint64>>; +extern template class EXPORT_TEMPLATE_DECLARE(SHELL_ENCRYPTION_EXPORT) RelinearizationKey<MontgomeryInt<absl::uint128>>; } // namespace rlwe #endif // RLWE_RELINEARIZATION_KEY_H_
diff --git a/third_party/shell-encryption/src/statusor.h b/third_party/shell-encryption/src/statusor.h index 200f62d9..b7ada09 100644 --- a/third_party/shell-encryption/src/statusor.h +++ b/third_party/shell-encryption/src/statusor.h
@@ -22,11 +22,12 @@ #include "absl/base/attributes.h" #include "absl/status/status.h" #include "absl/types/optional.h" +#include "third_party/shell-encryption/base/shell_encryption_export.h" namespace rlwe { template <typename T> -class StatusOr { +class SHELL_ENCRYPTION_EXPORT StatusOr { public: // Construct a new StatusOr with Status::UNKNOWN status StatusOr(); @@ -112,12 +113,12 @@ namespace internal { -class StatusOrHelper { +class SHELL_ENCRYPTION_EXPORT StatusOrHelper { public: // Move type-agnostic error handling to the .cc. - static absl::Status HandleInvalidStatusCtorArg(); - static absl::Status HandleNullObjectCtorArg(); - static void Crash(const absl::Status& status); + static SHELL_ENCRYPTION_EXPORT absl::Status HandleInvalidStatusCtorArg(); + static SHELL_ENCRYPTION_EXPORT absl::Status HandleNullObjectCtorArg(); + static SHELL_ENCRYPTION_EXPORT void Crash(const absl::Status& status); // Customized behavior for StatusOr<T> vs. StatusOr<T*> template <typename T> @@ -125,13 +126,13 @@ }; template <typename T> -struct StatusOrHelper::Specialize { +struct SHELL_ENCRYPTION_EXPORT StatusOrHelper::Specialize { // For non-pointer T, a reference can never be NULL. static inline bool IsValueNull(const T& t) { return false; } }; template <typename T> -struct StatusOrHelper::Specialize<T*> { +struct SHELL_ENCRYPTION_EXPORT StatusOrHelper::Specialize<T*> { static inline bool IsValueNull(const T* t) { return t == nullptr; } };
diff --git a/third_party/subresource-filter-ruleset/README.chromium b/third_party/subresource-filter-ruleset/README.chromium index 83c8dac2..f52c818 100644 --- a/third_party/subresource-filter-ruleset/README.chromium +++ b/third_party/subresource-filter-ruleset/README.chromium
@@ -1,6 +1,6 @@ Name: EasyList URL: https://easylist.to/easylist/easylist.txt -Version: 202110121535 +Version: 202111091709 License: Creative Commons Attribution-ShareAlike 3.0 Unported License Android Compatible: yes License File: LICENSE
diff --git a/third_party/subresource-filter-ruleset/data/UnindexedRules.sha1 b/third_party/subresource-filter-ruleset/data/UnindexedRules.sha1 index df774bc..b1640f8 100644 --- a/third_party/subresource-filter-ruleset/data/UnindexedRules.sha1 +++ b/third_party/subresource-filter-ruleset/data/UnindexedRules.sha1
@@ -1 +1 @@ -50461c265b3ff063690dfd7b5fdf742ba06de36d \ No newline at end of file +a703507a694340bac1a78ce6e54dfbd641062da5 \ No newline at end of file
diff --git a/third_party/subresource-filter-ruleset/manifest.json b/third_party/subresource-filter-ruleset/manifest.json index db9c58b7..8bc6c2d6 100644 --- a/third_party/subresource-filter-ruleset/manifest.json +++ b/third_party/subresource-filter-ruleset/manifest.json
@@ -2,5 +2,5 @@ "manifest_version": 2, "name": "Subresource Filtering Rules", "ruleset_format": 1, - "version": "9.32.0" + "version": "9.33.0" }
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py index e6bbb0a..cdb26d9 100644 --- a/tools/binary_size/libsupersize/archive.py +++ b/tools/binary_size/libsupersize/archive.py
@@ -124,9 +124,6 @@ # Parameters and states for archiving a container. @dataclasses.dataclass class ContainerArchiveOptions: - # TODO(agrieve): Delete pak_compression_ratio. We haven't compressed .pak - # files since moving to bundles. - pak_compression_ratio: float = 0.5 # Whether to count number of relative relocations instead of binary size. relocations_mode: bool = False # Whether to break down .so files. @@ -287,44 +284,42 @@ return True, path -def _ExtractSourcePathsAndNormalizeObjectPaths(raw_symbols, - object_source_mapper, - address_source_mapper): +def _AddSourcePathsUsingObjectPaths(ninja_source_mapper, raw_symbols): + logging.info('Looking up source paths from ninja files') + for symbol in raw_symbols: + if symbol.IsDex() or symbol.IsOther(): + continue + # Native symbols and pak symbols use object paths. + object_path = symbol.object_path + if not object_path: + continue + + # We don't have source info for prebuilt .a files. + if not os.path.isabs(object_path) and not object_path.startswith('..'): + symbol.source_path = ninja_source_mapper.FindSourceForPath(object_path) + assert ninja_source_mapper.unmatched_paths_count == 0, ( + 'One or more source file paths could not be found. Likely caused by ' + '.ninja files being generated at a different time than the .map file.') + + +def _AddSourcePathsUsingAddress(dwarf_source_mapper, raw_symbols): + logging.info('Looking up source paths from dwarfdump') + for symbol in raw_symbols: + if symbol.section_name != models.SECTION_TEXT: + continue + source_path = dwarf_source_mapper.FindSourceForTextAddress(symbol.address) + if source_path and not os.path.isabs(source_path): + symbol.source_path = source_path + # Majority of unmatched queries are for assembly source files (ex libav1d) + # and v8 builtins. + assert dwarf_source_mapper.unmatched_queries_ratio < 0.1, ( + 'Percentage of failing |dwarf_source_mapper| queries ' + + '({}%) >= 10% '.format(dwarf_source_mapper.unmatched_queries_ratio * 100) + + 'FindSourceForTextAddress() likely has a bug.') + + +def _NormalizeObjectPaths(raw_symbols): """Fills in the |source_path| attribute and normalizes |object_path|.""" - assert not object_source_mapper or not address_source_mapper - if object_source_mapper: - logging.info('Looking up source paths from ninja files') - for symbol in raw_symbols: - if symbol.IsDex() or symbol.IsOther(): - continue - # Native symbols and pak symbols use object paths. - object_path = symbol.object_path - if not object_path: - continue - - # We don't have source info for prebuilt .a files. - if not os.path.isabs(object_path) and not object_path.startswith('..'): - symbol.source_path = object_source_mapper.FindSourceForPath(object_path) - assert object_source_mapper.unmatched_paths_count == 0, ( - 'One or more source file paths could not be found. Likely caused by ' - '.ninja files being generated at a different time than the .map file.') - elif address_source_mapper: - logging.info('Looking up source paths from dwarfdump') - for symbol in raw_symbols: - if symbol.section_name != models.SECTION_TEXT: - continue - source_path = address_source_mapper.FindSourceForTextAddress( - symbol.address) - if source_path and not os.path.isabs(source_path): - symbol.source_path = source_path - # Majority of unmatched queries are for assembly source files (ex libav1d) - # and v8 builtins. - assert address_source_mapper.unmatched_queries_ratio < 0.1, ( - 'Percentage of failing |address_source_mapper| queries ' + - '({}%) >= 10% '.format( - address_source_mapper.unmatched_queries_ratio * 100) + - 'FindSourceForTextAddress() likely has a bug.') - logging.info('Normalizing source and object paths') for symbol in raw_symbols: if symbol.object_path: @@ -981,12 +976,9 @@ raw_symbols, object_paths_by_name) -def _ComputePakFileSymbols( - file_name, contents, res_info, symbols_by_id, compression_ratio=1): - id_map = { - id(v): k - for k, v in sorted(list(contents.resources.items()), reverse=True) - } +def _ComputePakFileSymbols(file_name, contents, res_info, symbols_by_id): + # Reversed so that aliases are clobbered by the entries they are aliases of. + id_map = {id(v): k for k, v in reversed(contents.resources.items())} alias_map = { k: id_map[id(v)] for k, v in contents.resources.items() if id_map[id(v)] != k @@ -999,15 +991,16 @@ else: # E.g.: resources.pak, chrome_100_percent.pak. section_name = models.SECTION_PAK_NONTRANSLATED - overhead = (12 + 6) * compression_ratio # Header size plus extra offset + overhead = 12 + 6 # Header size plus extra offset # Key just needs to be unique from other IDs and pak overhead symbols. symbols_by_id[-len(symbols_by_id) - 1] = models.Symbol( section_name, overhead, full_name='Overhead: {}'.format(file_name)) for resource_id in sorted(contents.resources): - if resource_id in alias_map: + aliased_resource_id = alias_map.get(resource_id) + if aliased_resource_id is not None: # 4 extra bytes of metadata (2 16-bit ints) size = 4 - resource_id = alias_map[resource_id] + resource_id = aliased_resource_id else: resource_data = contents.resources[resource_id] # 6 extra bytes of metadata (1 32-bit int, 1 16-bit int) @@ -1022,7 +1015,6 @@ new_symbol.flags |= models.FLAG_UNCOMPRESSED symbols_by_id[resource_id] = new_symbol - size *= compression_ratio symbols_by_id[resource_id].size += size return section_name @@ -1102,27 +1094,10 @@ full_name=symbol.full_name, object_path=path, aliases=aliases) aliases.append(new_sym) raw_symbols.append(new_sym) - raw_total = 0.0 - int_total = 0 - for symbol in raw_symbols: - raw_total += symbol.size - # We truncate rather than round to ensure that we do not over attribute. It - # is easier to add another symbol to make up the difference. - symbol.size = int(symbol.size) - int_total += symbol.size - # Attribute excess to translations since only those are compressed. - overhead_size = round(raw_total - int_total) - if overhead_size: - raw_symbols.append( - models.Symbol(models.SECTION_PAK_TRANSLATIONS, - overhead_size, - address=raw_symbols[-1].end_address, - full_name='Overhead: Pak compression artifacts')) # Pre-sort to make final sort faster. # Note: _SECTION_SORT_ORDER[] for pak symbols matches section_name ordering. - raw_symbols.sort( - key=lambda s: (s.section_name, s.IsOverhead(), s.address, s.object_path)) + raw_symbols.sort(key=lambda s: (s.section_name, s.address, s.object_path)) return raw_symbols @@ -1242,33 +1217,22 @@ return object_paths_by_pak_id -def _FindPakSymbolsFromApk(opts, section_ranges, apk_path, size_info_prefix): +def _FindPakSymbolsFromApk(section_ranges, apk_path, size_info_prefix): with zipfile.ZipFile(apk_path) as z: pak_zip_infos = (f for f in z.infolist() if f.filename.endswith('.pak')) pak_info_path = size_info_prefix + '.pak.info' res_info = _ParsePakInfoFile(pak_info_path) symbols_by_id = {} - total_compressed_size = 0 - total_uncompressed_size = 0 for zip_info in pak_zip_infos: contents = data_pack.ReadDataPackFromString(z.read(zip_info)) - compression_ratio = 1.0 - if zip_info.compress_size < zip_info.file_size: - total_compressed_size += zip_info.compress_size - total_uncompressed_size += zip_info.file_size - compression_ratio = opts.pak_compression_ratio - section_name = _ComputePakFileSymbols( - zip_info.filename, contents, - res_info, symbols_by_id, compression_ratio=compression_ratio) + if zip_info.compress_type != zipfile.ZIP_STORED: + logging.warning( + 'Expected .pak files to be STORED, but this one is compressed: %s', + zip_info.filename) + section_name = _ComputePakFileSymbols(zip_info.filename, contents, + res_info, symbols_by_id) _ExtendSectionRange(section_ranges, section_name, zip_info.compress_size) - if total_uncompressed_size > 0: - actual_ratio = ( - float(total_compressed_size) / total_uncompressed_size) - logging.info( - 'Pak Compression Ratio: %f Actual: %f Diff: %.0f', - opts.pak_compression_ratio, actual_ratio, - (opts.pak_compression_ratio - actual_ratio) * total_uncompressed_size) return symbols_by_id @@ -1460,8 +1424,8 @@ _ElfInfoFromApk, (apk_spec.apk_path, native_spec.apk_so_path, native_spec.tool_prefix)) - object_source_mapper = None - address_source_mapper = None + ninja_source_mapper = None + dwarf_source_mapper = None section_ranges = {} raw_symbols = [] object_paths_by_name = None @@ -1469,15 +1433,15 @@ ninja_elf_object_paths = None if output_directory and native_spec.map_path: # Finds all objects passed to the linker and creates a map of .o -> .cc. - object_source_mapper, ninja_elf_object_paths = _ParseNinjaFiles( + ninja_source_mapper, ninja_elf_object_paths = _ParseNinjaFiles( output_directory, native_spec.elf_path) elif native_spec.elf_path: logging.info('Parsing source path info via dwarfdump') - address_source_mapper = dwarfdump.CreateAddressSourceMapper( + dwarf_source_mapper = dwarfdump.CreateAddressSourceMapper( native_spec.elf_path, native_spec.tool_prefix) logging.info('Found %d source paths across %s ranges', - address_source_mapper.NumberOfPaths(), - address_source_mapper.num_ranges) + dwarf_source_mapper.NumberOfPaths(), + dwarf_source_mapper.num_ranges) # Start by finding elf_object_paths so that nm can run on them while the # linker .map is being parsed. @@ -1491,9 +1455,9 @@ known_inputs = None # When we don't know which elf file is used, just search all paths. # TODO(agrieve): Seems to be used only for tests. Remove? - if object_source_mapper: + if ninja_source_mapper: thin_archives = set( - p for p in object_source_mapper.IterAllPaths() if p.endswith('.a') + p for p in ninja_source_mapper.IterAllPaths() if p.endswith('.a') and ar.IsThinArchive(os.path.join(output_directory, p))) else: thin_archives = None @@ -1535,7 +1499,7 @@ other_symbols = [] if apk_spec and apk_spec.size_info_prefix and not opts.relocations_mode: # Can modify |section_ranges|. - pak_symbols_by_id = _FindPakSymbolsFromApk(opts, section_ranges, + pak_symbols_by_id = _FindPakSymbolsFromApk(section_ranges, apk_spec.apk_path, apk_spec.size_info_prefix) @@ -1609,8 +1573,12 @@ '**'), s.address, s.full_name)) raw_symbols.extend(other_symbols) - _ExtractSourcePathsAndNormalizeObjectPaths(raw_symbols, object_source_mapper, - address_source_mapper) + if ninja_source_mapper: + _AddSourcePathsUsingObjectPaths(ninja_source_mapper, raw_symbols) + elif dwarf_source_mapper: + _AddSourcePathsUsingAddress(dwarf_source_mapper, raw_symbols) + _NormalizeObjectPaths(raw_symbols) + dir_metadata.PopulateComponents(raw_symbols, source_directory) logging.info('Converting excessive aliases into shared-path symbols') _CompactLargeAliasesIntoSharedSymbols(raw_symbols, knobs) @@ -2042,10 +2010,6 @@ sub_args.aux_elf_file = None opts = ContainerArchiveOptions() - # An estimate of pak translation compression ratio to make comparisons - # between .size files reasonable. Otherwise this can differ every pak - # change. - opts.pak_compression_ratio = 0.38 if sub_args.minimal_apks_file else 0.33 opts.relocations_mode = top_args.relocations opts.analyze_native = not (sub_args.java_only or sub_args.no_native or top_args.java_only or top_args.no_native)
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py index 9737e7d..5cf7099 100755 --- a/tools/clang/scripts/build.py +++ b/tools/clang/scripts/build.py
@@ -995,14 +995,12 @@ cflags = [ '--target=' + target_triple, '--sysroot=%s/sysroot' % toolchain_dir, - '--gcc-toolchain=' + toolchain_dir, # android_ndk/toolchains/llvm/prebuilt/linux-x86_64/aarch64-linux-android/bin/ld # depends on a newer version of libxml2.so than what's available on # the bots. To make things work, use our just-built lld as linker. '-fuse-ld=lld', - # The compiler we're building with (just-built clang) doesn't have the - # compiler-rt builtins; use libgcc to get past the CMake checks. - '--rtlib=libgcc', + # We don't have an unwinder ready, and don't need it either. + '--unwindlib=none', ] android_args = base_cmake_args + [ @@ -1017,17 +1015,45 @@ '-DCOMPILER_RT_BUILD_LIBFUZZER=OFF', '-DCOMPILER_RT_BUILD_MEMPROF=OFF', '-DCOMPILER_RT_BUILD_ORC=OFF', - '-DCOMPILER_RT_BUILD_PROFILE=ON', - '-DCOMPILER_RT_BUILD_SANITIZERS=ON', + '-DCOMPILER_RT_BUILD_PROFILE=OFF', + '-DCOMPILER_RT_BUILD_SANITIZERS=OFF', '-DCOMPILER_RT_BUILD_XRAY=OFF', '-DSANITIZER_CXX_ABI=libcxxabi', '-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-u__cxa_demangle', - '-DANDROID=1'] + '-DANDROID=1' + + # These are necessary because otherwise CMake tries to build an + # executable to test to see if the compiler is working, but in doing so, + # it links against the builtins.a that we're about to build. + '-DCMAKE_CXX_COMPILER_WORKS=ON', + '-DCMAKE_C_COMPILER_WORKS=ON', + '-DCMAKE_ASM_COMPILER_WORKS=ON', + ] + + # First build the builtins and copy to the main build tree. + RunCommand(['cmake'] + + android_args + + [os.path.join(COMPILER_RT_DIR, 'lib', 'builtins')]) + builtins_a = 'lib/linux/libclang_rt.builtins-%s-android.a' % target_arch + RunCommand(['ninja', builtins_a]) + shutil.copy(builtins_a, rt_lib_dst_dir) + + # With the builtins in place, we can build the other runtimes. + build_dir_2 = build_dir + '-phase2' + if not os.path.exists(build_dir_2): + os.mkdir(os.path.join(build_dir_2)) + os.chdir(build_dir_2) + + android_args.extend([ + '-DCOMPILER_RT_BUILD_BUILTINS=OFF', + '-DCOMPILER_RT_USE_BUILTINS_LIBRARY=ON', + '-DCOMPILER_RT_BUILD_PROFILE=ON', + '-DCOMPILER_RT_BUILD_SANITIZERS=ON', + ]) RunCommand(['cmake'] + android_args + [COMPILER_RT_DIR]) libs_want = [ 'lib/linux/libclang_rt.asan-{0}-android.so', - 'lib/linux/libclang_rt.builtins-{0}-android.a', 'lib/linux/libclang_rt.ubsan_standalone-{0}-android.so', 'lib/linux/libclang_rt.profile-{0}-android.a', ]
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 9a8bae5..81e0425 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -35,7 +35,7 @@ # Reverting problematic clang rolls is safe, though. # This is the output of `git describe` and is usable as a commit-ish. CLANG_REVISION = 'llvmorg-14-init-8564-g34b903d8' -CLANG_SUB_REVISION = 2 +CLANG_SUB_REVISION = 7 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION) RELEASE_VERSION = '14.0.0'
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index d85dfc56..44d4f904 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -30082,6 +30082,7 @@ <int value="1599" label="WEB_AUTHENTICATION_PROXY_DETACH"/> <int value="1600" label="FILEMANAGERPRIVATE_CANCELIOTASK"/> <int value="1601" label="AUTOTESTPRIVATE_GETDISPLAYSMOOTHNESS"/> + <int value="1602" label="AUTOTESTPRIVATE_RESETHOLDINGSPACE"/> </enum> <enum name="ExtensionIconState"> @@ -50192,6 +50193,7 @@ <int value="-915035507" label="ArcPrintSpoolerExperiment:enabled"/> <int value="-914210146" label="enable-web-based-signin"/> <int value="-914097698" label="EnableDbusAndX11StatusIcons:disabled"/> + <int value="-913925109" label="FilesExtractArchive:disabled"/> <int value="-913294939" label="DriveFS:enabled"/> <int value="-912585719" label="AppManagementIntentSettings:disabled"/> <int value="-912456561" label="MidiManagerWinrt:enabled"/> @@ -51206,6 +51208,7 @@ <int value="-127666141" label="TabGroups:disabled"/> <int value="-127231994" label="VrBrowsingNativeAndroidUi:disabled"/> <int value="-122492389" label="enable-browser-task-scheduler"/> + <int value="-122458532" label="FilesExtractArchive:enabled"/> <int value="-121563330" label="SecurePaymentConfirmationBrowser:disabled"/> <int value="-120521482" label="DirectManipulationStylus:enabled"/> <int value="-120091289" label="CrostiniAppSearch:enabled"/> @@ -52133,7 +52136,6 @@ <int value="570469494" label="LoginDetection:disabled"/> <int value="571349694" label="AllowAllSitesToInitiateMirroring:enabled"/> <int value="571562912" label="InstallableAmbientBadgeMessage:disabled"/> - <int value="572915501" label="FilesZipUnpack:disabled"/> <int value="573385109" label="SharedClipboardUI:enabled"/> <int value="575380532" label="ExperimentalAccessibilityLabels:disabled"/> <int value="575394365" label="AndroidPaymentApps:disabled"/> @@ -52202,7 +52204,6 @@ <int value="624783596" label="SamePartyCookiesConsideredFirstParty:enabled"/> <int value="625273056" label="disable-boot-animation"/> <int value="625725485" label="FilesTrash:enabled"/> - <int value="626605468" label="FilesZipUnpack:enabled"/> <int value="628302973" label="NTPSnippets:enabled"/> <int value="628570445" label="AndroidAutofillAccessibility:enabled"/> <int value="629549626" label="ContextualSearchMlTapSuppression:enabled"/> @@ -64251,6 +64252,7 @@ <int value="1112" label="Privacy: Remove Fingerprint V2"/> <int value="1113" label="Privacy: Enable/Disable peripheral data access protection"/> + <int value="1114" label="Privacy: Snooping Protection"/> <int value="1200" label="Add Language"/> <int value="1201" label="Show Input Options In Shelf"/> <int value="1202" label="Show Personal Information Suggestions"/> @@ -64306,6 +64308,7 @@ <int value="1706" label="View Terms of Service"/> <int value="1707" label="Open Diagnostics App"/> <int value="1708" label="Change Device Name"/> + <int value="1709" label="Open Firmware Updates App"/> <int value="1800" label="Add Kerberos Ticket V2"/> <int value="1801" label="Remove Kerberos Ticket V2"/> <int value="1802" label="Set Active Kerberos Ticket V2"/>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index 2f3b4fb..149abea 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -2865,6 +2865,22 @@ </summary> </histogram> +<histogram + name="Android.StartupTabPreloader.LoadDecisionToFirstNavigationStart.{LoadDecision}" + units="ms" expires_after="2022-09-01"> + <owner>blundell@chromium.org</owner> + <owner>yfriedman@chromium.org</owner> + <summary> + The time in a cold start between the triggerpoint for a startup tab being + preloaded and first navigation start, recorded in the case where a startup + tab preload is determined {LoadDecision} viable. + </summary> + <token key="LoadDecision"> + <variant name="Load" summary="to be"/> + <variant name="NoLoad" summary="not to be"/> + </token> +</histogram> + <histogram name="Android.StrictMode.OverrideUrlLoadingTime" units="ms" expires_after="2022-04-24"> <owner>yfriedman@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index afb0f17..1b18f15c 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -1279,7 +1279,7 @@ </histogram> <histogram name="Media.AudioRendererAudioGlitches" enum="AudioGlitchResult" - expires_after="2022-04-10"> + expires_after="2022-02-10"> <owner>henrika@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> @@ -1288,6 +1288,24 @@ </summary> </histogram> +<histogram name="Media.AudioRendererAudioGlitches2.{LatencyTag}" + enum="AudioGlitchResult" expires_after="2022-10-04"> + <owner>dalecurtis@chromium.org</owner> + <owner>olka@chromium.org</owner> + <owner>tguilbert@chromium.org</owner> + <summary> + Captures if render-side audio glitches are detected or not. Sampled when a + low-latency output audio stream is destructed. + </summary> + <token key="LatencyTag"> + <variant name="LatencyExactMs"/> + <variant name="LatencyInteractive"/> + <variant name="LatencyPlayback"/> + <variant name="LatencyRtc"/> + <variant name="LatencyUnknown"/> + </token> +</histogram> + <histogram name="Media.AudioRendererImpl.SinkStatus" enum="OutputDeviceStatus" expires_after="2022-12-12"> <owner>armax@chromium.org</owner> @@ -1304,7 +1322,7 @@ </histogram> <histogram name="Media.AudioRendererMissedDeadline" units="%" - expires_after="2022-04-17"> + expires_after="2022-02-10"> <owner>dalecurtis@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> @@ -1313,6 +1331,29 @@ </summary> </histogram> +<histogram name="Media.AudioRendererMissedDeadline2.{Duration}.{LatencyTag}" + units="permille" expires_after="2022-10-04"> + <owner>dalecurtis@chromium.org</owner> + <owner>olka@chromium.org</owner> + <owner>tguilbert@chromium.org</owner> + <summary> + Proportion of AudioSyncReader::Read() calls where the renderer missed its + realtime deadline. Rounded up, clipped to 1/10 of the stream callbacks. + Sampled when a low-latency output audio stream is destructed. + </summary> + <token key="Duration"> + <variant name="Long" summary="Streams equal or longer than 3000 callbacks"/> + <variant name="Short" summary="Streams shorter than 3000 callbacks"/> + </token> + <token key="LatencyTag"> + <variant name="LatencyExactMs"/> + <variant name="LatencyInteractive"/> + <variant name="LatencyPlayback"/> + <variant name="LatencyRtc"/> + <variant name="LatencyUnknown"/> + </token> +</histogram> + <histogram name="Media.AudioService.AudioManagerStartupTime" units="ms" expires_after="2022-04-05"> <owner>guidou@chromium.org</owner>
diff --git a/tools/perf/cli_tools/update_wpr/update_wpr.py b/tools/perf/cli_tools/update_wpr/update_wpr.py index efb821a..dcc7aedc 100644 --- a/tools/perf/cli_tools/update_wpr/update_wpr.py +++ b/tools/perf/cli_tools/update_wpr/update_wpr.py
@@ -45,8 +45,11 @@ def _GetBranchName(): - return subprocess.check_output( + branch_name = subprocess.check_output( ['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip() + if isinstance(branch_name, bytes): + return branch_name.decode("utf-8") + return branch_name def _OpenBrowser(url):
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index fd3e249..2992f05 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": "2abe2291e0e9b51e8750059797f1284422cb27d8", - "remote_path": "perfetto_binaries/trace_processor_shell/win/f32b6ac45880108dee6eaa9e585aa8c6217607cb/trace_processor_shell.exe" + "remote_path": "perfetto_binaries/trace_processor_shell/win/19fb767c32d05d75314d376933b98be246e0b723/trace_processor_shell.exe" }, "mac": { "hash": "0dda5c90a9ea600e8c3dd1276671b55a07260c4d", @@ -18,7 +18,7 @@ }, "linux": { "hash": "4cdd2006b2e87bbf78fe37b58a3e09d6392977e1", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/f32b6ac45880108dee6eaa9e585aa8c6217607cb/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/linux/19fb767c32d05d75314d376933b98be246e0b723/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js index 6d5c7b1..f30544f 100644 --- a/ui/file_manager/file_manager/common/js/util.js +++ b/ui/file_manager/file_manager/common/js/util.js
@@ -1492,15 +1492,6 @@ }; /** - * Returns true when FilesZipUnpack feature is enabled. - * TODO(crbug.com/912236) Remove once transition to new ZIP system is finished. - * @return {boolean} - */ -util.isZipUnpackEnabled = () => { - return loadTimeData.getBoolean('ZIP_UNPACK'); -}; - -/** * Returns true if FilesSinglePartitionFormat flag is enabled. * @return {boolean} */ @@ -1525,6 +1516,14 @@ }; /** + * Returns true if FilesExtractArchive flag is enabled. + * @return {boolean} + */ +util.isExtractArchiveEnabled = () => { + return loadTimeData.getBoolean('EXTRACT_ARCHIVE'); +}; + +/** * Retrieves all entries inside the given |rootEntry|. * @param {!DirectoryEntry} rootEntry * @param {function(!Array<!Entry>)} entriesCallback Called when some chunk of
diff --git a/ui/native_theme/BUILD.gn b/ui/native_theme/BUILD.gn index e203452..833dc42 100644 --- a/ui/native_theme/BUILD.gn +++ b/ui/native_theme/BUILD.gn
@@ -44,6 +44,8 @@ "caption_style_mac.mm", "native_theme_mac.h", "native_theme_mac.mm", + "scrollbar_animator_mac.cc", + "scrollbar_animator_mac.h", ] } @@ -75,6 +77,7 @@ "//ui/color:mixers", "//ui/display", "//ui/gfx", + "//ui/gfx/animation/keyframe", "//ui/gfx/geometry", "//ui/resources", ] @@ -149,7 +152,10 @@ ] if (is_mac) { - sources += [ "native_theme_mac_unittest.mm" ] + sources += [ + "native_theme_mac_unittest.mm", + "scrollbar_animator_mac_unittest.cc", + ] deps += [ "//ui/color", "//ui/gfx:test_support",
diff --git a/ui/native_theme/scrollbar_animator_mac.cc b/ui/native_theme/scrollbar_animator_mac.cc new file mode 100644 index 0000000..c71d4b3 --- /dev/null +++ b/ui/native_theme/scrollbar_animator_mac.cc
@@ -0,0 +1,257 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/native_theme/scrollbar_animator_mac.h" + +#include "base/cxx17_backports.h" + +namespace ui { + +/////////////////////////////////////////////////////////////////////////////// +// ScrollbarAnimationTimerMac + +ScrollbarAnimationTimerMac::ScrollbarAnimationTimerMac( + base::RepeatingCallback<void(double)> callback, + double duration, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : start_time_(0.0), duration_(duration), callback_(std::move(callback)) { + timing_function_ = gfx::CubicBezierTimingFunction::CreatePreset( + gfx::CubicBezierTimingFunction::EaseType::EASE_IN_OUT); +} + +ScrollbarAnimationTimerMac::~ScrollbarAnimationTimerMac() {} + +void ScrollbarAnimationTimerMac::Start() { + start_time_ = base::Time::Now().ToDoubleT(); + // Set the framerate of the animation. NSAnimation uses a default + // framerate of 60 Hz, so use that here. + timer_.Start(FROM_HERE, base::Seconds(1.0 / 60.0), this, + &ScrollbarAnimationTimerMac::TimerFired); +} + +void ScrollbarAnimationTimerMac::Stop() { + timer_.Stop(); +} + +void ScrollbarAnimationTimerMac::SetDuration(double duration) { + duration_ = duration; +} + +void ScrollbarAnimationTimerMac::TimerFired() { + double current_time = base::Time::Now().ToDoubleT(); + double delta = current_time - start_time_; + + if (delta >= duration_) + timer_.Stop(); + + double fraction = delta / duration_; + fraction = base::clamp(fraction, 0.0, 1.0); + double progress = timing_function_->GetValue(fraction); + // Note that `this` may be destroyed from within `callback_`, so it is not + // safe to call any other code after it. + callback_.Run(progress); +} + +/////////////////////////////////////////////////////////////////////////////// +// OverlayScrollbarAnimatorMac + +OverlayScrollbarAnimatorMac::OverlayScrollbarAnimatorMac( + Client* client, + int thumb_width_expanded, + int thumb_width_unexpanded, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : client_(client), + thumb_width_expanded_(thumb_width_expanded), + thumb_width_unexpanded_(thumb_width_unexpanded), + thumb_width_(thumb_width_unexpanded), + task_runner_(task_runner), + weak_factory_(this) {} + +OverlayScrollbarAnimatorMac::~OverlayScrollbarAnimatorMac() = default; + +void OverlayScrollbarAnimatorMac::MouseDidEnter() { + // If the scrollbar is completely hidden, ignore this. We will initialize + // the `mouse_in_track_` state if there's a scroll. + if (thumb_alpha_ == 0.f) + return; + + if (mouse_in_track_) + return; + mouse_in_track_ = true; + + // Cancel any in-progress fade-out, and ensure that the fade-out timer be + // disabled. + if (fade_out_animation_) + FadeOutAnimationCancel(); + FadeOutTimerUpdate(); + + // Start the fade-in animation (unless it is in progress or has already + // completed). + if (!fade_in_track_animation_ && track_alpha_ != 1.f) + FadeInTrackAnimationStart(); + + // Start the expand-thumb animation (unless it is in progress or has already + // completed). + if (!expand_thumb_animation_ && thumb_width_ != thumb_width_expanded_) + ExpandThumbAnimationStart(); +} + +void OverlayScrollbarAnimatorMac::MouseDidExit() { + // Ensure that the fade-out timer be re-enabled. + mouse_in_track_ = false; + FadeOutTimerUpdate(); +} + +void OverlayScrollbarAnimatorMac::DidScroll() { + // If we were fading out, then immediately return to being fully opaque for + // both the thumb and track. + if (fade_out_animation_) { + FadeOutAnimationCancel(); + FadeOutTimerUpdate(); + return; + } + + // If the scrollbar was already fully visible, then just update the fade-out + // timer. + if (thumb_alpha_ == 1.f) { + FadeOutTimerUpdate(); + return; + } + + // This is an initial scroll causing the thumb to appear. + DCHECK_EQ(thumb_width_, thumb_width_unexpanded_); + DCHECK_EQ(thumb_alpha_, 0.f); + DCHECK(!fade_in_track_animation_); + thumb_width_ = thumb_width_unexpanded_; + thumb_alpha_ = 1; + client_->SetThumbNeedsDisplay(); + client_->SetHidden(false); + + // If the initial scroll is done inside the scrollbar's area, then also + // cause the track to appear and the thumb to enlarge. + if (client_->IsMouseInScrollbarFrameRect()) { + mouse_in_track_ = true; + thumb_width_ = thumb_width_expanded_; + track_alpha_ = 1; + client_->SetTrackNeedsDisplay(); + } + + // Update the fade-out timer (now that we know whether or not the mouse + // is in the track). + FadeOutTimerUpdate(); +} + +void OverlayScrollbarAnimatorMac::ExpandThumbAnimationStart() { + DCHECK(!expand_thumb_animation_); + DCHECK_NE(thumb_width_, thumb_width_expanded_); + expand_thumb_animation_ = std::make_unique<ScrollbarAnimationTimerMac>( + base::BindRepeating( + &OverlayScrollbarAnimatorMac::ExpandThumbAnimationTicked, + weak_factory_.GetWeakPtr()), + kAnimationDurationSeconds, task_runner_); + expand_thumb_animation_->Start(); +} + +void OverlayScrollbarAnimatorMac::ExpandThumbAnimationTicked(double progress) { + thumb_width_ = (1 - progress) * thumb_width_unexpanded_ + + progress * thumb_width_expanded_; + client_->SetThumbNeedsDisplay(); + if (progress == 1) + expand_thumb_animation_.reset(); +} + +void OverlayScrollbarAnimatorMac::FadeInTrackAnimationStart() { + DCHECK(!fade_in_track_animation_); + DCHECK(!fade_out_animation_); + fade_in_track_animation_ = std::make_unique<ScrollbarAnimationTimerMac>( + base::BindRepeating( + &OverlayScrollbarAnimatorMac::FadeInTrackAnimationTicked, + weak_factory_.GetWeakPtr()), + kAnimationDurationSeconds, task_runner_); + fade_in_track_animation_->Start(); +} + +void OverlayScrollbarAnimatorMac::FadeInTrackAnimationTicked(double progress) { + // Fade-in and fade-out are mutually exclusive. + DCHECK(!fade_out_animation_); + + track_alpha_ = progress; + client_->SetTrackNeedsDisplay(); + if (progress == 1) { + fade_in_track_animation_.reset(); + } +} + +void OverlayScrollbarAnimatorMac::FadeOutTimerUpdate() { + if (mouse_in_track_) { + start_scrollbar_fade_out_timer_.reset(); + return; + } + if (!start_scrollbar_fade_out_timer_) { + start_scrollbar_fade_out_timer_ = + std::make_unique<base::RetainingOneShotTimer>( + FROM_HERE, kFadeOutDelay, + base::BindRepeating( + &OverlayScrollbarAnimatorMac::FadeOutAnimationStart, + weak_factory_.GetWeakPtr())); + start_scrollbar_fade_out_timer_->SetTaskRunner(task_runner_); + } + start_scrollbar_fade_out_timer_->Reset(); +} + +void OverlayScrollbarAnimatorMac::FadeOutAnimationStart() { + start_scrollbar_fade_out_timer_.reset(); + fade_in_track_animation_.reset(); + fade_out_animation_.reset(); + + fade_out_animation_ = std::make_unique<ScrollbarAnimationTimerMac>( + base::BindRepeating(&OverlayScrollbarAnimatorMac::FadeOutAnimationTicked, + weak_factory_.GetWeakPtr()), + kAnimationDurationSeconds, task_runner_); + fade_out_animation_->Start(); +} + +void OverlayScrollbarAnimatorMac::FadeOutAnimationTicked(double progress) { + DCHECK(!fade_in_track_animation_); + + // Fade out the thumb. + thumb_alpha_ = 1 - progress; + client_->SetThumbNeedsDisplay(); + + // If the track is not already invisible, fade it out. + if (track_alpha_ != 0) { + track_alpha_ = 1 - progress; + client_->SetTrackNeedsDisplay(); + } + + // Once completely faded out, reset all state. + if (progress == 1) { + expand_thumb_animation_.reset(); + fade_out_animation_.reset(); + + thumb_width_ = thumb_width_unexpanded_; + DCHECK_EQ(thumb_alpha_, 0.f); + DCHECK_EQ(track_alpha_, 0.f); + + // Mark that the scrollbars were hidden. + client_->SetHidden(true); + } +} + +void OverlayScrollbarAnimatorMac::FadeOutAnimationCancel() { + DCHECK(fade_out_animation_); + fade_out_animation_.reset(); + thumb_alpha_ = 1; + client_->SetThumbNeedsDisplay(); + if (track_alpha_ > 0) { + track_alpha_ = 1; + client_->SetTrackNeedsDisplay(); + } +} + +const float OverlayScrollbarAnimatorMac::kAnimationDurationSeconds = 0.25f; +const base::TimeDelta OverlayScrollbarAnimatorMac::kFadeOutDelay = + base::Milliseconds(500); + +} // namespace ui
diff --git a/ui/native_theme/scrollbar_animator_mac.h b/ui/native_theme/scrollbar_animator_mac.h new file mode 100644 index 0000000..66a4158 --- /dev/null +++ b/ui/native_theme/scrollbar_animator_mac.h
@@ -0,0 +1,129 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_NATIVE_THEME_SCROLLBAR_ANIMATOR_MAC_H_ +#define UI_NATIVE_THEME_SCROLLBAR_ANIMATOR_MAC_H_ + +#include "base/callback.h" +#include "base/task/single_thread_task_runner.h" +#include "base/timer/timer.h" +#include "ui/gfx/animation/keyframe/timing_function.h" +#include "ui/native_theme/native_theme_export.h" + +namespace ui { + +// Timer used for animating scrollbar effects. +// TODO(https://crbug.com/961835): Change this to be driven by the client +// (Blink or Views) animation system. +class NATIVE_THEME_EXPORT ScrollbarAnimationTimerMac { + public: + ScrollbarAnimationTimerMac( + base::RepeatingCallback<void(double)> callback, + double duration, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + ~ScrollbarAnimationTimerMac(); + + void Start(); + void Stop(); + void SetDuration(double duration); + + private: + void TimerFired(); + + base::RepeatingTimer timer_; + double start_time_; // In seconds. + double duration_; // In seconds. + base::RepeatingCallback<void(double)> callback_; + std::unique_ptr<gfx::CubicBezierTimingFunction> timing_function_; +}; + +class NATIVE_THEME_EXPORT OverlayScrollbarAnimatorMac { + public: + class Client { + public: + virtual ~Client() {} + // Return true if the mouse is currently in the tracks' frame. This is used + // during an initial scroll, because MouseDidEnter and MouseDidExit are not + // while the scrollbar is hidden. + virtual bool IsMouseInScrollbarFrameRect() const = 0; + + // Set whether all of the scrollbar is hidden. + virtual void SetHidden(bool) = 0; + + // Called whenever the value of `GetThumbAlpha` or `GetThumbWidth` may + // have changed. + virtual void SetThumbNeedsDisplay() = 0; + + // Called whenever the value of `GetTrackAlpha` may have changed. + virtual void SetTrackNeedsDisplay() = 0; + }; + + OverlayScrollbarAnimatorMac( + Client* client, + int thumb_width_expanded, + int thumb_width_unexpanded, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + ~OverlayScrollbarAnimatorMac(); + + // Called when the mouse moves to be over the scrollbar's area. + void MouseDidEnter(); + + // Called when the mouse leave the scrollbar's area. + void MouseDidExit(); + + // Called in response to a scroll in the direction of this scrollbar. + void DidScroll(); + + // Retrieve the rendering properties of the scrollbar. + float GetThumbAlpha() const { return thumb_alpha_; } + float GetTrackAlpha() const { return track_alpha_; } + int GetThumbWidth() const { return thumb_width_; } + + protected: + void ExpandThumbAnimationStart(); + void ExpandThumbAnimationTicked(double progress); + + void FadeInTrackAnimationStart(); + void FadeInTrackAnimationTicked(double progress); + + void FadeOutTimerUpdate(); + void FadeOutAnimationStart(); + void FadeOutAnimationTicked(double progress); + void FadeOutAnimationCancel(); + + Client* const client_; // Weak, owns `this`. + const int thumb_width_expanded_; + const int thumb_width_unexpanded_; + + int thumb_width_ = 0; + float thumb_alpha_ = 0; + float track_alpha_ = 0; + bool mouse_in_track_ = false; + + static const float kAnimationDurationSeconds; + static const base::TimeDelta kFadeOutDelay; + + // Animator for expanding `thumb_width_` when the mouse enters the + // scrollbar area. + std::unique_ptr<ScrollbarAnimationTimerMac> expand_thumb_animation_; + + // Animator for fading in `track_alpha_` when the mouse enters the scrollbar + // area. Note that `thumb_alpha_` never fades in (it instantaneously appears). + std::unique_ptr<ScrollbarAnimationTimerMac> fade_in_track_animation_; + + // Animator for fading out `track_alpha_` and `thumb_alpha_` together after + // inactivity. + std::unique_ptr<ScrollbarAnimationTimerMac> fade_out_animation_; + + // Timer to trigger the `fade_out_animation_`. + std::unique_ptr<base::RetainingOneShotTimer> start_scrollbar_fade_out_timer_; + + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + base::WeakPtrFactory<OverlayScrollbarAnimatorMac> weak_factory_; +}; + +} // namespace ui + +#endif // UI_NATIVE_THEME_OVERLAY_SCROLLBAR_ANIMATOR_MAC_H_
diff --git a/ui/native_theme/scrollbar_animator_mac_unittest.cc b/ui/native_theme/scrollbar_animator_mac_unittest.cc new file mode 100644 index 0000000..a40964d --- /dev/null +++ b/ui/native_theme/scrollbar_animator_mac_unittest.cc
@@ -0,0 +1,271 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/native_theme/scrollbar_animator_mac.h" + +#include "base/logging.h" +#include "base/test/task_environment.h" +#include "base/time/time.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::Return; + +namespace ui { + +namespace { + +constexpr int kExpandedWidth = 32; +constexpr int kUnexpandedWidth = 16; +constexpr auto kTimeToFadeOut = base::Milliseconds(500); +constexpr auto kAnimationTime = base::Milliseconds(250); + +class MockClient : public OverlayScrollbarAnimatorMac::Client { + public: + MOCK_CONST_METHOD0(IsMouseInScrollbarFrameRect, bool()); + MOCK_METHOD1(SetHidden, void(bool)); + MOCK_METHOD0(SetThumbNeedsDisplay, void()); + MOCK_METHOD0(SetTrackNeedsDisplay, void()); +}; + +class MacScrollbarAnimatorTest : public ::testing::Test { + public: + MacScrollbarAnimatorTest() + : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) { + scrollbar_ = std::make_unique<OverlayScrollbarAnimatorMac>( + &client_, kExpandedWidth, kUnexpandedWidth, + task_environment_.GetMainThreadTaskRunner()); + } + + ~MacScrollbarAnimatorTest() override = default; + + base::test::TaskEnvironment task_environment_; + MockClient client_; + std::unique_ptr<OverlayScrollbarAnimatorMac> scrollbar_; +}; + +TEST_F(MacScrollbarAnimatorTest, DidScrollThenFadeOut) { + // The scrollbar_ starts as invisible. + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 0.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 0.f); + + // Scroll with the mouse not in the track. + EXPECT_CALL(client_, IsMouseInScrollbarFrameRect()).WillOnce(Return(false)); + EXPECT_CALL(client_, SetHidden(false)); + EXPECT_CALL(client_, SetThumbNeedsDisplay()); + scrollbar_->DidScroll(); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 0.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kUnexpandedWidth); + + // Fast-forward until just before the timeout threshold is hit. + EXPECT_CALL(client_, SetThumbNeedsDisplay()).Times(0); + task_environment_.FastForwardBy(kTimeToFadeOut); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 0.f); + + // Fast-forward through half of the fade-out animation. + EXPECT_CALL(client_, SetThumbNeedsDisplay()).WillRepeatedly(Return()); + task_environment_.FastForwardBy(kAnimationTime / 2); + EXPECT_GT(scrollbar_->GetThumbAlpha(), 0.f); + EXPECT_LT(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kUnexpandedWidth); + + // Fast-forward through past the end of the fade-out animation. The scrollbar_ + // should be hidden. + EXPECT_CALL(client_, SetHidden(true)); + task_environment_.FastForwardBy(kAnimationTime); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 0.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 0.f); +} + +TEST_F(MacScrollbarAnimatorTest, DidScrollStartsInTrack) { + // Scroll with the mouse in the track. + EXPECT_CALL(client_, IsMouseInScrollbarFrameRect()).WillOnce(Return(true)); + EXPECT_CALL(client_, SetHidden(false)); + EXPECT_CALL(client_, SetThumbNeedsDisplay()); + EXPECT_CALL(client_, SetTrackNeedsDisplay()); + scrollbar_->DidScroll(); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Fast-forward long past the fade-out animation would happen. Nothing should + // happen. + EXPECT_CALL(client_, SetThumbNeedsDisplay()).Times(0); + EXPECT_CALL(client_, SetTrackNeedsDisplay()).Times(0); + task_environment_.FastForwardBy(10 * kTimeToFadeOut); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Scroll again. Again, nothing should happen. + scrollbar_->DidScroll(); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Have the mouse leave the scrollbar_. Fast-forward not enough time for the + // scrollbar_ to fade out, then have the mouse re-enter. Exit again. Still + // nothing should happen. + scrollbar_->MouseDidExit(); + task_environment_.FastForwardBy(kTimeToFadeOut / 2); + scrollbar_->MouseDidEnter(); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + scrollbar_->MouseDidExit(); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Wait most of the fade-out timer's time. Nothing should happen in this + // interval. + task_environment_.FastForwardBy(3 * kTimeToFadeOut / 4); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Allow the fade-out animation to progress about halfway through. + EXPECT_CALL(client_, SetThumbNeedsDisplay()).WillRepeatedly(Return()); + EXPECT_CALL(client_, SetTrackNeedsDisplay()).WillRepeatedly(Return()); + task_environment_.FastForwardBy(kTimeToFadeOut / 4 + kAnimationTime / 2); + EXPECT_GT(scrollbar_->GetThumbAlpha(), 0.f); + EXPECT_LT(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_GT(scrollbar_->GetTrackAlpha(), 0.f); + EXPECT_LT(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Scroll, interrupting the fade-out animation. + EXPECT_CALL(client_, SetThumbNeedsDisplay()).Times(1); + EXPECT_CALL(client_, SetTrackNeedsDisplay()).Times(1); + scrollbar_->DidScroll(); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Wait most of the fade-out timer's time. Nothing should happen in this time. + EXPECT_CALL(client_, SetThumbNeedsDisplay()).Times(0); + EXPECT_CALL(client_, SetTrackNeedsDisplay()).Times(0); + task_environment_.FastForwardBy(3 * kTimeToFadeOut / 4); + + // Allow the fade-out animation to progress halfway again. + EXPECT_CALL(client_, SetThumbNeedsDisplay()).WillRepeatedly(Return()); + EXPECT_CALL(client_, SetTrackNeedsDisplay()).WillRepeatedly(Return()); + task_environment_.FastForwardBy(kTimeToFadeOut / 4 + kAnimationTime / 2); + EXPECT_GT(scrollbar_->GetThumbAlpha(), 0.f); + EXPECT_LT(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_GT(scrollbar_->GetTrackAlpha(), 0.f); + EXPECT_LT(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // And let it progress to completion. The scrollbar_ should hide itself. + EXPECT_CALL(client_, SetHidden(true)); + task_environment_.FastForwardBy(kAnimationTime); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 0.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 0.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kUnexpandedWidth); +} + +TEST_F(MacScrollbarAnimatorTest, EnterTrack) { + // First try to enter the track before showing the scrollbar_. Nothing should + // happen. + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 0.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 0.f); + scrollbar_->MouseDidEnter(); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 0.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 0.f); + + // Scroll with the mouse in the track. + EXPECT_CALL(client_, IsMouseInScrollbarFrameRect()).WillOnce(Return(false)); + EXPECT_CALL(client_, SetHidden(false)); + EXPECT_CALL(client_, SetThumbNeedsDisplay()); + scrollbar_->DidScroll(); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 0.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kUnexpandedWidth); + + // Have the mouse enter the scrollbar_ area. + scrollbar_->MouseDidEnter(); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 0.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kUnexpandedWidth); + + // Fast-forward part of the animation. + EXPECT_CALL(client_, SetThumbNeedsDisplay()).WillRepeatedly(Return()); + EXPECT_CALL(client_, SetTrackNeedsDisplay()).WillRepeatedly(Return()); + task_environment_.FastForwardBy(kAnimationTime / 2); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_GT(scrollbar_->GetTrackAlpha(), 0.f); + EXPECT_LT(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_GT(scrollbar_->GetThumbWidth(), kUnexpandedWidth); + EXPECT_LT(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Fast-forward through the rest of the animation. + task_environment_.FastForwardBy(kAnimationTime); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Fast-forward for a long time. Nothing should happen (no fade-out). + EXPECT_CALL(client_, SetThumbNeedsDisplay()).Times(0); + EXPECT_CALL(client_, SetTrackNeedsDisplay()).Times(0); + task_environment_.FastForwardBy(10 * kTimeToFadeOut); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Move the mouse out and wait for the the fade-out should start. + scrollbar_->MouseDidExit(); + task_environment_.FastForwardBy(kTimeToFadeOut); + EXPECT_CALL(client_, SetThumbNeedsDisplay()).WillRepeatedly(Return()); + EXPECT_CALL(client_, SetTrackNeedsDisplay()).WillRepeatedly(Return()); + task_environment_.FastForwardBy(kAnimationTime / 2); + EXPECT_GT(scrollbar_->GetThumbAlpha(), 0.f); + EXPECT_LT(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_GT(scrollbar_->GetTrackAlpha(), 0.f); + EXPECT_LT(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Re-enter. This will immediately return us to full opacity. + EXPECT_CALL(client_, SetThumbNeedsDisplay()).Times(1); + EXPECT_CALL(client_, SetTrackNeedsDisplay()).Times(1); + scrollbar_->MouseDidEnter(); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Wait for a long time. Nothing should happen. + EXPECT_CALL(client_, SetThumbNeedsDisplay()).Times(0); + EXPECT_CALL(client_, SetTrackNeedsDisplay()).Times(0); + task_environment_.FastForwardBy(10 * kTimeToFadeOut); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Re-leave the track. Again nothing should happen. + scrollbar_->MouseDidExit(); + + // Fast-forward through the start of the fade-out. + task_environment_.FastForwardBy(kTimeToFadeOut); + EXPECT_CALL(client_, SetThumbNeedsDisplay()).WillRepeatedly(Return()); + EXPECT_CALL(client_, SetTrackNeedsDisplay()).WillRepeatedly(Return()); + task_environment_.FastForwardBy(kAnimationTime / 2); + EXPECT_GT(scrollbar_->GetThumbAlpha(), 0.f); + EXPECT_LT(scrollbar_->GetThumbAlpha(), 1.f); + EXPECT_GT(scrollbar_->GetTrackAlpha(), 0.f); + EXPECT_LT(scrollbar_->GetTrackAlpha(), 1.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kExpandedWidth); + + // Fast-forward until the fade-out completes. + EXPECT_CALL(client_, SetHidden(true)); + task_environment_.FastForwardBy(kAnimationTime); + EXPECT_EQ(scrollbar_->GetThumbAlpha(), 0.f); + EXPECT_EQ(scrollbar_->GetTrackAlpha(), 0.f); + EXPECT_EQ(scrollbar_->GetThumbWidth(), kUnexpandedWidth); +} + +} // namespace + +} // namespace ui
diff --git a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc index 33dc6db5..93909d0 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc +++ b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/process/process.h" #include "base/task/current_thread.h" +#include "base/threading/thread_task_runner_handle.h" #include "ui/gfx/geometry/rrect_f.h" #include "ui/gfx/linux/drm_util_linux.h" #include "ui/gfx/overlay_priority_hint.h" @@ -69,6 +70,30 @@ // open the handle early and store it. OpenAndStoreDrmRenderNodeFd(); #endif + + // The WaylandBufferManagerGpu takes the task runner where it was created. + // However, it might be null in tests and be available later after + // initialization is done. Though, when this code runs outside tests, a race + // between setting a task runner via ::Initialize and ::RegisterSurface may + // happen, and a surface will never be registered. Thus, the following two + // cases are possible: + // 1) The WaylandBufferManagerGpu runs normally outside tests. + // ThreadTaskRunnerHandle is set and it is passed during construction and + // never changes. + // 2) The WaylandBufferManagerGpu runs in unit tests and when it's created, + // the task runner is not available and must be set later when ::Initialize is + // called. In this case, there is no race between ::Initialize and + // ::RegisterSurface and it's fine to defer setting the task runner. + // + // TODO(msisov): think about making unit tests initialize Ozone after task + // runner is set that would allow to always set the task runner. + if (base::ThreadTaskRunnerHandle::IsSet()) { + gpu_thread_runner_ = base::ThreadTaskRunnerHandle::Get(); + } else { + // In tests, the further calls might happen on a different sequence. + // Otherwise, ThreadTaskRunnerHandle should have already been set. + DETACH_FROM_SEQUENCE(gpu_sequence_checker_); + } } WaylandBufferManagerGpu::~WaylandBufferManagerGpu() = default; @@ -81,6 +106,12 @@ bool supports_viewporter, bool supports_acquire_fence, bool supports_non_backed_solid_color_buffers) { + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + + // See the comment in the constructor. + if (!gpu_thread_runner_) + gpu_thread_runner_ = base::ThreadTaskRunnerHandle::Get(); + supported_buffer_formats_with_modifiers_ = buffer_formats_with_modifiers; supports_viewporter_ = supports_viewporter; supports_acquire_fence_ = supports_acquire_fence; @@ -89,16 +120,15 @@ supports_dmabuf_ = supports_dma_buf; BindHostInterface(std::move(remote_host)); - - io_thread_runner_ = base::ThreadTaskRunnerHandle::Get(); } void WaylandBufferManagerGpu::OnSubmission(gfx::AcceleratedWidget widget, uint32_t buffer_id, gfx::SwapResult swap_result, gfx::GpuFenceHandle release_fence) { + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + base::AutoLock scoped_lock(lock_); - DCHECK(io_thread_runner_->BelongsToCurrentThread()); DCHECK_LE(commit_thread_runners_.count(widget), 1u); // Return back to the same thread where the commit request came from. auto it = commit_thread_runners_.find(widget); @@ -115,8 +145,9 @@ gfx::AcceleratedWidget widget, uint32_t buffer_id, const gfx::PresentationFeedback& feedback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + base::AutoLock scoped_lock(lock_); - DCHECK(io_thread_runner_->BelongsToCurrentThread()); DCHECK_LE(commit_thread_runners_.count(widget), 1u); // Return back to the same thread where the commit request came from. auto it = commit_thread_runners_.find(widget); @@ -130,13 +161,8 @@ void WaylandBufferManagerGpu::RegisterSurface(gfx::AcceleratedWidget widget, WaylandSurfaceGpu* surface) { - if (!io_thread_runner_) { - LOG(ERROR) << "WaylandBufferManagerGpu is not initialized. Can't register " - "a surface."; - return; - } - - io_thread_runner_->PostTask( + DCHECK(gpu_thread_runner_); + gpu_thread_runner_->PostTask( FROM_HERE, base::BindOnce( &WaylandBufferManagerGpu::SaveTaskRunnerForWidgetOnIOThread, @@ -147,13 +173,8 @@ } void WaylandBufferManagerGpu::UnregisterSurface(gfx::AcceleratedWidget widget) { - if (!io_thread_runner_) { - LOG(ERROR) << "WaylandBufferManagerGpu is not initialized. Can't register " - "a surface."; - return; - } - - io_thread_runner_->PostTask( + DCHECK(gpu_thread_runner_); + gpu_thread_runner_->PostTask( FROM_HERE, base::BindOnce( &WaylandBufferManagerGpu::ForgetTaskRunnerForWidgetOnIOThread, @@ -182,14 +203,9 @@ uint32_t current_format, uint32_t planes_count, uint32_t buffer_id) { - if (!remote_host_) { - LOG(ERROR) << "Interface is not bound. Can't request " - "WaylandBufferManagerHost to create/commit/destroy buffers."; - return; - } - - // Do the mojo call on the IO child thread. - io_thread_runner_->PostTask( + DCHECK(gpu_thread_runner_); + // Do the mojo call on the GpuMainThread. + gpu_thread_runner_->PostTask( FROM_HERE, base::BindOnce(&WaylandBufferManagerGpu::CreateDmabufBasedBufferInternal, base::Unretained(this), std::move(dmabuf_fd), @@ -202,14 +218,9 @@ size_t length, gfx::Size size, uint32_t buffer_id) { - if (!remote_host_) { - LOG(ERROR) << "Interface is not bound. Can't request " - "WaylandBufferManagerHost to create/commit/destroy buffers."; - return; - } - - // Do the mojo call on the IO child thread. - io_thread_runner_->PostTask( + DCHECK(gpu_thread_runner_); + // Do the mojo call on the GpuMainThread. + gpu_thread_runner_->PostTask( FROM_HERE, base::BindOnce(&WaylandBufferManagerGpu::CreateShmBasedBufferInternal, base::Unretained(this), std::move(shm_fd), length, @@ -219,14 +230,9 @@ void WaylandBufferManagerGpu::CreateSolidColorBuffer(SkColor color, const gfx::Size& size, uint32_t buf_id) { - if (!remote_host_) { - LOG(ERROR) << "Interface is not bound. Can't request " - "WaylandBufferManagerHost to create/commit/destroy buffers."; - return; - } - - // Do the mojo call on the IO child thread. - io_thread_runner_->PostTask( + DCHECK(gpu_thread_runner_); + // Do the mojo call on the GpuMainThread. + gpu_thread_runner_->PostTask( FROM_HERE, base::BindOnce(&WaylandBufferManagerGpu::CreateSolidColorBufferInternal, base::Unretained(this), color, size, buf_id)); @@ -252,14 +258,9 @@ void WaylandBufferManagerGpu::CommitOverlays( gfx::AcceleratedWidget widget, std::vector<ozone::mojom::WaylandOverlayConfigPtr> overlays) { - if (!remote_host_) { - LOG(ERROR) << "Interface is not bound. Can't request " - "WaylandBufferManagerHost to create/commit/destroy buffers."; - return; - } - - // Do the mojo call on the IO child thread. - io_thread_runner_->PostTask( + DCHECK(gpu_thread_runner_); + // Do the mojo call on the GpuMainThread. + gpu_thread_runner_->PostTask( FROM_HERE, base::BindOnce(&WaylandBufferManagerGpu::CommitOverlaysInternal, base::Unretained(this), widget, std::move(overlays))); @@ -267,14 +268,9 @@ void WaylandBufferManagerGpu::DestroyBuffer(gfx::AcceleratedWidget widget, uint32_t buffer_id) { - if (!remote_host_) { - LOG(ERROR) << "Interface is not bound. Can't request " - "WaylandBufferManagerHost to create/commit/destroy buffers."; - return; - } - - // Do the mojo call on the IO child thread. - io_thread_runner_->PostTask( + DCHECK(gpu_thread_runner_); + // Do the mojo call on the GpuMainThread. + gpu_thread_runner_->PostTask( FROM_HERE, base::BindOnce(&WaylandBufferManagerGpu::DestroyBufferInternal, base::Unretained(this), widget, buffer_id)); } @@ -331,7 +327,9 @@ uint32_t current_format, uint32_t planes_count, uint32_t buffer_id) { - DCHECK(io_thread_runner_->BelongsToCurrentThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + + DCHECK(remote_host_); remote_host_->CreateDmabufBasedBuffer( mojo::PlatformHandle(std::move(dmabuf_fd)), size, strides, offsets, modifiers, current_format, planes_count, buffer_id); @@ -342,7 +340,9 @@ size_t length, gfx::Size size, uint32_t buffer_id) { - DCHECK(io_thread_runner_->BelongsToCurrentThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + + DCHECK(remote_host_); remote_host_->CreateShmBasedBuffer(mojo::PlatformHandle(std::move(shm_fd)), length, size, buffer_id); } @@ -351,33 +351,40 @@ SkColor color, const gfx::Size& size, uint32_t buf_id) { - DCHECK(io_thread_runner_->BelongsToCurrentThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + + DCHECK(remote_host_); remote_host_->CreateSolidColorBuffer(size, color, buf_id); } void WaylandBufferManagerGpu::CommitOverlaysInternal( gfx::AcceleratedWidget widget, std::vector<ozone::mojom::WaylandOverlayConfigPtr> overlays) { - DCHECK(io_thread_runner_->BelongsToCurrentThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + + DCHECK(remote_host_); remote_host_->CommitOverlays(widget, std::move(overlays)); } void WaylandBufferManagerGpu::DestroyBufferInternal( gfx::AcceleratedWidget widget, uint32_t buffer_id) { - DCHECK(io_thread_runner_->BelongsToCurrentThread()); + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + + DCHECK(remote_host_); remote_host_->DestroyBuffer(widget, buffer_id); } void WaylandBufferManagerGpu::BindHostInterface( mojo::PendingRemote<ozone::mojom::WaylandBufferManagerHost> remote_host) { + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + + DCHECK(!remote_host_.is_bound() && !associated_receiver_.is_bound()); + remote_host_.Bind(std::move(remote_host)); // WaylandBufferManagerHost may bind host again after an error. See // WaylandBufferManagerHost::BindInterface for more details. - if (remote_host_.is_bound()) { - remote_host_.reset(); - associated_receiver_.reset(); - } - remote_host_.Bind(std::move(remote_host)); + remote_host_.set_disconnect_handler(base::BindOnce( + &WaylandBufferManagerGpu::OnHostDisconnected, base::Unretained(this))); // Setup associated interface. mojo::PendingAssociatedRemote<ozone::mojom::WaylandBufferManagerGpu> @@ -390,15 +397,17 @@ void WaylandBufferManagerGpu::SaveTaskRunnerForWidgetOnIOThread( gfx::AcceleratedWidget widget, scoped_refptr<base::SingleThreadTaskRunner> origin_runner) { + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + DCHECK_NE(widget, gfx::kNullAcceleratedWidget); - DCHECK(io_thread_runner_->BelongsToCurrentThread()); commit_thread_runners_.emplace(widget, origin_runner); } void WaylandBufferManagerGpu::ForgetTaskRunnerForWidgetOnIOThread( gfx::AcceleratedWidget widget) { + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + DCHECK_NE(widget, gfx::kNullAcceleratedWidget); - DCHECK(io_thread_runner_->BelongsToCurrentThread()); commit_thread_runners_.erase(widget); } @@ -445,4 +454,15 @@ } #endif +void WaylandBufferManagerGpu::OnHostDisconnected() { + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + + // WaylandBufferManagerHost may bind host again after an error. See + // WaylandBufferManagerHost::BindInterface for more details. + remote_host_.reset(); + // When the remote host is disconnected, it also disconnects the associated + // receiver. Thus, reset that as well. + associated_receiver_.reset(); +} + } // namespace ui
diff --git a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h index 8db3ff79..a65842ff 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h +++ b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h
@@ -40,12 +40,15 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu { public: WaylandBufferManagerGpu(); - WaylandBufferManagerGpu(const WaylandBufferManagerGpu&) = delete; WaylandBufferManagerGpu& operator=(const WaylandBufferManagerGpu&) = delete; ~WaylandBufferManagerGpu() override; + scoped_refptr<base::SingleThreadTaskRunner> gpu_thread_runner() const { + return gpu_thread_runner_; + } + // WaylandBufferManagerGpu overrides: void Initialize( mojo::PendingRemote<ozone::mojom::WaylandBufferManagerHost> remote_host, @@ -198,6 +201,8 @@ uint32_t buffer_id, const gfx::PresentationFeedback& feedback); + void OnHostDisconnected(); + #if defined(WAYLAND_GBM) // Finds drm render node, opens it and stores the handle into // |drm_render_node_fd|. @@ -246,26 +251,30 @@ // These task runners can be used to pass messages back to the same thread, // where the commit buffer request came from. For example, swap requests can - // come from the GpuMainThread, but are rerouted to the IOChildThread and then + // come from the Viz thread, but are rerouted to the GpuMainThread and then // mojo calls happen. However, when the manager receives mojo calls, it has to // reroute calls back to the same thread where the calls came from to ensure - // correct sequence. Note that not all calls come from the GpuMainThread, e.g. - // WaylandCanvasSurface calls from the VizCompositorThread. - // This map must only be accessed from the IO thread. + // correct sequence. Note that not all calls come from the Viz thread, e.g. + // GbmPixmapWayland may call from either the GpuMainThread or IOChildThread. + // This map must only be accessed from the GpuMainThread. base::small_map<std::map<gfx::AcceleratedWidget, scoped_refptr<base::SingleThreadTaskRunner>>> commit_thread_runners_; // A task runner, which is initialized in a multi-process mode. It is used to - // ensure all the methods of this class are run on IOChildThread. This is + // ensure all the methods of this class are run on GpuMainThread. This is // needed to ensure mojo calls happen on a right sequence. - scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner_; + scoped_refptr<base::SingleThreadTaskRunner> gpu_thread_runner_; // Protects access to |widget_to_surface_map_| and |commit_thread_runners_|. base::Lock lock_; // Keeps track of the next unique buffer ID. uint32_t next_buffer_id_ = 0; + + // All calls must happen on the correct sequence. See comments in the + // constructor for more details. + SEQUENCE_CHECKER(gpu_sequence_checker_); }; } // namespace ui
diff --git a/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/ui/ozone/platform/wayland/ozone_platform_wayland.cc index f50b2348..b4e5e74 100644 --- a/ui/ozone/platform/wayland/ozone_platform_wayland.cc +++ b/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -14,7 +14,7 @@ #include "base/memory/ptr_util.h" #include "base/message_loop/message_pump_type.h" #include "base/no_destructor.h" -#include "base/threading/sequenced_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "ui/base/buildflags.h" #include "ui/base/cursor/cursor_factory.h" #include "ui/base/dragdrop/os_exchange_data_provider_factory_ozone.h" @@ -327,11 +327,22 @@ } void AddInterfaces(mojo::BinderMap* binders) override { + // It's preferred to reuse the same task runner where the + // WaylandBufferManagerGpu has been created. However, when tests are + // executed, the task runner might not have been set at that time. Thus, use + // the current one. See the comment in WaylandBufferManagerGpu why it takes + // a task runner. + // + // Please note this call happens on the gpu. + auto gpu_task_runner = buffer_manager_->gpu_thread_runner(); + if (!gpu_task_runner) + gpu_task_runner = base::ThreadTaskRunnerHandle::Get(); + binders->Add<ozone::mojom::WaylandBufferManagerGpu>( base::BindRepeating( &OzonePlatformWayland::CreateWaylandBufferManagerGpuBinding, base::Unretained(this)), - base::SequencedTaskRunnerHandle::Get()); + gpu_task_runner); } void CreateWaylandBufferManagerGpuBinding(